diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index f5cc530badffe6..ffc20a7aafbe10 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -50,7 +50,7 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: stm32 - + extra-submodule-parameters: --recursive - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports if: ${{ !env.ACT }} diff --git a/.gitmodules b/.gitmodules index 26fff510eebfb5..55d44f9dba9e9f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -313,7 +313,7 @@ [submodule "third_party/st/STM32CubeWB"] path = third_party/st/STM32CubeWB url = https://github.com/STMicroelectronics/STM32CubeWB.git - branch = v1.17.0 + branch = v1.18.0 platforms = stm32 [submodule "p6/lwip-network-interface-integration"] path = third_party/infineon/psoc6/psoc6_sdk/libs/lwip-network-interface-integration diff --git a/examples/lighting-app/stm32/BUILD.gn b/examples/lighting-app/stm32/BUILD.gn index 6adecf2d04c1f5..3ac2fd365f11fa 100644 --- a/examples/lighting-app/stm32/BUILD.gn +++ b/examples/lighting-app/stm32/BUILD.gn @@ -54,24 +54,22 @@ if (stm32_board == "STM32WB5MM-DK") { } 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}", + "${stm32_project_dir}/include/STM32WB5", "${chip_root}/src/lib", ] 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 += [ "${stm32_project_dir}/include/STM32WB5", - "${examples_plat_dir}/config_files/STM32WB5", "${chip_root}/src/include", ] } @@ -100,25 +98,29 @@ stm32_executable("lighting_app") { "${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}/STM32_WPAN/Target/hw_ipcc.c", "${stm32_board_src}/Src/app_entry.cpp", "${stm32_board_src}/Src/main.cpp", + "${stm32_board_src}/Src/ota.cpp", "src/STM32WB5/AppTask.cpp", + "src/STM32WB5/IdentifierEffect.cpp", "src/STM32WB5/LightingManager.cpp", "src/STM32WB5/ZclCallbacks.cpp", ] + + 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", + ] } # 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", diff --git a/examples/lighting-app/stm32/include/STM32WB5/AppTask.h b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h index 5c0344cc8c687a..641233581872d3 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/AppTask.h +++ b/examples/lighting-app/stm32/include/STM32WB5/AppTask.h @@ -26,6 +26,7 @@ #include "LightingManager.h" #include "app_entry.h" +#include #include #include #define APP_NAME "Lighting-app" @@ -55,9 +56,10 @@ class AppTask 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); +#if (OTA_SUPPORT == 0) static void UpdateLCD(void); +#endif static void UpdateNvmEventHandler(AppEvent * aEvent); enum Function_t diff --git a/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h index a911c565e95a1b..6540d718328090 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h +++ b/examples/lighting-app/stm32/include/STM32WB5/CHIPProjectConfig.h @@ -23,16 +23,26 @@ */ #ifndef CHIPPROJECTCONFIG_H #define CHIPPROJECTCONFIG_H +#include "app_conf.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 +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +// For convenience, Chip Security Test Mode can be enabled and the +// requirement for authentication in various protocols can be disabled. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 + /** * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID * @@ -73,6 +83,25 @@ */ #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 +/** + * CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY + * + * Enables the use of a hard-coded default Chip device id and credentials if no device id + * is found in Chip NV storage. + * + * This option is for testing only and should be disabled in production releases. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_TEST_DEVICE_IDENTITY 34 + +// For convenience, enable Chip Security Test Mode and disable the requirement for +// authentication in various protocols. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 +#define CHIP_CONFIG_REQUIRE_AUTH 1 + /** * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING * @@ -84,6 +113,15 @@ #define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "1.1" #endif +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION + * + * A monothonic number identifying the software version running on the device. + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 1 +#endif + /** * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_REVISION * diff --git a/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h index aeb0ac1b8913da..e1ff4e30648486 100644 --- a/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h +++ b/examples/lighting-app/stm32/include/STM32WB5/FreeRTOSConfig.h @@ -76,7 +76,7 @@ extern uint32_t SystemCoreClock; #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 0 +#define configUSE_TICKLESS_IDLE 2 /* 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. */ @@ -172,19 +172,20 @@ standard names. */ /* 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 +/*#define configGENERATE_RUN_TIME_STATS 1 -#if (configGENERATE_RUN_TIME_STATS == 1) +#if( configGENERATE_RUN_TIME_STATS == 1 ) -extern void RTOS_AppConfigureTimerForRuntimeStats(); + extern void RTOS_AppConfigureTimerForRuntimeStats(); -extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() -#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + #define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() #endif +*/ /* USER CODE END Defines */ diff --git a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp index d102f8a9dfd421..5841f15264bad4 100644 --- a/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp +++ b/examples/lighting-app/stm32/src/STM32WB5/AppTask.cpp @@ -24,12 +24,12 @@ #include "cmsis_os.h" #include "dbg_trace.h" #include "flash_wb.h" +#include "ota.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 @@ -65,16 +65,12 @@ 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, @@ -92,6 +88,8 @@ static bool sHaveFabric = false; static uint8_t NvmTimerCpt = 0; static uint8_t NvmButtonStateCpt = 0; +chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; + CHIP_ERROR AppTask::StartAppTask() { sAppEventQueue = xQueueCreate(APP_EVENT_QUEUE_SIZE, sizeof(AppEvent)); @@ -134,15 +132,7 @@ CHIP_ERROR AppTask::Init() 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); @@ -174,6 +164,9 @@ CHIP_ERROR AppTask::Init() initParams.endpointNativeParams = static_cast(&nativeParams); chip::Server::GetInstance().Init(initParams); + gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); + ConfigurationMgr().LogDeviceConfig(); // Open commissioning after boot if no fabric was available @@ -186,23 +179,13 @@ CHIP_ERROR AppTask::Init() } else { // try to attach to the thread network - uint8_t datasetBytes[Thread::kSizeOperationalDataset]; - size_t datasetLength = 0; + sHaveFabric = true; +#if (CFG_LCD_SUPPORTED == 1) 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"); - } +#endif } err = PlatformMgr().StartEventLoopTask(); @@ -225,7 +208,6 @@ CHIP_ERROR AppTask::InitMatter() } else { - APP_DBG("Init CHIP stack"); err = PlatformMgr().InitChipStack(); if (err != CHIP_NO_ERROR) { @@ -248,14 +230,14 @@ void AppTask::AppTaskMain(void * pvParameter) #endif // endif HIGHWATERMARK if (err != CHIP_NO_ERROR) { - APP_DBG("App task init failled "); + APP_DBG("App task init failed "); } APP_DBG("App Task started"); while (true) { - BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, pdMS_TO_TICKS(10)); + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, &event, portMAX_DELAY); while (eventReceived == pdTRUE) { sAppTask.DispatchEvent(&event); @@ -309,7 +291,7 @@ void AppTask::ButtonEventHandler(Push_Button_st * Button) button_event.ButtonEvent.ButtonIdx = Button->Pushed_Button; button_event.ButtonEvent.Action = Button->State; - if (Button->Pushed_Button == APP_FUNCTION_BUTTON) + if (Button->Pushed_Button == BUTTON_USER1) { // Hand off to Functionality handler - depends on duration of press button_event.Handler = FunctionHandler; @@ -344,12 +326,16 @@ void AppTask::TimerEventHandler(TimerHandle_t xTimer) } 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); + if (sHaveFabric == true) + { + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + xTimerStop(sPushButtonTimeoutTimer, 0); + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); + } } } @@ -366,30 +352,40 @@ void AppTask::FunctionHandler(AppEvent * aEvent) void AppTask::ActionInitiated(LightingManager::Action_t aAction) { // Placeholder for light action +#if (CFG_LCD_SUPPORTED == 1) UTIL_LCD_ClearStringLine(2); +#endif if (aAction == LightingManager::ON_ACTION) { APP_DBG("Light goes on"); +#if (CFG_LCD_SUPPORTED == 1) char Message[11]; snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); +#endif } else if (aAction == LightingManager::OFF_ACTION) { APP_DBG("Light goes off "); +#if (CFG_LCD_SUPPORTED == 1) UTIL_LCD_ClearStringLine(2); +#endif } else if (aAction == LightingManager::LEVEL_ACTION) { if (LightingMgr().IsTurnedOn()) { +#if (CFG_LCD_SUPPORTED == 1) char Message[11]; snprintf(Message, sizeof(Message), "LED ON %d", LightingMgr().GetLevel()); UTIL_LCD_DisplayStringAt(0, LINE(2), (uint8_t *) Message, CENTER_MODE); +#endif APP_DBG("Update level control %d", LightingMgr().GetLevel()); } } +#if (CFG_LCD_SUPPORTED == 1) BSP_LCD_Refresh(0); +#endif } void AppTask::ActionCompleted(LightingManager::Action_t aAction) @@ -459,15 +455,7 @@ void AppTask::UpdateClusterState(void) } } -void AppTask::DelayNvmHandler(TimerHandle_t xTimer) -{ - AppEvent event; - event.Type = AppEvent::kEventType_Timer; - event.Handler = UpdateNvmEventHandler; - sAppTask.mFunction = kFunction_SaveNvm; - sAppTask.PostEvent(&event); -} - +#if (CFG_LCD_SUPPORTED == 1) void AppTask::UpdateLCD(void) { if (sIsThreadProvisioned && sIsThreadEnabled) @@ -498,6 +486,7 @@ void AppTask::UpdateLCD(void) } BSP_LCD_Refresh(0); } +#endif void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) { @@ -505,13 +494,6 @@ void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) 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) { @@ -520,8 +502,6 @@ void AppTask::UpdateNvmEventHandler(AppEvent * aEvent) else { APP_DBG("Failed to SAVE NVM"); - // restart timer to save nvm later - xTimerStart(DelayNvmTimer, 0); } } else if (sAppTask.mFunction == kFunction_FactoryReset) @@ -537,32 +517,42 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) { case DeviceEventType::kServiceProvisioningChange: { sIsThreadProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kThreadConnectivityChange: { sIsThreadEnabled = (event->ThreadConnectivityChange.Result == kConnectivity_Established); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kCHIPoBLEConnectionEstablished: { sHaveBLEConnections = true; APP_DBG("kCHIPoBLEConnectionEstablished"); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kCHIPoBLEConnectionClosed: { sHaveBLEConnections = false; APP_DBG("kCHIPoBLEConnectionClosed"); +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif 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); + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); sFabricNeedSaved = false; } break; @@ -574,18 +564,30 @@ void AppTask::MatterEventHandler(const ChipDeviceEvent * event, intptr_t) // 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 + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = UpdateNvmEventHandler; + sAppTask.mFunction = kFunction_SaveNvm; + sAppTask.PostEvent(&event); } +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif break; } case DeviceEventType::kFailSafeTimerExpired: { +#if (CFG_LCD_SUPPORTED == 1) UpdateLCD(); +#endif sFailCommissioning = true; break; } + case DeviceEventType::kDnssdInitialized: +#if (OTA_SUPPORT == 1) + InitializeOTARequestor(); +#endif + break; default: break; } diff --git a/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp b/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp new file mode 100644 index 00000000000000..ebed8fd6c6e39c --- /dev/null +++ b/examples/lighting-app/stm32/src/STM32WB5/IdentifierEffect.cpp @@ -0,0 +1,66 @@ + + +#include "AppEvent.h" +#include "AppTask.h" +#include + +using namespace ::chip::app; +using namespace ::chip::DeviceLayer; + +Clusters::Identify::EffectIdentifierEnum sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; + +/********************************************************** + * Identify Callbacks + *********************************************************/ + +namespace { +void OnTriggerIdentifyEffectCompleted(chip::System::Layer * systemLayer, void * appState) +{ + sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; +} +} // namespace + +void OnTriggerIdentifyEffect(Identify * identify) +{ + sIdentifyEffect = identify->mCurrentEffectIdentifier; + + if (identify->mEffectVariant != Clusters::Identify::EffectVariantEnum::kDefault) + { + ChipLogDetail(AppServer, "Identify Effect Variant unsupported. Using default"); + } + + switch (sIdentifyEffect) + { + case Clusters::Identify::EffectIdentifierEnum::kBlink: + case Clusters::Identify::EffectIdentifierEnum::kBreathe: + case Clusters::Identify::EffectIdentifierEnum::kOkay: + case Clusters::Identify::EffectIdentifierEnum::kChannelChange: + SystemLayer().ScheduleLambda([identify] { + (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(5), OnTriggerIdentifyEffectCompleted, + identify); + }); + break; + case Clusters::Identify::EffectIdentifierEnum::kFinishEffect: + SystemLayer().ScheduleLambda([identify] { + (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); + (void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds16(1), OnTriggerIdentifyEffectCompleted, + identify); + }); + break; + case Clusters::Identify::EffectIdentifierEnum::kStopEffect: + SystemLayer().ScheduleLambda( + [identify] { (void) chip::DeviceLayer::SystemLayer().CancelTimer(OnTriggerIdentifyEffectCompleted, identify); }); + sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + } +} + +Identify gIdentify = { + chip::EndpointId{ 1 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, + OnTriggerIdentifyEffect, +}; diff --git a/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp index 762ad402274cf6..02002c9250227c 100644 --- a/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp +++ b/examples/lighting-app/stm32/src/STM32WB5/ZclCallbacks.cpp @@ -1,7 +1,7 @@ +/* USER CODE BEGIN Header */ /* * - * Copyright (c) 2021 Project CHIP Authors - * Copyright (c) 2019 Google LLC. + * Copyright (c) 2020 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +/* USER CODE END Header */ #include "AppTask.h" #include "LightingManager.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 index f439fd72f7393f..74903fa4d4d6dd 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_conf.h @@ -87,109 +87,10 @@ extern "C" { #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 \ +#define CFG_BLE_IR \ { \ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 \ } @@ -197,7 +98,7 @@ extern "C" { /** * Encryption root key used to derive LTK and CSRK */ -#define CFG_BLE_ERK \ +#define CFG_BLE_ER \ { \ 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21, 0xfe, 0xdc, 0xba, 0x09, 0x87, 0x65, 0x43, 0x21 \ } @@ -236,11 +137,11 @@ extern "C" { #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_REQUEST_NEW_CONN_PARAM 0 #define L2CAP_INTERVAL_MIN CONN_P(1000) /* 1s */ #define L2CAP_INTERVAL_MAX CONN_P(1000) /* 1s */ -#define L2CAP_SLAVE_LATENCY 0x0000 +#define L2CAP_PERIPHERAL_LATENCY 0x0000 #define L2CAP_TIMEOUT_MULTIPLIER 0x1F4 /****************************************************************************** @@ -301,12 +202,12 @@ extern "C" { #define CFG_BLE_DATA_LENGTH_EXTENSION 1 /** - * Sleep clock accuracy in Slave mode (ppm value) + * Sleep clock accuracy in Peripheral mode (ppm value) */ -#define CFG_BLE_SLAVE_SCA 500 +#define CFG_BLE_PERIPHERAL_SCA 500 /** - * Sleep clock accuracy in Master mode + * Sleep clock accuracy in Central mode * 0 : 251 ppm to 500 ppm * 1 : 151 ppm to 250 ppm * 2 : 101 ppm to 150 ppm @@ -316,14 +217,14 @@ extern "C" { * 6 : 21 ppm to 30 ppm * 7 : 0 ppm to 20 ppm */ -#define CFG_BLE_MASTER_SCA 0 +#define CFG_BLE_CENTRAL_SCA 0 /** * Source for the 32 kHz slow speed clock * 1 : internal RO * 0 : external crystal ( no calibration ) */ -#define CFG_BLE_LSE_SOURCE 0 +#define CFG_BLE_LS_SOURCE 0 /** * Start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us) @@ -331,7 +232,7 @@ extern "C" { #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) + * Maximum duration of the connection event when the device is in Peripheral mode in units of 625/256 us (~2.44 us) */ #define CFG_BLE_MAX_CONN_EVENT_LENGTH (0xFFFFFFFF) @@ -512,6 +413,7 @@ extern "C" { /** tick timer value in us */ #define CFG_TS_TICK_VAL DIVR((CFG_RTCCLK_DIV * 1000000), LSE_VALUE) +#define CFG_TS_TICK_VAL_PS DIVR(((uint64_t) CFG_RTCCLK_DIV * 1e12), (uint64_t) LSE_VALUE) typedef enum { @@ -631,6 +533,16 @@ typedef enum #endif /* CFG_FULL_LOW_POWER */ /* USER CODE END Defines */ +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_NAME "CONN_INT_UPD_REQ" +#define CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY osPriorityNormal +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE (128 * 8) +#endif + /****************************************************************************** * LOW POWER ******************************************************************************/ @@ -648,12 +560,124 @@ typedef enum /* USER CODE END CFG_LPM_Id_t */ } CFG_LPM_Id_t; +/****************************************************************************** + * FreeRTOS + ******************************************************************************/ +/* USER CODE BEGIN FreeRTOS */ + +#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 osPriorityNone +#define CFG_SHCI_USER_EVT_PROCESS_STACK_SIZE (128 * 20) + +#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 osPriorityLow +#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_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 osPriorityNone +#define CFG_HCI_USER_EVT_PROCESS_STACK_SIZE (128 * 40) + +#define CFG_ADV_CANCEL_PROCESS_NAME "ADV_CANCEL_PROCESS" +#define CFG_ADV_CANCEL_PROCESS_ATTR_BITS (0) +#define CFG_ADV_CANCEL_PROCESS_CB_MEM (0) +#define CFG_ADV_CANCEL_PROCESS_CB_SIZE (0) +#define CFG_ADV_CANCEL_PROCESS_STACK_MEM (0) +#define CFG_ADV_CANCEL_PROCESS_PRIORITY osPriorityNormal +#define CFG_ADV_CANCEL_PROCESS_STACK_SIZE (128 * 8) + +#define CFG_P2PS_SEND_NOTIF_PROCESS_NAME "P2PS_SEND_NOTIF_PROCESS" +#define CFG_P2PS_SEND_NOTIF_PROCESS_ATTR_BITS (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_CB_MEM (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_CB_SIZE (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_STACK_MEM (0) +#define CFG_P2PS_SEND_NOTIF_PROCESS_PRIORITY osPriorityNormal +#define CFG_P2PS_SEND_NOTIF_PROCESS_STACK_SIZE (128 * 8) + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_NAME "CONN_INT_UPD_REQ" +#define CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM (0) +#define CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY osPriorityNormal +#define CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE (128 * 8) +#endif + +#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) + +#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) +/* USER CODE END FreeRTOS_Defines */ + /****************************************************************************** * OTP manager ******************************************************************************/ #define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE -#define CFG_OTP_END_ADDRESS OTP_AREA_END_ADDR +#define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR + +/****************************************************************************** + * OTA support + ******************************************************************************/ +#define OTA_SUPPORT 0 + +/****************************************************************************** + * LCD support + ******************************************************************************/ +#define CFG_LCD_SUPPORTED 1 + +#if ((OTA_SUPPORT == 1) || (CFG_FULL_LOW_POWER == 1)) +/****************************************************************************** + * LCD support + ******************************************************************************/ +#undef CFG_LCD_SUPPORTED +#define CFG_LCD_SUPPORTED 0 +#endif + +/****************************************************************************** + * versions + ******************************************************************************/ +#define X_CUBE_MATTER_VERSION "1.0.3" +#define PRODUCT_NAME "Dimmable Light" +#define VENDOR_NAME "STMicroelectronics" +#define HARDWARE_VERSION "STM32WB5MM-DK" +#define MATTER_SDK_VERSION "github CSA" + +/****************************************************************************** + * Matter Factory data + ******************************************************************************/ +#define CONFIG_STM32_FACTORY_DATA_ENABLE 0 typedef enum { diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h new file mode 100644 index 00000000000000..6ea86e05ffa9f8 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_debug.h @@ -0,0 +1,67 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_debug.h + * @author MCD Application Team + * @brief Header for app_debug.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 APP_DEBUG_H +#define APP_DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported variables --------------------------------------------------------*/ +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/* Exported macros ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions ---------------------------------------------*/ +void APPD_Init(void); +void APPD_EnableCPU2(void); +/* USER CODE BEGIN EF */ + +/* USER CODE END EF */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /*APP_DEBUG_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 index 9d0378c18792c1..ff90bc72025585 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/app_entry.h @@ -48,7 +48,6 @@ 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 } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h deleted file mode 100644 index 24f4cfc6253572..00000000000000 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_driver.h +++ /dev/null @@ -1,181 +0,0 @@ -/* 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 index 5a866b3edf7fbe..010881188f6feb 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/flash_wb.h @@ -40,6 +40,7 @@ typedef enum NVM_BLOCK_SIZE_OVERFLOW, NVM_ERROR_BLOCK_ALIGN, NVM_FLASH_CORRUPTION, + NVM_PARAM_ERROR, NVM_BUFFER_TOO_SMALL } NVM_StatusTypeDef; @@ -57,19 +58,13 @@ typedef enum * @brief Copy Flash to RAM NVM */ -void NM_Init(void); +NVM_StatusTypeDef 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 * @@ -86,7 +81,6 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t * * @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 @@ -103,11 +97,16 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi NVM_StatusTypeDef NM_DeleteKey(const char * Keyname, NVM_Sector sector); /** - * @brief Erase all persistent and reboot program + * @brief Get the address of the OT NVM buffer + * @param Addr: return the Address of the OT buffer + * @retval return state of function */ +NVM_StatusTypeDef NM_GetOtNVMAddr(uint32_t * NVMAddr); +/** + * @brief Erase all persistent and reboot program + */ void NM_ResetFactory(void); -void NM_FullErase(void); #ifdef __cplusplus } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h index 109084d298637f..4614e33b58a817 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/hw_conf.h @@ -20,6 +20,7 @@ #ifndef __HW_CONF_H #define __HW_CONF_H +#include "FreeRTOSConfig.h" /****************************************************************************** * Semaphores * THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+ @@ -81,7 +82,7 @@ * wakeup timer. * This setting is the preemptpriority part of the NVIC. */ -#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO 3 +#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1) /* FreeRTOS requirement */ /** * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h index 6ea2f076e6a8ae..ca1b5ffa4bea36 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/main.h @@ -35,7 +35,7 @@ #include "x_nucleo_epd.h" #endif #ifdef USE_STM32WB5M_DK -#include "./../../../../../Drivers/BSP/STM32WB5MM-DK/stm32wb5mm_dk.h" +#include "stm32wb5mm_dk.h" #endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h new file mode 100644 index 00000000000000..dbce1040104dd4 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/ota.h @@ -0,0 +1,50 @@ +/* + * + * 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. + */ + +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef OTA_H +#define OTA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/*! Attribute structure */ +typedef struct +{ + uint16_t vendorId; /*! VendorId info from image header */ + uint16_t productId; /*! ProductId info from image header */ + uint32_t softwareVersion; /*! Software version of the binary */ + uint32_t minApplicableVersion; /*! Minimum running software version to be compatible with the OTA image */ + uint32_t maxApplicableVersion; /*! Maximum running software version to be compatible with the OTA image */ +} Ota_ImageHeader_t; + +void InitializeOTARequestor(void); +bool OtaHeaderValidation(Ota_ImageHeader_t imageHeader); +void TriggerOTAQuery(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* OTA_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h new file mode 100644 index 00000000000000..009853e8989420 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/s25fl128s_conf.h @@ -0,0 +1,77 @@ +/** + ****************************************************************************** + * @file s25fl128s_conf_template.h + * @author MCD Application Team + * @brief This file contains the configurations of the S25FL128S QSPI memory. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef S25FL128S_CONF_H +#define S25FL128S_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wbxx_hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup Components + * @{ + */ + +/** @addtogroup S25FL128S + * @brief This file provides a set of definitions for the Spansion + * S25FL128S memory configuration. + * @{ + */ + +/** @addtogroup S25FL128S_Exported_Constants + * @{ + */ + +#define CONF_S25FL128S_READ_ENHANCE 0 /* MMP performance enhance read enable/disable */ +#define CONF_QSPI_DUMMY_CLOCK 8U + +/* Dummy cycles for STR read mode */ +#define S25FL128S_DUMMY_CYCLES_READ_QUAD 8U +#define S25FL128S_DUMMY_CYCLES_READ 8U +#define S25FL128S_DUMMY_CYCLES_READ_DUAL_INOUT 4U +#define S25FL128S_DUMMY_CYCLES_READ_QUAD_INOUT 6U + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* S25FL128S_CONF_H */ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h new file mode 100644 index 00000000000000..ddf384fa03e2e3 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32_factorydata.h @@ -0,0 +1,78 @@ +/* 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 STM32_FACTORYDATA_H +#define STM32_FACTORYDATA_H + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PRIVATE_KEY_LEN 32 +#define PUBLIC_KEY_LEN 65 +typedef enum +{ + DATAFACTORY_OK, + DATAFACTORY_DATA_NOT_FOUND, + DATAFACTORY_BUFFER_TOO_SMALL, + DATAFACTORY_PARAM_ERROR, + +} FACTORYDATA_StatusTypeDef; + +typedef enum +{ + /* DeviceAttestationCredentialsProvider */ + TAG_ID_CERTIFICATION_DECLARATION = 1, + TAG_ID_FIRMWARE_INFORMATION = 2, + TAG_ID_DEVICE_ATTESTATION_CERTIFICATE = 3, + TAG_ID_PRODUCT_ATTESTATION_INTERMEDIATE_CERTIFICATE = 4, + TAG_ID_DEVICE_ATTESTATION_PRIVATE_KEY = 5, + TAG_ID_DEVICE_ATTESTATION_PUBLIC_KEY = 6, + /* CommissionableDataProvider */ + TAG_ID_SETUP_DISCRIMINATOR = 11, + TAG_ID_SPAKE2_ITERATION_COUNT = 12, + TAG_ID_SPAKE2_SALT = 13, + TAG_ID_SPAKE2_VERIFIER = 14, + TAG_ID_SPAKE2_SETUP_PASSCODE = 15, + /* DeviceInstanceInfoProvider */ + TAG_ID_VENDOR_NAME = 21, + TAG_ID_VENDOR_ID = 22, + TAG_ID_PRODUCT_NAME = 23, + TAG_ID_PRODUCT_ID = 24, + TAG_ID_SERIAL_NUMBER = 25, + TAG_ID_MANUFACTURING_DATE = 26, + TAG_ID_HARDWARE_VERSION = 27, + TAG_ID_HARDWARE_VERSION_STRING = 28, + TAG_ID_ROTATING_DEVICE_ID = 29, + /* Platform specific */ + TAG_ID_ENABLE_KEY = 41, + +} FACTORYDATA_TagId; + +FACTORYDATA_StatusTypeDef FACTORYDATA_GetValue(FACTORYDATA_TagId tag, uint8_t * data, uint32_t size, uint32_t * out_datalength); + +#ifdef __cplusplus +} +#endif +#endif /*STM32_FACTORYDATA_H*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h new file mode 100644 index 00000000000000..f525f6e1c7ed65 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wb5mm_dk_qspi.h @@ -0,0 +1,213 @@ +/** + ****************************************************************************** + * @file stm32wb5mm_dk_qspi.h + * @author MCD Application Team + * @brief This file contains the common defines and functions prototypes for + * the stm32wb5mm_dk_qspi.c driver. + ****************************************************************************** + * @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. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WB5MM_DK_QSPI_H +#define STM32WB5MM_DK_QSPI_H + +#ifdef __cplusplus +extern "C" { +#endif +/* Includes ------------------------------------------------------------------*/ +#include "../Components/s25fl128s/s25fl128s.h" +#include "stm32wb5mm_dk_conf.h" +#include "stm32wb5mm_dk_errno.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WB5MM_DK + * @{ + */ + +/** @addtogroup STM32WB5MM_DK_QSPI + * @{ + */ +/* Exported types ------------------------------------------------------------*/ +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Types Exported Types + * @{ + */ +#define BSP_QSPI_Info_t S25FL128S_Info_t +#define BSP_QSPI_Interface_t S25FL128S_Interface_t +#define BSP_QSPI_Transfer_t S25FL128S_Transfer_t +#define BSP_QSPI_DualFlash_t S25FL128S_DualFlash_t +#define BSP_QSPI_Erase_t S25FL128S_Erase_t + +typedef enum +{ + QSPI_ACCESS_NONE = 0, /*!< Instance not initialized, */ + QSPI_ACCESS_INDIRECT, /*!< Instance use indirect mode access */ + QSPI_ACCESS_MMP /*!< Instance use Memory Mapped Mode read */ +} BSP_QSPI_Access_t; + +typedef struct +{ + BSP_QSPI_Access_t IsInitialized; /*!< Instance access Flash method */ + BSP_QSPI_Interface_t InterfaceMode; /*!< Flash Interface mode of Instance */ + BSP_QSPI_Transfer_t TransferRate; /*!< Flash Transfer mode of Instance */ + uint32_t DualFlashMode; /*!< Flash dual mode */ + uint32_t IsMspCallbacksValid; +} BSP_QSPI_Ctx_t; + +typedef struct +{ + BSP_QSPI_Interface_t InterfaceMode; /*!< Current Flash Interface mode */ + BSP_QSPI_Transfer_t TransferRate; /*!< Current Flash Transfer mode */ + BSP_QSPI_DualFlash_t DualFlashMode; /*!< Dual Flash mode */ +} BSP_QSPI_Init_t; + +typedef struct +{ + uint32_t FlashSize; + uint32_t ClockPrescaler; + uint32_t SampleShifting; + uint32_t DualFlashMode; +} MX_QSPI_Init_t; +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +typedef struct +{ + void (*pMspInitCb)(pQSPI_CallbackTypeDef); + void (*pMspDeInitCb)(pQSPI_CallbackTypeDef); +} BSP_QSPI_Cb_t; +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Constants Exported Constants + * @{ + */ +/* QSPI instances number */ +#define QSPI_INSTANCES_NUMBER 1U + +/* Definition for QSPI modes */ +#define BSP_QSPI_SPI_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_MODE /* 1 Cmd Line, 1 Address Line and 1 Data Line */ +#define BSP_QSPI_SPI_1I2O_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_1I2O_MODE /* 1 Cmd Line, 1 Address Line and 2 Data Lines */ +#define BSP_QSPI_SPI_2IO_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_2IO_MODE /* 1 Cmd Line, 2 Address Lines and 2 Data Lines */ +#define BSP_QSPI_SPI_1I4O_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_1I4O_MODE /* 1 Cmd Line, 1 Address Line and 4 Data Lines */ +#define BSP_QSPI_SPI_4IO_MODE (BSP_QSPI_Interface_t) S25FL128S_SPI_4IO_MODE /* 1 Cmd Line, 4 Address Lines and 4 Data Lines */ +#define BSP_QSPI_QPI_MODE (BSP_QSPI_Interface_t) S25FL128S_QPI_MODE /* 4 Cmd Lines, 4 Address Lines and 4 Data Lines */ + +/* Definition for QSPI transfer rates */ +#define BSP_QSPI_STR_TRANSFER (BSP_QSPI_Transfer_t) S25FL128S_STR_TRANSFER /* Single Transfer Rate */ + +/* Definition for QSPI dual flash mode */ +#define BSP_QSPI_DUALFLASH_DISABLE (BSP_QSPI_DualFlash_t) S25FL128S_DUALFLASH_DISABLE /* Single flash mode */ + +/* QSPI erase types */ +#define BSP_QSPI_ERASE_4K (BSP_QSPI_Erase_t) S25FL128S_ERASE_4K +#define BSP_QSPI_ERASE_64K (BSP_QSPI_Erase_t) S25FL128S_ERASE_64K +#define BSP_QSPI_ERASE_CHIP (BSP_QSPI_Erase_t) S25FL128S_ERASE_CHIP + +/* QSPI block sizes */ +#define BSP_QSPI_BLOCK_4K S25FL128S_SECTOR_4K +#define BSP_QSPI_BLOCK_64K S25FL128S_BLOCK_64K + +/* Definition for QSPI clock resources */ +#define QSPI_CLK_ENABLE() __HAL_RCC_QSPI_CLK_ENABLE() +#define QSPI_CLK_DISABLE() __HAL_RCC_QSPI_CLK_DISABLE() +#define QSPI_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_CLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define QSPI_D0_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define QSPI_D1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_D2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define QSPI_D3_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() + +#define QSPI_FORCE_RESET() __HAL_RCC_QSPI_FORCE_RESET() +#define QSPI_RELEASE_RESET() __HAL_RCC_QSPI_RELEASE_RESET() + +/* Definition for QSPI Pins */ +#define QSPI_CS_PIN GPIO_PIN_3 +#define QSPI_CS_GPIO_PORT GPIOD +#define QSPI_CLK_PIN GPIO_PIN_3 +#define QSPI_CLK_GPIO_PORT GPIOA +#define QSPI_D0_PIN GPIO_PIN_9 +#define QSPI_D0_GPIO_PORT GPIOB +#define QSPI_D1_PIN GPIO_PIN_5 +#define QSPI_D1_GPIO_PORT GPIOD +#define QSPI_D2_PIN GPIO_PIN_6 +#define QSPI_D2_GPIO_PORT GPIOD +#define QSPI_D3_PIN GPIO_PIN_7 +#define QSPI_D3_GPIO_PORT GPIOD + +/* S25FL128S memory */ +/* Size of the flash */ +#define QSPI_FLASH_SIZE 26 +#define QSPI_PAGE_SIZE 256 + +/** + * @} + */ + +/** @addtogroup STM32WB5MM_DK_QSPI_Exported_Variables + * @{ + */ +extern QSPI_HandleTypeDef hqspi; +extern BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup STM32WB5MM_DK_QSPI_Exported_Functions + * @{ + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t * Init); +int32_t BSP_QSPI_DeInit(uint32_t Instance); +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +int32_t BSP_QSPI_RegisterMspCallbacks(uint32_t Instance, BSP_QSPI_Cb_t * CallBacks); +int32_t BSP_QSPI_RegisterDefaultMspCallbacks(uint32_t Instance); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t * pData, uint32_t ReadAddr, uint32_t Size); +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t * pData, uint32_t WriteAddr, uint32_t Size); +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize); +int32_t BSP_QSPI_EraseChip(uint32_t Instance); +int32_t BSP_QSPI_GetStatus(uint32_t Instance); +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t * pInfo); +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance); +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t * Id); + +/* These functions can be modified in case the current settings + need to be changed for specific application needs */ +HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef * hQspi, MX_QSPI_Init_t * Config); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WB5MM_DK_QSPI_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 index fbba7c4af75667..b5b6fe06460491 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm32wbxx_it.h @@ -37,20 +37,21 @@ 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); +#if (CFG_HW_USART1_ENABLED == 1) void USART1_IRQHandler(void); -void DMA2_Channel4_IRQHandler(void); +#endif +#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1) +void CFG_HW_USART1_DMA_TX_IRQHandler(void); +#endif +#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1) void CFG_HW_USART1_DMA_TX_IRQHandler(void); +#endif void RTC_WKUP_IRQHandler(void); +#if (CFG_HW_LPUART1_ENABLED == 1) void LPUART1_IRQHandler(void); -void DMA1_Channel4_IRQHandler(void); -void QUADSPI_IRQHandler(void); +#endif #ifdef __cplusplus } diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h new file mode 100644 index 00000000000000..f4bf139e2a3c37 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_ext_flash.h @@ -0,0 +1,73 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm_ext_flash.h + * @author MCD Application Team + * @brief Header file for stm_ext_flash.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 STM_EXT_FLASH_H +#define STM_EXT_FLASH_H + +/* Includes ------------------------------------------------------------------*/ +#include "utilities_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define EXTERNAL_FLASH_ADDRESS 0x90000000U +#define OTA_MAX_SIZE 0x100000 // 1 Mbytes + +typedef enum +{ + STM_EXT_FLASH_OK, + STM_EXT_FLASH_INIT_FAILED, + STM_EXT_FLASH_WRITE_FAILED, + STM_EXT_FLASH_READ_FAILED, + STM_EXT_FLASH_DELETE_FAILED, + STM_EXT_FLASH_INVALID_PARAM, + STM_EXT_FLASH_SIZE_FULL +} STM_OTA_StatusTypeDef; + +/* Exported variables ------------------------------------------------------- */ +/* Exported functions ------------------------------------------------------- */ + +/** + * @brief init ota fw + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_Init(void); + +/** + * @brief Delete old image in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_Delete_Image(uint32_t Address, uint32_t Length); + +/** + * @brief Write chunk of data in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_WriteChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length); + +/** + * @brief Read chunk of data in external flash + */ +STM_OTA_StatusTypeDef STM_EXT_FLASH_ReadChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length); + +#ifdef __cplusplus +} +#endif + +#endif /*STM_EXT_FLASH_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 index 21400abd1df463..e34783ebc1307b 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Inc/stm_logging.h @@ -66,6 +66,6 @@ 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/STM32_WPAN/App/app_ble.c b/examples/platform/stm32/common/STM32WB5MM-DK/STM32_WPAN/App/app_ble.c index 4200191a38a0e9..7863775d427146 100644 --- 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 @@ -161,11 +161,6 @@ 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 */ @@ -174,8 +169,8 @@ typedef struct /* 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 FAST_ADV_TIMEOUT (30 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 30s */ +#define INITIAL_ADV_TIMEOUT (1 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 60s */ #define BD_ADDR_SIZE_LOCAL 6 @@ -188,20 +183,6 @@ typedef struct /* 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; @@ -213,17 +194,17 @@ static const uint8_t M_bd_addr[BD_ADDR_SIZE_LOCAL] = { static uint8_t bd_addr_udn[BD_ADDR_SIZE_LOCAL]; /** - * Identity root key used to derive LTK and CSRK + * Identity root key used to derive IRK and DHK(Legacy) */ -static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IRK; +static const uint8_t BLE_CFG_IR_VALUE[16] = CFG_BLE_IR; /** - * Encryption root key used to derive LTK and CSRK + * Encryption root key used to derive LTK(Legacy) and CSRK */ -static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ERK; +static const uint8_t BLE_CFG_ER_VALUE[16] = CFG_BLE_ER; -PLACE_IN_SECTION("BLE_APP_CONTEXT") static BleApplicationContext_t BleApplicationContext; -PLACE_IN_SECTION("BLE_APP_CONTEXT") static uint16_t AdvIntervalMin, AdvIntervalMax; +static BleApplicationContext_t BleApplicationContext; +static uint16_t AdvIntervalMin, AdvIntervalMax; MATTER_App_Notification_evt_t handleNotification; @@ -245,18 +226,45 @@ uint8_t manuf_data[15] = { /* USER CODE END PV */ +/* Global variables ----------------------------------------------------------*/ +osMutexId_t MtxHciId; +osSemaphoreId_t SemHciId; +osThreadId_t HciUserEvtProcessId; +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +osThreadId_t ConnIntUpdateReqProcessId; +#endif + +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 }; + +#if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +const osThreadAttr_t ConnIntUpdateReqProcess_attr = { .name = CFG_CONN_INT_UPD_REQ_PROCESS_NAME, + .attr_bits = CFG_CONN_INT_UPD_REQ_PROCESS_ATTR_BITS, + .cb_mem = CFG_CONN_INT_UPD_REQ_PROCESS_CB_MEM, + .cb_size = CFG_CONN_INT_UPD_REQ_PROCESS_CB_SIZE, + .stack_mem = CFG_CONN_INT_UPD_REQ_PROCESS_STACK_MEM, + .priority = CFG_CONN_INT_UPD_REQ_PROCESS_PRIORITY, + .stack_size = CFG_CONN_INT_UPD_REQ_PROCESS_STACK_SIZE }; +#endif + /* 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 HciUserEvtProcess(void * argument); static void Switch_OFF_GPIO(void); #if (L2CAP_REQUEST_NEW_CONN_PARAM != 0) +static void ConnIntUpdateReqProcess(void * argument); 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 */ @@ -267,6 +275,7 @@ 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 */ @@ -278,9 +287,9 @@ void APP_BLE_Init_Dyn_1(void) 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_PERIPHERAL_SCA, + CFG_BLE_CENTRAL_SCA, + CFG_BLE_LS_SOURCE, CFG_BLE_MAX_CONN_EVENT_LENGTH, CFG_BLE_HSE_STARTUP_TIME, CFG_BLE_VITERBI_MODE, @@ -300,8 +309,6 @@ void APP_BLE_Init_Dyn_1(void) */ 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 */ @@ -327,27 +334,26 @@ void APP_BLE_Init_Dyn_1(void) */ 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) + ConnIntUpdateReqProcessId = osThreadNew(ConnIntUpdateReqProcess, NULL, &ConnIntUpdateReqProcess_attr); + index_con_int = 0; mutex = 1; #endif /** - * Initialize P2P Server Application + * Initialize Matter 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); + return; } void APP_BLE_Init_Dyn_2(void) @@ -361,26 +367,16 @@ void APP_BLE_Init_Dyn_2(void) AdvIntervalMin = CFG_FAST_CONN_ADV_INTERVAL_MIN; AdvIntervalMax = CFG_FAST_CONN_ADV_INTERVAL_MAX; + /** + * Start to Advertise to be connected by P2P Client + */ +#if (CFG_LPM_SUPPORTED == 1) + APP_BLE_Adv_Request(APP_BLE_LP_ADV); +#endif /* 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); + return; } SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt) @@ -437,8 +433,6 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void * pckt) */ 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) @@ -486,15 +480,13 @@ APP_BLE_ConnStatus_t APP_BLE_Get_Server_Connection_Status(void) return BleApplicationContext.Device_Connection_Status; } +/* USER CODE BEGIN FD*/ +void APP_BLE_Key_Button1_Action(void) {} + 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; + osThreadFlagsSet(ConnIntUpdateReqProcessId, 1); #endif } @@ -502,9 +494,7 @@ 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(); } @@ -518,6 +508,8 @@ static void Ble_Tl_Init(void) { HCI_TL_HciInitConf_t Hci_Tl_Init_Conf; + MtxHciId = osMutexNew(NULL); + SemHciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ 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); @@ -549,13 +541,13 @@ static void Ble_Hci_Gap_Gatt_Init(void) 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]; - // + // 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 @@ -567,7 +559,7 @@ static void Ble_Hci_Gap_Gatt_Init(void) 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 + * Write Identity root key used to derive IRK and DHK(Legacy) */ aci_hal_write_config_data(CONFIG_DATA_IR_OFFSET, CONFIG_DATA_IR_LEN, (uint8_t *) BLE_CFG_IR_VALUE); @@ -642,7 +634,7 @@ static void Ble_Hci_Gap_Gatt_Init(void) } aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode, - BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 1, 0, + BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode, 0, 0, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax, BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin, @@ -700,7 +692,6 @@ void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status) /* 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) @@ -709,14 +700,14 @@ void APP_BLE_Adv_Request(APP_BLE_ConnStatus_t New_Status) } else { - APP_DBG_MSG("Successfully Start Low Power Advertising \n"); + APP_DBG_MSG("\n\rSuccessfully Start Low Power Advertising \n\r"); } } else { if (New_Status == APP_BLE_FAST_ADV) { - APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n", ret); + APP_DBG_MSG("Start Fast Advertising Failed , result: %d \n\r", ret); } else { @@ -785,15 +776,9 @@ const uint8_t * BleGetBdAddress(void) *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) @@ -825,7 +810,6 @@ void APP_BLE_Adv_Cancel(void) static void Switch_OFF_GPIO() { /* USER CODE BEGIN Switch_OFF_GPIO */ - // BSP_LED_Off(LED_GREEN); /* USER CODE END Switch_OFF_GPIO */ } @@ -841,12 +825,12 @@ void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle) 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 peripheral_latency = L2CAP_PERIPHERAL_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); + interval_min, interval_max, peripheral_latency, timeout_multiplier); if (result == BLE_STATUS_SUCCESS) { APP_DBG_MSG("BLE_SVC_L2CAP_Conn_Update(), Successfully \r\n\r"); @@ -861,16 +845,21 @@ void BLE_SVC_L2CAP_Conn_Update(uint16_t Connection_Handle) /* 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 ConnIntUpdateReqProcess(void * argument) +{ + UNUSED(argument); + for (;;) + { + osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + 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); + } + } +} +#endif static void HciUserEvtProcess(void * argument) { @@ -883,39 +872,56 @@ static void HciUserEvtProcess(void * argument) } } +/* USER CODE BEGIN FD_SPECIFIC_FUNCTIONS */ + +/* USER CODE END FD_SPECIFIC_FUNCTIONS */ +/************************************************************* + * + * WRAP FUNCTIONS + * + *************************************************************/ void hci_notify_asynch_evt(void * pdata) { + UNUSED(pdata); + osThreadFlagsSet(HciUserEvtProcessId, 1); + return; } void hci_cmd_resp_release(uint32_t flag) { + UNUSED(flag); + osSemaphoreRelease(SemHciId); + return; } void hci_cmd_resp_wait(uint32_t timeout) { + UNUSED(timeout); + osSemaphoreAcquire(SemHciId, osWaitForever); + return; } static void BLE_UserEvtRx(void * pPayload) { SVCCTL_UserEvtFlowStatus_t svctl_return_status; - tHCI_UserEvtRxParam * pParam; + tHCI_UserEvtRxParam * p_param; - pParam = (tHCI_UserEvtRxParam *) pPayload; + p_param = (tHCI_UserEvtRxParam *) pPayload; - svctl_return_status = SVCCTL_UserEvtRx((void *) &(pParam->pckt->evtserial)); + svctl_return_status = SVCCTL_UserEvtRx((void *) &(p_param->pckt->evtserial)); if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; + p_param->status = HCI_TL_UserEventFlow_Enable; } else { - pParam->status = HCI_TL_UserEventFlow_Disable; + p_param->status = HCI_TL_UserEventFlow_Disable; } } @@ -929,7 +935,6 @@ static void BLE_StatusNot(HCI_TL_CmdStatus_t status) * This is to prevent a new command is sent while one is already pending */ osMutexAcquire(MtxHciId, osWaitForever); - break; case HCI_TL_CmdAvailable: @@ -938,7 +943,6 @@ static void BLE_StatusNot(HCI_TL_CmdStatus_t status) * This is to prevent a new command is sent while one is already pending */ osMutexRelease(MtxHciId); - break; default: 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 index cb0b80a25628f6..1197ff8ecd27b8 100644 --- 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 @@ -35,6 +35,7 @@ extern "C" { /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ + typedef enum { APP_BLE_IDLE, @@ -68,8 +69,6 @@ typedef enum /* 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 */ 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 index f917b8542fc4bf..dd58d369187e1e 100644 --- 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 @@ -44,15 +44,8 @@ /* Private defines -----------------------------------------------------------*/ #define C_SIZE_CMD_STRING 256U +#define THREAD_LINK_POLL_PERIOD (5 * 1000 * 1000 / CFG_TS_TICK_VAL) /**< 5s */ #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, @@ -62,15 +55,13 @@ const osThreadAttr_t ThreadMsgM0ToM4Process_attr = { .name = CFG_THREAD_MS .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 osSemaphoreId_t OtCmdProcessSem; +static osSemaphoreId_t OtCmdAckSem; + +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ -static volatile int FlagReceiveAckFromM0 = 0; /* Private macros ------------------------------------------------------------*/ /* USER CODE BEGIN PM */ @@ -78,38 +69,21 @@ static volatile int FlagReceiveAckFromM0 = 0; /* Private function prototypes -----------------------------------------------*/ static void APP_THREAD_CheckWirelessFirmwareInfo(void); +static void APP_THREAD_StateNotif(uint32_t NotifFlags, void * pContext); +static void APP_THREAD_DeviceConfig(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); + +/* FreeRTos wrapper functions */ 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; @@ -119,18 +93,20 @@ 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 BEGIN PV */ + /* USER CODE END PV */ /* Functions Definition ------------------------------------------------------*/ -void APP_THREAD_Init(void) +/** + * @brief Main entry point for the Thread Application + * @param none + * @retval None + */ +void APP_THREAD_Init_Dyn_1(void) { /* USER CODE BEGIN APP_THREAD_INIT_1 */ /* Do not allow stop mode before Thread is initialized */ @@ -153,32 +129,40 @@ void APP_THREAD_Init(void) /* 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); + /* Create the different FreeRTOS tasks requested to run this Thread application*/ + OsTaskMsgM0ToM4Id = osThreadNew(APP_THREAD_FreeRTOSProcessMsgM0ToM4Task, NULL, &ThreadMsgM0ToM4Process_attr); + + /* Create binary semaphores for OT command handling */ + OtCmdProcessSem = osSemaphoreNew(1, 1, NULL); + OtCmdAckSem = osSemaphoreNew(1, 0, NULL); + /* USER CODE BEGIN APP_THREAD_INIT_FREERTOS */ MoNotifQueue = xQueueCreate(MO_NOTIF_QUEUE_SIZE, sizeof(uint8_t)); if (MoNotifQueue == NULL) { APP_DBG("Failed to allocate M0 notification queue"); } + /* USER CODE END APP_THREAD_INIT_FREERTOS */ +} - /* Create the different FreeRTOS tasks requested to run this Thread application*/ - OsTaskMsgM0ToM4Id = osThreadNew(APP_THREAD_FreeRTOSProcessMsgM0ToM4Task, NULL, &ThreadMsgM0ToM4Process_attr); +void APP_THREAD_Init_Dyn_2(void) +{ + /* Initialize and configure the Thread device*/ +#if (CFG_LPM_SUPPORTED == 1) + APP_THREAD_DeviceConfig(); - /* 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 */ + /* Allow the 800_15_4 IP to enter in low power mode */ + SHCI_C2_RADIO_AllowLowPower(THREAD_IP, TRUE); + + /* Allow stop mode after Thread initialization*/ + UTIL_LPM_SetStopMode(1 << CFG_LPM_APP_THREAD, UTIL_LPM_ENABLE); +#endif } /** @@ -215,10 +199,13 @@ void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode) case ERR_THREAD_ERASE_PERSISTENT_INFO: APP_THREAD_TraceError("ERROR : ERR_THREAD_ERASE_PERSISTENT_INFO ", ErrCode); break; + case ERR_THREAD_SET_NETWORK_KEY: + APP_THREAD_TraceError("ERROR : ERR_THREAD_SET_NETWORK_KEY ", ErrCode); + break; case ERR_THREAD_CHECK_WIRELESS: APP_THREAD_TraceError("ERROR : ERR_THREAD_CHECK_WIRELESS ", ErrCode); break; - /* USER CODE BEGIN APP_THREAD_Error_2 */ + /* USER CODE BEGIN APP_THREAD_Error_2 */ case ERR_THREAD_COAP_START: APP_THREAD_TraceError("ERROR : ERR_THREAD_COAP_START ", ErrCode); break; @@ -243,164 +230,101 @@ void APP_THREAD_Error(uint32_t ErrId, uint32_t ErrCode) case ERR_TIMER_START: APP_THREAD_TraceError("ERROR : ERR_TIMER_START ", ErrCode); break; - /* USER CODE END APP_THREAD_Error_2 */ + /* 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+. + * LOCAL FUNCTIONS * - * @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 + * @brief Thread initialization. + * @param None + * @retval None */ -void TL_THREAD_CliNotReceived(TL_EvtPacket_t * Notbuffer) +static void APP_THREAD_DeviceConfig(void) { - 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) + otError error = OT_ERROR_NONE; + otLinkModeConfig OT_LinkMode = { 0 }; + /* Set the pool period to 5 sec. It means that when the device will enter + * in 'sleepy end device' mode, it will send an ACK_Request every 5 sec. + * This message will act as keep alive message. + */ + error = otLinkSetPollPeriod(NULL, THREAD_LINK_POLL_PERIOD); + /* Set the sleepy end device mode */ + OT_LinkMode.mRxOnWhenIdle = 0; + OT_LinkMode.mDeviceType = 0; + OT_LinkMode.mNetworkData = 1U; + + error = otThreadSetLinkMode(NULL, OT_LinkMode); + if (error != OT_ERROR_NONE) { - /* Write to CLI UART */ - HW_UART_Transmit_IT(CFG_CLI_UART, l_CliBuffer->cmdserial.cmd.payload, l_size, HostTxCb); + APP_THREAD_Error(ERR_THREAD_LINK_MODE, error); } - else + error = otIp6SetEnabled(NULL, true); + if (error != OT_ERROR_NONE) + { + APP_THREAD_Error(ERR_THREAD_IPV6_ENABLE, error); + } + error = otThreadSetEnabled(NULL, true); + if (error != OT_ERROR_NONE) { - Send_CLI_Ack_For_OT(); + APP_THREAD_Error(ERR_THREAD_START, error); } } - -/** - * @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 +/* @brief Thread notification when the state changes. + * @param aFlags : Define the item that has been modified + * aContext: Context * @retval None */ -void Pre_OtCmdProcessing(void) +static void APP_THREAD_StateNotif(uint32_t NotifFlags, void * pContext) { - osMutexAcquire(MtxThreadId, osWaitForever); -} - -void APP_THREAD_RegisterCmdBuffer(TL_CmdPacket_t * p_buffer) -{ - p_thread_otcmdbuffer = p_buffer; -} + /* Prevent unused argument(s) compilation warning */ + UNUSED(pContext); -Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) p_thread_otcmdbuffer->cmdserial.cmd.payload; -} + /* USER CODE BEGIN APP_THREAD_STATENOTIF */ -Thread_OT_Cmd_Request_t * THREAD_Get_OTCmdRspPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) ((TL_EvtPacket_t *) p_thread_otcmdbuffer)->evtserial.evt.payload; -} + /* USER CODE END APP_THREAD_STATENOTIF */ -Thread_OT_Cmd_Request_t * THREAD_Get_NotificationPayloadBuffer(void) -{ - return (Thread_OT_Cmd_Request_t *) (p_thread_notif_M0_to_M4)->evtserial.evt.payload; + if ((NotifFlags & (uint32_t) OT_CHANGED_THREAD_ROLE) == (uint32_t) OT_CHANGED_THREAD_ROLE) + { + switch (otThreadGetDeviceRole(NULL)) + { + case OT_DEVICE_ROLE_DISABLED: + /* USER CODE BEGIN OT_DEVICE_ROLE_DISABLED */ + /* USER CODE END OT_DEVICE_ROLE_DISABLED */ + break; + case OT_DEVICE_ROLE_DETACHED: + /* USER CODE BEGIN OT_DEVICE_ROLE_DETACHED */ + /* USER CODE END OT_DEVICE_ROLE_DETACHED */ + break; + case OT_DEVICE_ROLE_CHILD: + /* USER CODE BEGIN OT_DEVICE_ROLE_CHILD */ + /* USER CODE END OT_DEVICE_ROLE_CHILD */ + break; + case OT_DEVICE_ROLE_ROUTER: + /* USER CODE BEGIN OT_DEVICE_ROLE_ROUTER */ + /* USER CODE END OT_DEVICE_ROLE_ROUTER */ + break; + case OT_DEVICE_ROLE_LEADER: + /* USER CODE BEGIN OT_DEVICE_ROLE_LEADER */ + /* USER CODE END OT_DEVICE_ROLE_LEADER */ + break; + default: + /* USER CODE BEGIN DEFAULT */ + /* USER CODE END DEFAULT */ + break; + } + } } -/************************************************************* - * - * LOCAL FUNCTIONS - * - *************************************************************/ - /** * @brief Warn the user that an error has occurred.In this case, * the LEDs on the Board will start blinking. @@ -438,30 +362,16 @@ static void APP_THREAD_CheckWirelessFirmwareInfo(void) 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); + APP_DBG("PRODUCT NAME : " PRODUCT_NAME); + APP_DBG("VENDOR NAME : " VENDOR_NAME); + APP_DBG("HARDWARE : " HARDWARE_VERSION); + APP_DBG("SOFTWARE : X-CUBE-MATTER release revision " X_CUBE_MATTER_VERSION); + APP_DBG("Embedded SW components :"); + APP_DBG("- Matter SDK version : " MATTER_SDK_VERSION); + APP_DBG("- STM32WB Cube Firmware Version : %d.%d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, + p_wireless_info->VersionSub, p_wireless_info->VersionBranch); + APP_DBG("**********************************************************"); - 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("**********************************************************"); } } @@ -478,7 +388,6 @@ static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument) 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); @@ -496,25 +405,8 @@ static void APP_THREAD_FreeRTOSProcessMsgM0ToM4Task(void * argument) } } -#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 */ @@ -526,6 +418,27 @@ static void APP_THREAD_FreeRTOSSendCLIToM0Task(void * argument) * WRAP FUNCTIONS * *************************************************************/ + +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; +} + static void Ot_Cmd_Transfer_Common(void) { /* OpenThread OT command cmdcode range 0x280 .. 0x3DF = 352 */ @@ -542,122 +455,159 @@ static void Ot_Cmd_Transfer_Common(void) } /** - * @brief This function waits for getting an acknowledgment from the M0. + * @brief This function is used to transfer the Ot commands from the + * M4 to the M0. * - * @param None - * @retval None + * @param None + * @return None */ -static void Wait_Getting_Ack_From_M0(void) +void Ot_Cmd_Transfer(void) { - while (FlagReceiveAckFromM0 == 0) - { - } - FlagReceiveAckFromM0 = 0; - osMutexRelease(MtxThreadId); - // osSemaphoreAcquire( TransferToM0Semaphore, osWaitForever ); + Ot_Cmd_Transfer_Common(); } /** - * @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 + * @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 */ -static void Receive_Ack_From_M0(void) +void Ot_Cmd_TransferWithNotif(void) { - FlagReceiveAckFromM0 = 1; - // osSemaphoreRelease( TransferToM0Semaphore); + /* Flag to specify to UTIL_SEQ_EvtIdle that M0 to M4 notifications are allowed */ + g_ot_notification_allowed = 1U; + + Ot_Cmd_Transfer_Common(); } /** - * @brief Receive a notification from the M0+ through the IPCC. - * This function is called under interrupt. + * @brief Perform initialization of TL for THREAD. * @param None * @retval None */ -static void Receive_Notification_From_M0(void) +void APP_THREAD_TL_THREAD_INIT(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); + ThreadConfigBuffer.p_ThreadOtCmdRspBuffer = (uint8_t *) &ThreadOtCmdBuffer; + ThreadConfigBuffer.p_ThreadNotAckBuffer = (uint8_t *) ThreadNotifRspEvtBuffer; + ThreadConfigBuffer.p_ThreadCliRspBuffer = (uint8_t *) &ThreadCliCmdBuffer; + ThreadConfigBuffer.p_ThreadCliNotBuffer = (uint8_t *) &ThreadCliNotBuffer; - /* 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); + TL_THREAD_Init(&ThreadConfigBuffer); } -#if (CFG_FULL_LOW_POWER == 0) -static void RxCpltCallback(void) +/** + * @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) { - /* Filling buffer and wait for '\r' char */ - if (indexReceiveChar < C_SIZE_CMD_STRING) - { - CommandString[indexReceiveChar++] = aRxBuffer[0]; - if (aRxBuffer[0] == '\r') - { - CptReceiveCmdFromUser = 1U; + TL_CmdPacket_t * l_CliBuffer = (TL_CmdPacket_t *) Notbuffer; + uint8_t l_size = l_CliBuffer->cmdserial.cmd.plen; - /* UART task scheduling*/ - osThreadFlagsSet(OsTaskCliId, 1); - } + /* 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) + { + /* Do nothing CLI is not enable */ + } + else + { + /* Notify M0 that characters have been sent to UART */ + TL_THREAD_CliSendAck(); } +} + +/** + * @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); - /* Once a character has been sent, put back the device in reception mode */ - HW_UART_Receive_IT(CFG_CLI_UART, aRxBuffer, 1U, RxCpltCallback); + Receive_Ack_From_M0(); + + /* Does not allow OpenThread M0 to M4 notification */ + g_ot_notification_allowed = 0U; } -#endif /* (CFG_FULL_LOW_POWER == 0) */ -#if (CFG_FULL_LOW_POWER == 0) /** - * @brief Process sends receive CLI command to M0. - * @param None - * @retval None + * @brief This function is called when notification from M0+ is received. + * + * @param Notbuffer : a pointer to TL_EvtPacket_t + * @return None */ -static void Send_CLI_To_M0(void) +void TL_THREAD_NotReceived(TL_EvtPacket_t * Notbuffer) { - memset(ThreadCliCmdBuffer.cmdserial.cmd.payload, 0x0U, 255U); - memcpy(ThreadCliCmdBuffer.cmdserial.cmd.payload, CommandString, indexReceiveChar); - ThreadCliCmdBuffer.cmdserial.cmd.plen = indexReceiveChar; - ThreadCliCmdBuffer.cmdserial.cmd.cmdcode = 0x0; + p_thread_notif_M0_to_M4 = Notbuffer; - /* Clear receive buffer, character counter and command complete */ - CptReceiveCmdFromUser = 0; - indexReceiveChar = 0; - memset(CommandString, 0, C_SIZE_CMD_STRING); + Receive_Notification_From_M0(); +} - TL_CLI_SendCmd(); +/** + * @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) +{ + osSemaphoreAcquire(OtCmdProcessSem, osWaitForever); } -#endif /* (CFG_FULL_LOW_POWER == 0) */ /** - * @brief Send notification for CLI TL Channel. + * @brief This function waits for getting an acknowledgment from the M0. + * * @param None * @retval None */ -static void Send_CLI_Ack_For_OT(void) +static void Wait_Getting_Ack_From_M0(void) { + osSemaphoreAcquire(OtCmdAckSem, osWaitForever); + osSemaphoreRelease(OtCmdProcessSem); +} - /* Notify M0 that characters have been sent to UART */ - TL_THREAD_CliSendAck(); +/** + * @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) +{ + osSemaphoreRelease(OtCmdAckSem); } /** - * @brief End of transfer callback for CLI UART sending. - * - * @param Notbuffer : a pointer to TL_EvtPacket_t - * @return None + * @brief Receive a notification from the M0+ through the IPCC. + * This function is called under interrupt. + * @param None + * @retval None */ -static void HostTxCb(void) +static void Receive_Notification_From_M0(void) { - Send_CLI_Ack_For_OT(); + /* 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); } /* USER CODE BEGIN 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 index 512b3bcd544538..b4b31bfd25ad1c 100644 --- 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 @@ -110,16 +110,12 @@ typedef enum /* USER CODE END EM */ /* Exported functions ------------------------------------------------------- */ -void APP_THREAD_Init(void); +void APP_THREAD_Init_Dyn_1(void); +void APP_THREAD_Init_Dyn_2(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 */ 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 index a4e4a492cbc360..9a7479e48d9302 100644 --- 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 @@ -1,6 +1,6 @@ /** ****************************************************************************** - * @file custom_stm.c + * @file matter_stm.c * @author MCD Application Team * @brief matter Service using gatt(Custom STM) ****************************************************************************** @@ -234,6 +234,11 @@ static SVCCTL_EvtAckStatus_t Matter_Event_Handler(void * Event) Notification.DataTransfered.Length = attribute_modified->Attr_Data_Length; Notification.DataTransfered.pPayload = attribute_modified->Attr_Data; Notification.ConnectionHandle = attribute_modified->Connection_Handle; + if (Notification.DataTransfered.Length == 0) + { + /* Exit the function because of bad packet */ + break; + } APP_MATTER_Notification(&Notification); } } 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 index a4627c05ae9223..17240d11e36cbe 100644 --- 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 @@ -28,7 +28,7 @@ extern "C" { /* Includes ------------------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include + /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c new file mode 100644 index 00000000000000..49c95488297abf --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_debug.c @@ -0,0 +1,345 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file app_debug.c + * @author MCD Application Team + * @brief Debug capabilities source file for STM32WPAN Middleware + ****************************************************************************** + * @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 */ + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +#include "app_common.h" + +#include "app_debug.h" +#include "dbg_trace.h" +#include "shci.h" +#include "tl.h" +#include "utilities_common.h" +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +typedef PACKED_STRUCT +{ + GPIO_TypeDef * port; + uint16_t pin; + uint8_t enable; + uint8_t reserved; +} +APPD_GpioConfig_t; +/* USER CODE END PTD */ + +/* Private defines -----------------------------------------------------------*/ +/* USER CODE BEGIN PD */ +#define GPIO_NBR_OF_RF_SIGNALS 9 +#define GPIO_CFG_NBR_OF_FEATURES 43 +#define NBR_OF_TRACES_CONFIG_PARAMETERS 4 +#define NBR_OF_GENERAL_CONFIG_PARAMETERS 4 + +/** + * THIS SHALL BE SET TO A VALUE DIFFERENT FROM 0 ONLY ON REQUEST FROM ST SUPPORT + */ +#define BLE_DTB_CFG 0 + +/** + * System Debug Options flags to be configured with: + * - SHCI_C2_DEBUG_OPTIONS_IPCORE_LP + * - SHCI_C2_DEBUG_OPTIONS_IPCORE_NO_LP + * - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN + * - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_DIS + * which are used to set following configuration bits: + * - bit 0: 0: IP BLE core in LP mode 1: IP BLE core in run mode (no LP supported) + * - bit 1: 0: CPU2 STOP mode Enable 1: CPU2 STOP mode Disable + * - bit [2-7]: bits reserved ( shall be set to 0) + */ +#define SYS_DBG_CFG1 (SHCI_C2_DEBUG_OPTIONS_IPCORE_LP | SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN) +/* USER CODE END PD */ + +/* Private macros ------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ +PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig = { 0, 0, 0, 0 }; +PLACE_IN_SECTION("MB_MEM2") +ALIGN(4) static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig = { BLE_DTB_CFG, SYS_DBG_CFG1, { 0, 0 } }; + +#ifdef CFG_DEBUG_TRACE_UART +#if (CFG_HW_LPUART1_ENABLED == 1) +extern void MX_LPUART1_UART_Init(void); +#endif +#if (CFG_HW_USART1_ENABLED == 1) +extern void MX_USART1_UART_Init(void); +#endif +#endif + +/** + * THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT + * It provides timing information on the CPU2 activity. + * All configuration of (port, pin) is supported for each features and can be selected by the user + * depending on the availability + */ +static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] = { + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ISR - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_STACK_TICK - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_CMD_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ACL_DATA_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* SYS_CMD_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* RNG_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVM_PROCESS - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_GENERAL - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_EVT_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_ACL_DATA_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_SYS_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_SYS_EVT_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_CLI_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_OT_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_OT_ACK_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_CLI_ACK_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_MEM_MANAGER_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_TRACES_TX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* HARD_FAULT - Set on Entry / Reset on Exit */ + /* From v1.1.1 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */ + /* From v1.2.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* TIMER_SERVER_CALLBACK - Toggle on Entry */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* PES_ACTIVITY - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */ + /* From v1.3.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_WRITE_ONGOING - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_WRITE_COMPLETE - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_CLEANUP - Set on Entry / Reset on Exit */ + /* From v1.4.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* NVMA_START - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, + /* FLASH_EOP - Set on Entry / Reset on Exit */ /* The FLASH_EOP Debug GPIO trace is not supported since v1.5.0 */ + /* From v1.5.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* FLASH_WRITE - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* FLASH_ERASE - Set on Entry / Reset on Exit */ + /* From v1.6.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_RESCHEDULE_EVENT - Set on Entry / Reset on Exit */ + /* From v1.8.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_LLD_CMD_RX - Set on Entry / Reset on Exit */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* IPCC_BLE_LLD_ACK_TX - Set on Entry / Reset on Exit */ + /* From v1.9.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* BLE_ASYNCH_EVENT_NACKED - Set on Entry / Reset on Exit */ + /* From v1.17.0 */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_SFTIMER_IRQ */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_COMPC_WRAP */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_SWITCH_RADIO */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_PROG_SFTIMER */ + { GPIOA, LL_GPIO_PIN_0, 0, 0 }, /* DYNAMIC CONCURRENT - RTSM_RADIO_GRANTED_TO_15_4 */ +}; + +/** + * THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT + * This table is relevant only for BLE + * It provides timing information on BLE RF activity. + * New signals may be allocated at any location when requested by ST + * The GPIO allocated to each signal depend on the BLE_DTB_CFG value and cannot be changed + */ +#if (BLE_DTB_CFG == 7) +static const APPD_GpioConfig_t aRfConfigList[GPIO_NBR_OF_RF_SIGNALS] = { + { GPIOB, LL_GPIO_PIN_2, 0, 0 }, /* DTB10 - Tx/Rx SPI */ + { GPIOB, LL_GPIO_PIN_7, 0, 0 }, /* DTB11 - Tx/Tx SPI Clk */ + { GPIOA, LL_GPIO_PIN_8, 0, 0 }, /* DTB12 - Tx/Rx Ready & SPI Select */ + { GPIOA, LL_GPIO_PIN_9, 0, 0 }, /* DTB13 - Tx/Rx Start */ + { GPIOA, LL_GPIO_PIN_10, 0, 0 }, /* DTB14 - FSM0 */ + { GPIOA, LL_GPIO_PIN_11, 0, 0 }, /* DTB15 - FSM1 */ + { GPIOB, LL_GPIO_PIN_8, 0, 0 }, /* DTB16 - FSM2 */ + { GPIOB, LL_GPIO_PIN_11, 0, 0 }, /* DTB17 - FSM3 */ + { GPIOB, LL_GPIO_PIN_10, 0, 0 }, /* DTB18 - FSM4 */ +}; +#endif +/* USER CODE END PV */ + +/* Global variables ----------------------------------------------------------*/ +/* USER CODE BEGIN GV */ +/* USER CODE END GV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ +static void APPD_SetCPU2GpioConfig(void); +static void APPD_BleDtbCfg(void); +/* USER CODE END PFP */ + +/* Functions Definition ------------------------------------------------------*/ +void APPD_Init(void) +{ + /* USER CODE BEGIN APPD_Init */ + APPD_SetCPU2GpioConfig(); + APPD_BleDtbCfg(); + + /* USER CODE END APPD_Init */ + return; +} + +void APPD_EnableCPU2(void) +{ + /* USER CODE BEGIN APPD_EnableCPU2 */ + SHCI_C2_DEBUG_Init_Cmd_Packet_t DebugCmdPacket = { { { 0, 0, 0 } }, /**< Does not need to be initialized */ + { (uint8_t *) aGpioConfigList, (uint8_t *) &APPD_TracesConfig, + (uint8_t *) &APPD_GeneralConfig, GPIO_CFG_NBR_OF_FEATURES, + NBR_OF_TRACES_CONFIG_PARAMETERS, NBR_OF_GENERAL_CONFIG_PARAMETERS } }; + + /**< Traces channel initialization */ + TL_TRACES_Init(); + + /** GPIO DEBUG Initialization */ + SHCI_C2_DEBUG_Init(&DebugCmdPacket); + + /* USER CODE END APPD_EnableCPU2 */ + return; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static void APPD_SetCPU2GpioConfig(void) +{ + /* USER CODE BEGIN APPD_SetCPU2GpioConfig */ + GPIO_InitTypeDef gpio_config = { 0 }; + uint8_t local_loop; + uint16_t gpioa_pin_list; + uint16_t gpiob_pin_list; + uint16_t gpioc_pin_list; + + gpioa_pin_list = 0; + gpiob_pin_list = 0; + gpioc_pin_list = 0; + + for (local_loop = 0; local_loop < GPIO_CFG_NBR_OF_FEATURES; local_loop++) + { + if (aGpioConfigList[local_loop].enable != 0) + { + switch ((uint32_t) aGpioConfigList[local_loop].port) + { + case (uint32_t) GPIOA: + gpioa_pin_list |= aGpioConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOB: + gpiob_pin_list |= aGpioConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOC: + gpioc_pin_list |= aGpioConfigList[local_loop].pin; + break; + + default: + break; + } + } + } + + gpio_config.Pull = GPIO_NOPULL; + gpio_config.Mode = GPIO_MODE_OUTPUT_PP; + gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + + if (gpioa_pin_list != 0) + { + gpio_config.Pin = gpioa_pin_list; + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_C2GPIOA_CLK_ENABLE(); + HAL_GPIO_Init(GPIOA, &gpio_config); + HAL_GPIO_WritePin(GPIOA, gpioa_pin_list, GPIO_PIN_RESET); + } + + if (gpiob_pin_list != 0) + { + gpio_config.Pin = gpiob_pin_list; + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_C2GPIOB_CLK_ENABLE(); + HAL_GPIO_Init(GPIOB, &gpio_config); + HAL_GPIO_WritePin(GPIOB, gpiob_pin_list, GPIO_PIN_RESET); + } + + if (gpioc_pin_list != 0) + { + gpio_config.Pin = gpioc_pin_list; + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_C2GPIOC_CLK_ENABLE(); + HAL_GPIO_Init(GPIOC, &gpio_config); + HAL_GPIO_WritePin(GPIOC, gpioc_pin_list, GPIO_PIN_RESET); + } + + /* USER CODE END APPD_SetCPU2GpioConfig */ + return; +} + +static void APPD_BleDtbCfg(void) +{ +/* USER CODE BEGIN APPD_BleDtbCfg */ +#if (BLE_DTB_CFG != 0) + GPIO_InitTypeDef gpio_config = { 0 }; + uint8_t local_loop; + uint16_t gpioa_pin_list; + uint16_t gpiob_pin_list; + + gpioa_pin_list = 0; + gpiob_pin_list = 0; + + for (local_loop = 0; local_loop < GPIO_NBR_OF_RF_SIGNALS; local_loop++) + { + if (aRfConfigList[local_loop].enable != 0) + { + switch ((uint32_t) aRfConfigList[local_loop].port) + { + case (uint32_t) GPIOA: + gpioa_pin_list |= aRfConfigList[local_loop].pin; + break; + + case (uint32_t) GPIOB: + gpiob_pin_list |= aRfConfigList[local_loop].pin; + break; + + default: + break; + } + } + } + + gpio_config.Pull = GPIO_NOPULL; + gpio_config.Mode = GPIO_MODE_AF_PP; + gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_config.Alternate = GPIO_AF6_RF_DTB7; + + if (gpioa_pin_list != 0) + { + gpio_config.Pin = gpioa_pin_list; + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_C2GPIOA_CLK_ENABLE(); + HAL_GPIO_Init(GPIOA, &gpio_config); + } + + if (gpiob_pin_list != 0) + { + gpio_config.Pin = gpiob_pin_list; + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_C2GPIOB_CLK_ENABLE(); + HAL_GPIO_Init(GPIOB, &gpio_config); + } +#endif + + /* USER CODE END APPD_BleDtbCfg */ + return; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp index f631165467e749..cf0cb741c54f10 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/app_entry.cpp @@ -19,12 +19,15 @@ /* Includes ------------------------------------------------------------------*/ #include "app_entry.h" +#include "AppTask.h" #include "app_ble.h" #include "app_common.h" #include "app_conf.h" +#include "app_debug.h" #include "app_thread.h" #include "cmsis_os.h" #include "dbg_trace.h" +#include "flash_wb.h" #include "hw_conf.h" #include "main.h" #include "shci.h" @@ -33,9 +36,9 @@ #include "stm32_lcd.h" #include "stm32_lpm.h" #include "stm32wb5mm_dk_lcd.h" +#include "stm_ext_flash.h" #include "stm_logging.h" -#include "AppTask.h" /* Private includes -----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ @@ -48,7 +51,7 @@ /* 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)) +#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH * 4U * DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4U)) /* USER CODE BEGIN PD */ /* USER CODE END PD */ @@ -70,17 +73,11 @@ 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 */ +/* Global variables ----------------------------------------------------------*/ +osMutexId_t MtxShciId; osSemaphoreId_t SemShciId; -osSemaphoreId_t SemShciUserEvtProcessId; -osThreadId_t OsShciUserEvtProcessId; +osThreadId_t ShciUserEvtProcessId; osThreadId_t OsPushButtonProcessId; const osThreadAttr_t ShciUserEvtProcess_attr = { .name = CFG_SHCI_USER_EVT_PROCESS_NAME, @@ -99,6 +96,13 @@ const osThreadAttr_t PushButtonProcess_attr = { .name = CFG_PUSH_BUTTON_EV .stack_size = CFG_PUSH_BUTTON_EVT_PROCESS_STACK_SIZE, .priority = CFG_PUSH_BUTTON_EVT_PROCESS_PRIORITY }; +/* 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 */ + /* USER CODE END GFP */ /* Private functions prototypes-----------------------------------------------*/ @@ -108,6 +112,9 @@ 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 ShciUserEvtProcess(void * argument); +static void PushButtonEvtProcess(void * argument); + static void appe_Tl_Init(void); /* USER CODE BEGIN PFP */ static void Led_Init(void); @@ -115,12 +122,8 @@ 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; @@ -128,7 +131,6 @@ void APP_ENTRY_PBSetReceiveCallback(PushButtonCallback aCallback) { PbCb = aCallback; } - /* Functions Definition ------------------------------------------------------*/ void APPE_Init(void) { @@ -142,8 +144,12 @@ void APPE_Init(void) /* initialize debugger module if supported and debug trace if activated */ Init_Debug(); - /* Display Dynamic concurrent mode (BLE and Thread) */ - displayConcurrentMode(); + // Init qspi and external flash + STM_EXT_FLASH_Init(); + // Init nvm + NM_Init(); + + APPD_Init(); /** * The Standby mode should not be entered before the initialization is over @@ -151,12 +157,7 @@ void APPE_Init(void) */ 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); - + OsPushButtonProcessId = osThreadNew(PushButtonEvtProcess, NULL, &PushButtonProcess_attr); Led_Init(); Button_Init(); @@ -164,6 +165,7 @@ void APPE_Init(void) /* Initialize all transport layers and start CPU2 which will send back a ready event to CPU1 */ appe_Tl_Init(); +#if (CFG_LCD_SUPPORTED == 1) BSP_LCD_Init(0, LCD_ORIENTATION_LANDSCAPE); /* Set LCD Foreground Layer */ UTIL_LCD_SetFuncDriver(&LCD_Driver); /* SetFunc before setting device */ @@ -177,9 +179,9 @@ void APPE_Init(void) 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); + UTIL_LCD_DisplayStringAt(0, 0, (uint8_t *) APP_NAME, CENTER_MODE); BSP_LCD_Refresh(0); - +#endif /** * From now, the application is waiting for the ready event ( VS_HCI_C2_Ready ) * received on the system channel before starting the Stack @@ -194,11 +196,6 @@ void APPE_Init(void) return; } -static void displayConcurrentMode() -{ - APP_DBG("Matter Over Thread Lighting-App starting..."); -} - /************************************************************* * * LOCAL FUNCTIONS @@ -292,6 +289,12 @@ static void appe_Tl_Init(void) /**< Reference table initialization */ TL_Init(); + MtxShciId = osMutexNew(NULL); + SemShciId = osSemaphoreNew(1, 0, NULL); /*< Create the semaphore and make it busy at initialization */ + + /** FreeRTOS system task creation */ + ShciUserEvtProcessId = osThreadNew(ShciUserEvtProcess, NULL, &ShciUserEvtProcess_attr); + /**< System channel initialization */ SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t *) &SystemCmdBuffer; SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot; @@ -311,7 +314,19 @@ static void appe_Tl_Init(void) static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) { - UNUSED(status); + switch (status) + { + case SHCI_TL_CmdBusy: + osMutexAcquire(MtxShciId, osWaitForever); + break; + + case SHCI_TL_CmdAvailable: + osMutexRelease(MtxShciId); + break; + + default: + break; + } return; } @@ -321,7 +336,7 @@ static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status) * - 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 ) + * (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) @@ -373,31 +388,64 @@ static void APPE_SysEvtError(SCHI_SystemErrCode_t ErrorCode) static void APPE_SysEvtReadyProcessing(void) { /* Traces channel initialization */ - TL_TRACES_Init(); + APPD_EnableCPU2(); + /* Configuration to CPU2 */ + SHCI_C2_CONFIG_Cmd_Param_t config_param = { 0 }; + uint32_t Ot_NVMAddr = 0; /* 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_BLE_Init_Dyn_1() : 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_BLE_Init_Dyn_2() : Start ADV + * APP_THREAD_Init_Dyn_2() : Thread Stack configuration (default channel, PID, etc...) to be able to start scanning + * or joining a Thread Network */ APP_DBG("1- Initialisation of BLE Stack..."); APP_BLE_Init_Dyn_1(); + /* Set the address that will be used by OT stack for NVM data management */ + if (NM_GetOtNVMAddr(&Ot_NVMAddr) == NVM_OK) + { + config_param.ThreadNvmRamAddress = Ot_NVMAddr; + (void) SHCI_C2_Config(&config_param); + } + APP_DBG("2- Initialisation of OpenThread Stack. FW info :"); - APP_THREAD_Init(); + APP_THREAD_Init_Dyn_1(); APP_BLE_Init_Dyn_2(); - + APP_THREAD_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; } +/************************************************************* + * + * FREERTOS WRAPPER FUNCTIONS + * + *************************************************************/ +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); + shci_user_evt_proc(); + /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ + + /* USER CODE END SHCI_USER_EVT_PROCESS_2 */ + } +} + +/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */ static void Led_Init(void) { #if (CFG_LED_SUPPORTED == 1U) @@ -413,12 +461,14 @@ static void Led_Init(void) static void Button_Init(void) { -#if (CFG_BUTTON_SUPPORTED == 1U) +#if ((CFG_BUTTON_SUPPORTED == 1U) || (CFG_HW_EXTPA_ENABLED == 1)) /** * Button Initialization */ BSP_PB_Init(BUTTON_USER1, BUTTON_MODE_EXTI); + BSP_PB_Init(BUTTON_USER2, BUTTON_MODE_EXTI); + #endif return; @@ -457,15 +507,24 @@ static void ExtPA_Init(void) static void PushButtonEvtProcess(void * argument) { UNUSED(argument); + uint32_t ButtonPressed = 0; + for (;;) { /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_1 */ - /* USER CODE END SHCI_USER_EVT_PROCESS_1 */ - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); + ButtonPressed = osThreadFlagsWait(3, osFlagsWaitAny, osWaitForever); Push_Button_st Message; - Message.Pushed_Button = BUTTON_USER1; - Message.State = 1; + if (1 == ButtonPressed) + { + Message.Pushed_Button = BUTTON_USER1; + Message.State = 1; + } + if (2 == ButtonPressed) + { + Message.Pushed_Button = BUTTON_USER2; + Message.State = 2; + } PbCb(&Message); // call matter callback to handle push button /* USER CODE BEGIN SHCI_USER_EVT_PROCESS_2 */ @@ -473,27 +532,10 @@ static void PushButtonEvtProcess(void * argument) } } -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); + osThreadFlagsSet(ShciUserEvtProcessId, 1); return; } @@ -506,8 +548,7 @@ void shci_cmd_resp_release(uint32_t flag) void shci_cmd_resp_wait(uint32_t timeout) { - UNUSED(timeout); - osSemaphoreAcquire(SemShciId, osWaitForever); + osSemaphoreAcquire(SemShciId, pdMS_TO_TICKS(timeout)); return; } @@ -569,7 +610,7 @@ void BSP_PB_Callback(Button_TypeDef Button) case BUTTON_USER2: APP_DBG("BUTTON 2 PUSHED !"); - /* Set "Switch Protocol" Task */ + osThreadFlagsSet(OsPushButtonProcessId, 2); break; default: @@ -578,6 +619,7 @@ void BSP_PB_Callback(Button_TypeDef Button) 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 index db25dccdf97cf0..3adaf861b574a3 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/entropy_hardware_poll.c @@ -1,4 +1,3 @@ - /* USER CODE BEGIN Header */ /** ****************************************************************************** diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c deleted file mode 100644 index fcf4534a327003..00000000000000 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_driver.c +++ /dev/null @@ -1,322 +0,0 @@ -/** - ****************************************************************************** - * @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 index 4c24d6f71c9103..6fb60c16f87609 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/flash_wb.c @@ -19,29 +19,36 @@ /* Includes ------------------------------------------------------------------*/ #include "flash_wb.h" -#include "flash_driver.h" +#include "stm_ext_flash.h" + +#if (OTA_SUPPORT == 1) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#elif defined(__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __CC_ARM || __ARMCC_VERSION */ +#endif #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 +#if (OTA_SUPPORT == 1) +#define NVM_MATTER_ADDR_INIT_SECURE BACKUP_END + 1 // start after back up slot +#else +#define NVM_MATTER_ADDR_INIT_SECURE EXTERNAL_FLASH_ADDRESS +#endif +// #define NVM_MATTER_ADDR_INIT_SECURE EXTERNAL_FLASH_ADDRESS + OTA_MAX_SIZE // start after back up slot +#define MATTER_KEY_NAME_MAX_LENGTH (16 * 2) // ADD Max key name string size is 32 "keyType...;KeyName..." #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 SECTOR_SIZE_SECURE 4096 * 5 #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 { @@ -63,7 +70,6 @@ const NVM_Sector_Struct sector_no_secure = { .id_sector = SECTOR_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 -----------------------------------------------*/ @@ -72,28 +78,17 @@ static uint8_t flash_update(const NVM_Sector_Struct select_sector, uint8_t * Key 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 uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName, size_t nvm_size); 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 NM_Init(void) { NVM_StatusTypeDef err = NVM_OK; - if (CheckSanity != 0) - { - err = NVM_FLASH_CORRUPTION; - } + + memset(ram_nvm, DEFAULT_VALUE, sizeof(ram_nvm)); + err = STM_EXT_FLASH_ReadChunk(NVM_MATTER_ADDR_INIT_SECURE, ram_nvm, sizeof(ram_nvm)); return err; } @@ -101,24 +96,15 @@ 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) + if (STM_EXT_FLASH_Delete_Image(NVM_MATTER_ADDR_INIT_SECURE, sizeof(ram_nvm)) == STM_EXT_FLASH_OK) { - err = FD_WriteData(NVM_MATTER_ADDR_INIT_SECURE, (uint64_t *) ram_nvm, (uint32_t) (NVM_SIZE_FLASH / sizeof(uint64_t))); - if (err != 0) + if (STM_EXT_FLASH_WriteChunk(NVM_MATTER_ADDR_INIT_SECURE, ram_nvm, sizeof(ram_nvm)) == STM_EXT_FLASH_OK) { - err = NVM_WRITE_FAILED; + err = NVM_OK; } else { - if (memcmp(ram_nvm, (void *) NVM_MATTER_ADDR_INIT_SECURE, (size_t) NVM_SIZE_FLASH)) - { - err = NVM_WRITE_FAILED; - } - else - { - err = NVM_OK; - } + err = NVM_WRITE_FAILED; } } return err; @@ -127,6 +113,10 @@ NVM_StatusTypeDef NM_Dump(void) NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t KeySize, size_t * read_by_size, NVM_Sector sector) { + if ((KeyValue == NULL) || (read_by_size == NULL)) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; switch (sector) { @@ -142,7 +132,7 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t return NVM_WRITE_FAILED; } - uint8_t * key_search = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName); + uint8_t * key_search = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName, select_nvm.sector_size); if (key_search != NULL) { // copy Keyname's value in KeyValue and copy the size of KeyValue in read_by_size @@ -151,9 +141,23 @@ NVM_StatusTypeDef NM_GetKeyValue(void * KeyValue, const char * KeyName, uint32_t return NVM_KEY_NOT_FOUND; } +NVM_StatusTypeDef NM_GetOtNVMAddr(uint32_t * NVMAddr) +{ + if (NVMAddr == NULL) + { + return NVM_PARAM_ERROR; + } + *NVMAddr = (uint32_t) ram_nvm + SECTOR_SIZE_SECURE; + return NVM_OK; +} + NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySize, NVM_Sector sector) { + if ((KeyValue == NULL) || (KeyName == NULL)) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; void * Ptkey = NULL; @@ -176,7 +180,7 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi 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); + Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) KeyName, select_nvm.sector_size); if (Ptkey == NULL) { @@ -192,9 +196,13 @@ NVM_StatusTypeDef NM_SetKeyValue(char * KeyValue, char * KeyName, uint32_t KeySi return NVM_WRITE_FAILED; } -uint8_t NM_DeleteKey(const char * Keyname, NVM_Sector sector) +NVM_StatusTypeDef NM_DeleteKey(const char * Keyname, NVM_Sector sector) { + if (Keyname == NULL) + { + return NVM_PARAM_ERROR; + } NVM_Sector_Struct select_nvm = { 0 }; switch (sector) { @@ -209,7 +217,7 @@ uint8_t NM_DeleteKey(const char * Keyname, NVM_Sector sector) default: return NVM_WRITE_FAILED; } - uint8_t * Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) Keyname); + uint8_t * Ptkey = SearchKey(select_nvm.ram_ptr, (uint8_t *) Keyname, select_nvm.sector_size); if (Ptkey != NULL) { return delete_key(select_nvm, Ptkey); @@ -221,7 +229,7 @@ void NM_ResetFactory(void) { while (1) { - FD_EraseSectors((NVM_MATTER_ADDR_INIT_SECURE - FLASH_START) / (NVM_SIZE_FLASH / NB_SECTOR), NB_SECTOR); + STM_EXT_FLASH_Delete_Image(NVM_MATTER_ADDR_INIT_SECURE, sizeof(ram_nvm)); NVIC_SystemReset(); } } @@ -232,24 +240,29 @@ void NM_ResetFactory(void) * *************************************************************/ -static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName) +static uint8_t * SearchKey(uint8_t * PtPage, uint8_t * KeyName, size_t nvm_size) { uint8_t * i = PtPage; size_t read_by_size = 0; - while ((i >= PtPage) || (i < (PtPage + NVM_SIZE_FLASH))) + while ((i >= PtPage) || (i < (PtPage + nvm_size))) { if (*i != DEFAULT_VALUE) { - if (strcmp((char *) KeyName, (char *) i) == 0) + if (strcmp(KeyName, (uint8_t *) i) == 0) { return i; } read_by_size = *(size_t *) ((uint8_t *) i + MATTER_KEY_NAME_MAX_LENGTH); + // ensure that the size of the data being read does not exceed the remaining size of the buffer + if (read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH > nvm_size - (i - PtPage)) + { + return NULL; + } i += read_by_size + sizeof(size_t) + MATTER_KEY_NAME_MAX_LENGTH; // Flash is corrupted - if ((i < PtPage) || (i > (PtPage + NVM_SIZE_FLASH))) + if ((i < PtPage) || (i > (PtPage + nvm_size))) { NM_ResetFactory(); } @@ -327,14 +340,14 @@ static NVM_StatusTypeDef delete_key(const NVM_Sector_Struct select_sector, uint8 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))) + while ((*PtKeyNext != 0xFF) && (PtKeyNext < (select_sector.ram_ptr + select_sector.sector_size))) { 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)); + memset(PtKeyCpy, DEFAULT_VALUE, (select_sector.ram_ptr + select_sector.sector_size - PtKeyCpy)); return NVM_OK; } return NVM_DELETE_FAILED; diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp index a48e8b88dc6101..06481af913c99c 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/main.cpp @@ -45,9 +45,7 @@ #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 ------------------------------------------------------------*/ @@ -96,6 +94,7 @@ int main(void) * 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); /** @@ -126,9 +125,7 @@ int main(void) MX_GPIO_Init(); /* IPCC initialisation */ MX_IPCC_Init(); - NM_Init(); freertos_mbedtls_init(); - APPE_Init(); GetAppTask().InitMatter(); osKernelStart(); diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp b/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp new file mode 100644 index 00000000000000..7af8c69807fbf7 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/ota.cpp @@ -0,0 +1,113 @@ +/* + * + * 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. + */ + +/***************************************************************************** + * Includes Definitions + *****************************************************************************/ + +#if (OTA_SUPPORT == 1) +#include "ota.h" +#include + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::DeviceLayer; + +/***************************************************************************** + * Static Data Definitions + *****************************************************************************/ + +DefaultOTARequestor gRequestorCore; +DefaultOTARequestorStorage gRequestorStorage; +DefaultOTARequestorDriver gRequestorUser; +BDXDownloader gDownloader; +OTAImageProcessorImpl gImageProcessor; +FactoryDataProvider gFactoryDataProvider; +chip::ota::DefaultOTARequestorUserConsent gUserConsentProvider; +static chip::ota::UserConsentState gUserConsentState = chip::ota::UserConsentState::kGranted; + +/***************************************************************************** + * Application Function Definitions + *****************************************************************************/ + +bool OtaHeaderValidation(Ota_ImageHeader_t imageHeader) +{ + + uint16_t vendorId = 0; + uint16_t productId = 0; + + if (gFactoryDataProvider.GetVendorId(vendorId) != CHIP_NO_ERROR) + { + return false; + } + if (gFactoryDataProvider.GetProductId(productId) != CHIP_NO_ERROR) + { + return false; + } + + // Check that the image matches vendor and product ID and that the version is higher than what we currently have + if (imageHeader.vendorId != vendorId || imageHeader.productId != productId || + imageHeader.softwareVersion <= CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION) + { + return false; + } + + return true; +} + +void InitializeOTARequestor(void) +{ + ChipLogProgress(DeviceLayer, "Initialising OTA Requestor"); + // Initialize and interconnect the Requestor and Image Processor objects + SetRequestorInstance(&gRequestorCore); + + gRequestorStorage.Init(chip::Server::GetInstance().GetPersistentStorage()); + gRequestorCore.Init(chip::Server::GetInstance(), gRequestorStorage, gRequestorUser, gDownloader); + gImageProcessor.SetOTADownloader(&gDownloader); + gDownloader.SetImageProcessorDelegate(&gImageProcessor); + gRequestorUser.Init(&gRequestorCore, &gImageProcessor); + gUserConsentProvider.SetUserConsentState(gUserConsentState); + // Test to trigger ota. this function can be trigger by a Push Button + TriggerOTAQuery(); +} + +void TriggerOTAQuery(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + OTARequestorInterface * requestor = GetRequestorInstance(); + + if (requestor != nullptr) + { + err = requestor->TriggerImmediateQuery(kUndefinedFabricIndex); + + if (CHIP_NO_ERROR != err) + { + ChipLogError(DeviceLayer, "Failed trigger OTA query: %" CHIP_ERROR_FORMAT, err.Format()); + } + } + else + { + ChipLogProgress(DeviceLayer, "No OTA requestor instance, can't query OTA"); + } +} +#endif diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c index ee2d71467514b5..f355df04fb803d 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/otp.c @@ -33,7 +33,7 @@ uint8_t * OTP_Read(uint8_t id) { uint8_t * p_id; - p_id = (uint8_t *) (CFG_OTP_END_ADDRESS - 7); + p_id = (uint8_t *) (CFG_OTP_END_ADRESS - 7); while (((*(p_id + 7)) != id) && (p_id != (uint8_t *) CFG_OTP_BASE_ADDRESS)) { diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c new file mode 100644 index 00000000000000..3ad44445b11908 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32_factorydata.c @@ -0,0 +1,132 @@ +/** + ****************************************************************************** + * @file stm32_factorydata.c + * @author MCD Application Team + * @brief Middleware between matter factory data and external flash , + * to manage factory data 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 "stm32_factorydata.h" +#include "stm_ext_flash.h" + +/* Private defines -----------------------------------------------------------*/ +#define HEADER_SIZE 8 +#define FACTORY_DATA_START_ADDR 0x901C0000U +#define FACTORY_DATA_END_ADDR 0x901CFFFFU +#define DATA_MAX_LENGTH 603 + +/* Private variables ---------------------------------------------------------*/ +typedef struct +{ + uint32_t tag_id; + uint32_t data_length; +} header; + +/* Private functions prototypes-----------------------------------------------*/ +static FACTORYDATA_StatusTypeDef Get_TagLocation(FACTORYDATA_TagId tag, uint32_t * out_Location, uint32_t * out_length); + +/************************************************************* + * + * PUBLIC FUNCTIONS + * + *************************************************************/ + +FACTORYDATA_StatusTypeDef FACTORYDATA_GetValue(FACTORYDATA_TagId tag, uint8_t * data, uint32_t size, uint32_t * out_datalength) +{ + + FACTORYDATA_StatusTypeDef err = DATAFACTORY_DATA_NOT_FOUND; + uint32_t Location; + uint32_t datalength; + + if ((data == NULL) || (out_datalength == NULL)) + { + return DATAFACTORY_PARAM_ERROR; + } + + // search for tag location + err = Get_TagLocation(tag, &Location, &datalength); + if (err != DATAFACTORY_OK) + { + return err; + } + else + { + if (datalength > size) + { + return DATAFACTORY_BUFFER_TOO_SMALL; + } + // Read data + err = STM_EXT_FLASH_ReadChunk(Location, data, datalength); + if (err == DATAFACTORY_OK) + { + *out_datalength = datalength; + } + } + + return err; +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ + +static FACTORYDATA_StatusTypeDef Get_TagLocation(FACTORYDATA_TagId tag, uint32_t * out_Location, uint32_t * out_length) +{ + FACTORYDATA_StatusTypeDef err = DATAFACTORY_OK; + header Header_tag; + uint8_t Header_data[HEADER_SIZE]; + uint32_t location_tmp = FACTORY_DATA_START_ADDR; + + // read all header until find the right tag + do + { + memset(Header_data, 0, HEADER_SIZE); + err = STM_EXT_FLASH_ReadChunk(location_tmp, Header_data, HEADER_SIZE); + if (err != DATAFACTORY_OK) + { + return DATAFACTORY_PARAM_ERROR; + } + + // retrieve header with tag_id and data_length + Header_tag.tag_id = Header_data[0] + ((Header_data[1]) << 8) + ((Header_data[2]) << 16) + ((Header_data[3]) << 24); + Header_tag.data_length = Header_data[4] + ((Header_data[5]) << 8) + ((Header_data[6]) << 16) + ((Header_data[7]) << 24); + + // check if the length is valid + if ((Header_tag.data_length > 0) && (Header_tag.data_length < DATA_MAX_LENGTH)) + { + if (Header_tag.tag_id == tag) + { + *out_Location = location_tmp + HEADER_SIZE; + *out_length = Header_tag.data_length; + break; + } + // move to the next data + location_tmp += Header_tag.data_length + HEADER_SIZE; + } + else + { + return DATAFACTORY_PARAM_ERROR; + } + } while (location_tmp < FACTORY_DATA_END_ADDR); + + if (location_tmp > FACTORY_DATA_END_ADDR) + { + err = DATAFACTORY_DATA_NOT_FOUND; + } + + return err; +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c new file mode 100644 index 00000000000000..6925269ea304a1 --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wb5mm_dk_qspi.c @@ -0,0 +1,922 @@ +/** + ****************************************************************************** + * @file stm32wb5mm_dk_qspi.c + * @author MCD Application Team + * @brief This file includes a standard driver for the S25FL128S QSPI + * memory mounted on STM32WB5MM-DK board. + ****************************************************************************** + * @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. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + (#) This driver is used to drive the S25FL128S QSPI external + memory mounted on STM32WB5MM-DK board. + + (#) This driver needs a specific component driver (S25FL128S) to be included with. + + (#) Initialization steps: + (++) Initialize the QPSI external memory using the BSP_QSPI_Init() function. This + function includes the MSP layer hardware resources initialization and the + QSPI interface with the external memory. + + (#) QSPI memory operations + (++) QSPI memory can be accessed with read/write operations once it is + initialized. + Read/write operation can be performed with AHB access using the functions + BSP_QSPI_Read()/BSP_QSPI_Write(). + (++) The function BSP_QSPI_GetInfo() returns the configuration of the QSPI memory. + (see the QSPI memory data sheet) + (++) Perform erase block operation using the function BSP_QSPI_Erase_Block() and by + specifying the block address. You can perform an erase operation of the whole + chip by calling the function BSP_QSPI_Erase_Chip(). + (++) The function BSP_QSPI_GetStatus() returns the current status of the QSPI memory. + (see the QSPI memory data sheet) + (++) The function BSP_QSPI_EnableMemoryMappedMode enables the QSPI memory mapped mode. + (++) The function BSP_QSPI_DisableMemoryMappedMode disables the QSPI memory mapped mode. + (++) The function BSP_QSPI_ReadID() returns 3 bytes memory IDs: Manufacturer ID, + Memory type, Memory density. + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32wb5mm_dk_qspi.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32WB5MM_DK + * @{ + */ + +/** @defgroup STM32WB5MM_DK_QSPI STM32WB5MM_DK QSPI + * @{ + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Variables Exported Variables + * @{ + */ +QSPI_HandleTypeDef hqspi; +BSP_QSPI_Ctx_t QSPI_Ctx[QSPI_INSTANCES_NUMBER]; +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup STM32WB5MM_DK_QSPI_Private_Functions Private Functions + * @{ + */ +static void QSPI_MspInit(QSPI_HandleTypeDef * hQspi); +static void QSPI_MspDeInit(QSPI_HandleTypeDef * hSspi); +static int32_t QSPI_ResetMemory(uint32_t Instance); +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance); + +/** + * @} + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Exported_Functions Exported Functions + * @{ + */ + +/** + * @brief Initializes the QSPI interface. + * @param Instance QSPI Instance + * @param Init QSPI Init structure + * @retval BSP status + */ +int32_t BSP_QSPI_Init(uint32_t Instance, BSP_QSPI_Init_t * Init) +{ + int32_t ret = BSP_ERROR_NONE; + BSP_QSPI_Info_t pInfo; + MX_QSPI_Init_t qspi_init; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check if instance is already initialized */ + if (QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_NONE) + { +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) + /* Register the QSPI MSP Callbacks */ + if (QSPI_Ctx[Instance].IsMspCallbacksValid == 0UL) + { + if (BSP_QSPI_RegisterDefaultMspCallbacks(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } +#else + /* Msp QSPI initialization */ + QSPI_MspInit(&hqspi); +#endif /* USE_HAL_QSPI_REGISTER_CALLBACKS == 1 */ + + if (ret == BSP_ERROR_NONE) + { + /* STM32 QSPI interface initialization */ + (void) S25FL128S_GetFlashInfo(&pInfo); + qspi_init.ClockPrescaler = 4; + qspi_init.DualFlashMode = S25FL128S_DUALFLASH_DISABLE; + qspi_init.FlashSize = (uint32_t) POSITION_VAL((uint32_t) pInfo.FlashSize) - 1U; + qspi_init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + + if (MX_QSPI_Init(&hqspi, &qspi_init) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } /* QSPI memory reset */ + else if (QSPI_ResetMemory(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Force Flash enter 4 Byte address mode */ + else if (S25FL128S_AutoPollingMemReady(&hqspi, Init->InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else if (S25FL128S_Enter4BytesAddressMode(&hqspi, Init->InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Configuration of the dummy cycles on QSPI memory side */ + else if (QSPI_DummyCyclesCfg(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + QSPI_Ctx[Instance].InterfaceMode = Init->InterfaceMode; + } + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief De-Initializes the QSPI interface. + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_DeInit(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].IsInitialized == QSPI_ACCESS_MMP) + { + if (BSP_QSPI_DisableMemoryMappedMode(Instance) != BSP_ERROR_NONE) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + if (ret == BSP_ERROR_NONE) + { + /* Set default QSPI_Ctx values */ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_NONE; + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; + QSPI_Ctx[Instance].DualFlashMode = 0; + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) + QSPI_MspDeInit(&hqspi); +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 0) */ + + /* Call the DeInit function to reset the driver */ + if (HAL_QSPI_DeInit(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Initializes the QSPI interface. + * @param hQspi QSPI handle + * @param Config QSPI configuration structure + * @retval BSP status + */ +__weak HAL_StatusTypeDef MX_QSPI_Init(QSPI_HandleTypeDef * hQspi, MX_QSPI_Init_t * Config) +{ + /* QSPI initialization */ + /* QSPI freq = SYSCLK /(1 + ClockPrescaler) Mhz */ + hQspi->Instance = QUADSPI; + hQspi->Init.ClockPrescaler = Config->ClockPrescaler; + hQspi->Init.FifoThreshold = 1; + hQspi->Init.SampleShifting = Config->SampleShifting; + hQspi->Init.FlashSize = Config->FlashSize; + hQspi->Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_8_CYCLE; + hQspi->Init.ClockMode = QSPI_CLOCK_MODE_0; + + return HAL_QSPI_Init(hQspi); +} + +#if (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) +/** + * @brief Default BSP QSPI Msp Callbacks + * @param Instance QSPI Instance + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterDefaultMspCallbacks(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, QSPI_MspInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, QSPI_MspDeInit) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief BSP QSPI Msp Callback registering + * @param Instance QSPI Instance + * @param CallBacks pointer to MspInit/MspDeInit callbacks functions + * @retval BSP status + */ +int32_t BSP_QSPI_RegisterMspCallbacks(uint32_t Instance, BSP_QSPI_Cb_t * CallBacks) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Register MspInit/MspDeInit Callbacks */ + if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPINIT_CB_ID, CallBacks->pMspInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else if (HAL_QSPI_RegisterCallback(&hqspi, HAL_QSPI_MSPDEINIT_CB_ID, CallBacks->pMspDeInitCb) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsMspCallbacksValid = 1U; + } + } + + /* Return BSP status */ + return ret; +} +#endif /* (USE_HAL_QSPI_REGISTER_CALLBACKS == 1) */ + +/** + * @brief Reads an amount of data from the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be read + * @param ReadAddr Read start address + * @param Size Size of data to read + * @retval BSP status + */ +int32_t BSP_QSPI_Read(uint32_t Instance, uint8_t * pData, uint32_t ReadAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if (S25FL128S_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, pData, ReadAddr, Size) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Writes an amount of data to the QSPI memory. + * @param Instance QSPI instance + * @param pData Pointer to data to be written + * @param WriteAddr Write start address + * @param Size Size of data to write + * @retval BSP status + */ +int32_t BSP_QSPI_Write(uint32_t Instance, uint8_t * pData, uint32_t WriteAddr, uint32_t Size) +{ + int32_t ret = BSP_ERROR_NONE; + uint32_t end_addr, current_size, current_addr; + uint8_t * write_data; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Calculation of the size between the write address and the end of the page */ + current_size = S25FL128S_PAGE_SIZE - (WriteAddr % S25FL128S_PAGE_SIZE); + + /* Check if the size of the data is less than the remaining place in the page */ + if (current_size > Size) + { + current_size = Size; + } + + /* Initialize the address variables */ + current_addr = WriteAddr; + end_addr = WriteAddr + Size; + write_data = pData; + + /* Perform the write page by page */ + do + { + /* Check if Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Issue page program command */ + else if (S25FL128S_PageProgram(&hqspi, QSPI_Ctx[Instance].InterfaceMode, write_data, current_addr, current_size) != + S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Configure automatic polling mode to wait for end of program */ + else if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Update the address and size variables for next page programming */ + current_addr += current_size; + write_data += current_size; + current_size = ((current_addr + S25FL128S_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : S25FL128S_PAGE_SIZE; + } + } while ((current_addr < end_addr) && (ret == BSP_ERROR_NONE)); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the specified block of the QSPI memory. + * S25FL128S support 4K, 64K size block erase commands. + * @param Instance QSPI instance + * @param BlockAddress Block address to erase + * @param BlockSize Erase Block size + * @retval BSP status + */ +int32_t BSP_QSPI_EraseBlock(uint32_t Instance, uint32_t BlockAddress, BSP_QSPI_Erase_t BlockSize) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Block Erase command */ + if (S25FL128S_BlockErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode, BlockAddress, BlockSize) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Erases the entire QSPI memory. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EraseChip(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + /* Check Flash busy ? */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Enable write operations */ + else if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Issue Chip erase command */ + if (S25FL128S_ChipErase(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Reads current status of the QSPI memory. + * If WIP != 0 then return busy. + * @param Instance QSPI instance + * @retval QSPI memory status: whether busy or not + */ +int32_t BSP_QSPI_GetStatus(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + uint8_t reg; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (S25FL128S_ReadStatusRegister(&hqspi, QSPI_Ctx[Instance].InterfaceMode, ®) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + /* Check the value of the register */ + if ((reg & S25FL128S_SR1_WIP) != 0U) + { + ret = BSP_ERROR_BUSY; + } + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Return the configuration of the QSPI memory. + * @param Instance QSPI instance + * @param pInfo pointer on the configuration structure + * @retval BSP status + */ +int32_t BSP_QSPI_GetInfo(uint32_t Instance, BSP_QSPI_Info_t * pInfo) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + (void) S25FL128S_GetFlashInfo(pInfo); + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Configure the QSPI in memory-mapped mode + * Only 1 Instance can running MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_EnableMemoryMappedMode(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].TransferRate == BSP_QSPI_STR_TRANSFER) + { + if (S25FL128S_EnableMemoryMappedModeSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + else + { + /* Update QSPI context if all operations are well done */ + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_MMP; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief Exit form memory-mapped mode + * Only 1 Instance can run MMP mode. And it will lock system at this mode. + * @param Instance QSPI instance + * @retval BSP status + */ +int32_t BSP_QSPI_DisableMemoryMappedMode(uint32_t Instance) +{ + uint8_t Dummy; + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (QSPI_Ctx[Instance].IsInitialized != QSPI_ACCESS_MMP) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } /* Abort MMP back to indirect mode */ + else if (HAL_QSPI_Abort(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + else + { + /* Force QSPI interface Sampling Shift to half cycle */ + hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE; + + if (HAL_QSPI_Init(&hqspi) != HAL_OK) + { + ret = BSP_ERROR_PERIPH_FAILURE; + } + /* Dummy read for exit from Performance Enhance mode */ + else if (S25FL128S_ReadSTR(&hqspi, QSPI_Ctx[Instance].InterfaceMode, &Dummy, 0, 1) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else /* Update QSPI context if all operations are well done */ + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; + } + } + } + /* Return BSP status */ + return ret; +} + +/** + * @brief Get flash ID, 3 Bytes + * Manufacturer ID, Memory type, Memory density + * @param Instance QSPI instance + * @param Id QSPI Identifier + * @retval BSP status + */ +int32_t BSP_QSPI_ReadID(uint32_t Instance, uint8_t * Id) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Check if the instance is supported */ + if (Instance >= QSPI_INSTANCES_NUMBER) + { + ret = BSP_ERROR_WRONG_PARAM; + } + else + { + if (S25FL128S_ReadID(&hqspi, QSPI_Ctx[Instance].InterfaceMode, Id) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + } + + /* Return BSP status */ + return ret; +} + +/** + * @} + */ + +/** @defgroup STM32WB5MM_DK_QSPI_Private_Functions Private Functions + * @{ + */ + +/** + * @brief QSPI MSP Initialization + * @param hQspi : QSPI handle + * This function configures the hardware resources used in this example: + * - Peripheral's clock enable + * - Peripheral's GPIO Configuration + * - NVIC configuration for QSPI interrupt + * @retval None + */ +static void QSPI_MspInit(QSPI_HandleTypeDef * hQspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Enable peripherals and GPIO Clocks #################################*/ + /* Enable the QuadSPI memory interface clock */ + QSPI_CLK_ENABLE(); + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + /* Enable GPIO clocks */ + QSPI_CS_GPIO_CLK_ENABLE(); + QSPI_CLK_GPIO_CLK_ENABLE(); + QSPI_D0_GPIO_CLK_ENABLE(); + QSPI_D1_GPIO_CLK_ENABLE(); + QSPI_D2_GPIO_CLK_ENABLE(); + QSPI_D3_GPIO_CLK_ENABLE(); + + /*##-2- Configure peripheral GPIO ##########################################*/ + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure); + + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CLK_PIN; + gpio_init_structure.Pull = GPIO_PULLUP; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D0_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D2_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D3_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure); + + /*##-3- Configure the NVIC for QSPI #########################################*/ + /* NVIC configuration for QSPI interrupt */ + HAL_NVIC_SetPriority(QUADSPI_IRQn, 0x0F, 0); + HAL_NVIC_EnableIRQ(QUADSPI_IRQn); +} + +/** + * @brief QSPI MSP De-Initialization + * @param hQspi QSPI handle + * This function frees the hardware resources used in this example: + * - Disable the Peripheral's clock + * - Revert GPIO and NVIC configuration to their default state + * @retval None + */ +static void QSPI_MspDeInit(QSPI_HandleTypeDef * hQspi) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hQspi); + + /*##-2- Disable peripherals and GPIO Clocks ################################*/ + /* De-Configure QSPI pins */ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN); + HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); + HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN); + HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN); + HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN); + HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN); + + /*##-3- Reset peripherals ##################################################*/ + /* Reset the QuadSPI memory interface */ + QSPI_FORCE_RESET(); + QSPI_RELEASE_RESET(); + + /* Disable the QuadSPI memory interface clock */ + QSPI_CLK_DISABLE(); +} + +/** + * @brief This function reset the QSPI Flash memory. + * For SPI reset to avoid system come from unknown status. + * Flash accept 1-1-1, 1-1-2, 1-2-2 commands after reset. + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_ResetMemory(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + + /* Wait Flash ready */ + if (S25FL128S_AutoPollingMemReady(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Send RESET ENABLE command in SPI mode (1-1-1) */ + else if (S25FL128S_ResetEnable(&hqspi, BSP_QSPI_SPI_MODE) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } /* Send RESET memory command in SPI mode (1-1-1) */ + else if (S25FL128S_ResetMemory(&hqspi, BSP_QSPI_SPI_MODE) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + else + { + QSPI_Ctx[Instance].IsInitialized = QSPI_ACCESS_INDIRECT; /* After reset S/W setting to indirect access */ + QSPI_Ctx[Instance].InterfaceMode = BSP_QSPI_SPI_MODE; /* After reset H/W back to SPI mode by default */ + QSPI_Ctx[Instance].TransferRate = BSP_QSPI_STR_TRANSFER; /* After reset S/W setting to STR mode */ + } + + /* Return BSP status */ + return ret; +} + +/** + * @brief This function configures the dummy cycles on memory side. + * Dummy cycle bit locate in Configuration Register[7:6] + * @param Instance QSPI instance + * @retval BSP status + */ +static int32_t QSPI_DummyCyclesCfg(uint32_t Instance) +{ + int32_t ret = BSP_ERROR_NONE; + QSPI_CommandTypeDef s_command; + uint8_t reg[2]; + + /* Initialize the read configuration register command */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.Instruction = S25FL128S_READ_CONFIGURATION_REG1_CMD; + s_command.AddressMode = QSPI_ADDRESS_NONE; + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = QSPI_DATA_1_LINE; + s_command.DummyCycles = 0; + s_command.NbData = 1; + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&hqspi, ®[1], HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Initialize the read status register1 command */ + s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE; + s_command.Instruction = S25FL128S_READ_STATUS_REG1_CMD; + s_command.AddressMode = QSPI_ADDRESS_NONE; + s_command.AlternateByteMode = QSPI_ALTERNATE_BYTES_NONE; + s_command.DataMode = QSPI_DATA_1_LINE; + s_command.DummyCycles = 0; + s_command.NbData = 1; + s_command.DdrMode = QSPI_DDR_MODE_DISABLE; + s_command.SIOOMode = QSPI_SIOO_INST_EVERY_CMD; + + /* Configure the command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Reception of the data */ + if (HAL_QSPI_Receive(&hqspi, ®[0], HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Enable write operations */ + if (S25FL128S_WriteEnable(&hqspi, QSPI_Ctx[Instance].InterfaceMode) != S25FL128S_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Update configuration register (with new Latency Code) */ + s_command.Instruction = S25FL128S_WRITE_STATUS_CMD_REG_CMD; + s_command.NbData = 2; + MODIFY_REG(reg[1], S25FL128S_CR1_LC_MASK, S25FL128S_CR1_LC1); + + /* Configure the write volatile configuration register command */ + if (HAL_QSPI_Command(&hqspi, &s_command, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Transmission of the data Status Register 1 */ + if (HAL_QSPI_Transmit(&hqspi, reg, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) + { + ret = BSP_ERROR_COMPONENT_FAILURE; + } + + /* Return BSP status */ + return ret; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ 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 index b5fa5b234e778f..1ff1746dcd5ef1 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_hal_msp.c @@ -29,16 +29,7 @@ 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 ------------------------------------------------------------*/ diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c index aa13c0fb6ada54..bf28e5b4c3dff8 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm32wbxx_it.c @@ -74,14 +74,6 @@ void MemManage_Handler(void) /* 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. @@ -90,25 +82,6 @@ void MemManage_Handler(void) */ 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(); @@ -142,7 +115,6 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) * @param None * @retval None */ - void EXTI15_10_IRQHandler(void) { BSP_PB_IRQHandler(BUTTON_USER1); diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c new file mode 100644 index 00000000000000..feb8e92041175e --- /dev/null +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_ext_flash.c @@ -0,0 +1,257 @@ +/** + ****************************************************************************** + * @file stm_ota.c + * @author MCD Application Team + * @brief Write new image in external flash + ****************************************************************************** + * @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 "stm_ext_flash.h" +#include "cmsis_os.h" +#include "stm32wb5mm_dk_qspi.h" + +/* Private defines -----------------------------------------------------------*/ +#define ERASE_BLOC_SIZE 0x10000U /*!< 64 Kbytes */ + +/* Private macros ------------------------------------------------------------*/ + +/* Private variables ---------------------------------------------------------*/ +osSemaphoreId_t SemExtFlashId; + +/* Global variables ----------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static STM_OTA_StatusTypeDef check_addr(uint32_t Address, uint32_t Length); +static void QSPI_Pin_LP(void); +static void QSPI_Pin_WakeUP(void); +/* Public functions ----------------------------------------------------------*/ + +STM_OTA_StatusTypeDef STM_EXT_FLASH_Init(void) +{ + BSP_QSPI_Init_t init; + + SemExtFlashId = osSemaphoreNew(1, 1, NULL); /*< Create the semaphore and make it available at initialization */ + + init.TransferRate = BSP_QSPI_STR_TRANSFER; + init.DualFlashMode = BSP_QSPI_DUALFLASH_DISABLE; + init.InterfaceMode = S25FL128S_QPI_MODE; + if (BSP_QSPI_Init(0, &init) != BSP_ERROR_NONE) + { + return STM_EXT_FLASH_INIT_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + return STM_EXT_FLASH_OK; + } +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_Delete_Image(uint32_t Address, uint32_t Length) +{ + uint32_t loop_flash; + + // check if the address is in the external flash and if the length is < flash size + if (check_addr(Address, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + + /* flash address to erase is the offset from begin of external flash */ + Address -= EXTERNAL_FLASH_ADDRESS; + + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + /* Loop on 64KBytes block */ + for (loop_flash = 0U; loop_flash < (((Length - 1U) / ERASE_BLOC_SIZE) + 1U); loop_flash++) + { + if (BSP_QSPI_EraseBlock(0, Address, BSP_QSPI_ERASE_64K) != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_DELETE_FAILED; + } + + /* next 64KBytes block */ + Address += ERASE_BLOC_SIZE; + } +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_WriteChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length) +{ + int32_t error = 0; + if (pSrcBuffer == NULL) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + // check if the address is in the external flash and if the length is < flash size + if (check_addr(DestAddress, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + error = BSP_QSPI_Write(0, pSrcBuffer, DestAddress - EXTERNAL_FLASH_ADDRESS, Length); + if (error != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_WRITE_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; + } +} + +STM_OTA_StatusTypeDef STM_EXT_FLASH_ReadChunk(uint32_t DestAddress, uint8_t * pSrcBuffer, uint32_t Length) +{ + int32_t error = 0; + if (pSrcBuffer == NULL) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + // check if the address is in the external flash and if the length is < flash size + if (check_addr(DestAddress, Length) != STM_EXT_FLASH_OK) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + + /* Do nothing if Length equal to 0 */ + if (Length == 0U) + { + return STM_EXT_FLASH_OK; + } + osSemaphoreAcquire(SemExtFlashId, osWaitForever); +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_WakeUP(); +#endif + error = BSP_QSPI_Read(0, pSrcBuffer, DestAddress - EXTERNAL_FLASH_ADDRESS, Length); + if (error != BSP_ERROR_NONE) + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_READ_FAILED; + } + else + { +#if CFG_FULL_LOW_POWER == 1 + QSPI_Pin_LP(); +#endif + osSemaphoreRelease(SemExtFlashId); + return STM_EXT_FLASH_OK; + } +} + +/************************************************************* + * + * LOCAL FUNCTIONS + * + *************************************************************/ +static STM_OTA_StatusTypeDef check_addr(uint32_t Address, uint32_t Length) +{ + // check if the address is in the external flash and if the length is < flash size + if ((Address < EXTERNAL_FLASH_ADDRESS) || (S25FL128S_FLASH_SIZE < Length) || + (Address + Length > EXTERNAL_FLASH_ADDRESS + S25FL128S_FLASH_SIZE)) + { + return STM_EXT_FLASH_INVALID_PARAM; + } + else + { + return STM_EXT_FLASH_OK; + } +} + +static void QSPI_Pin_WakeUP(void) +{ + + GPIO_InitTypeDef gpio_init_structure; + + /*##-1- Configure peripheral GPIO ##########################################*/ + /* QSPI CS GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CS_PIN; + gpio_init_structure.Mode = GPIO_MODE_AF_PP; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CS_GPIO_PORT, &gpio_init_structure); + + /* QSPI CLK GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_CLK_PIN; + gpio_init_structure.Pull = GPIO_NOPULL; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_CLK_GPIO_PORT, &gpio_init_structure); + + /* QSPI D0 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D0_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D0_GPIO_PORT, &gpio_init_structure); + + /* QSPI D1 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D1_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D1_GPIO_PORT, &gpio_init_structure); + + /* QSPI D2 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D2_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D2_GPIO_PORT, &gpio_init_structure); + + /* QSPI D3 GPIO pin configuration */ + gpio_init_structure.Pin = QSPI_D3_PIN; + gpio_init_structure.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(QSPI_D3_GPIO_PORT, &gpio_init_structure); +} + +static void QSPI_Pin_LP(void) +{ + /*##-1- Disable peripherals ################################*/ + /* De-Configure QSPI pins */ + HAL_GPIO_DeInit(QSPI_CS_GPIO_PORT, QSPI_CS_PIN); + HAL_GPIO_DeInit(QSPI_CLK_GPIO_PORT, QSPI_CLK_PIN); + HAL_GPIO_DeInit(QSPI_D0_GPIO_PORT, QSPI_D0_PIN); + HAL_GPIO_DeInit(QSPI_D1_GPIO_PORT, QSPI_D1_PIN); + HAL_GPIO_DeInit(QSPI_D2_GPIO_PORT, QSPI_D2_PIN); + HAL_GPIO_DeInit(QSPI_D3_GPIO_PORT, QSPI_D3_PIN); +} diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c index 910a401c70eef5..bfe1ed754c2c82 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/stm_logging.c @@ -1,4 +1,3 @@ - /** ****************************************************************************** * @file stm_logging.c diff --git a/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c index 7231d53efafcb2..319074d8d26eac 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/sysmem.c @@ -35,7 +35,7 @@ register char * stack_ptr asm("sp"); _sbrk Increase program data space. Malloc and related functions depend on this **/ -caddr_t _sbrk(int incr) +void * _sbrk(int incr) { extern char end asm("end"); static char * heap_end; @@ -48,10 +48,10 @@ caddr_t _sbrk(int incr) if (heap_end + incr > stack_ptr) { errno = ENOMEM; - return (caddr_t) -1; + return (void *) -1; } heap_end += incr; - return (caddr_t) prev_heap_end; + return (void *) 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 index 533cc4f0aa9671..86bc4defd7edc4 100644 --- a/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c +++ b/examples/platform/stm32/common/STM32WB5MM-DK/Src/system_stm32wbxx.c @@ -124,7 +124,55 @@ /** * @} */ - +#if (OTA_SUPPORT == 1) +/* Note: Following vector table addresses must be defined in line with linker + configuration. */ +/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2 + CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept + at address 0x00 which correspond to automatic remap of boot address selected */ +#define USER_VECT_TAB_ADDRESS +#if defined(USER_VECT_TAB_ADDRESS) +#ifdef CORE_CM0PLUS +/*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM2_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x100. */ +#define VECT_TAB_OFFSET \ + 0x00008000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x100. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x100. */ +#define VECT_TAB_OFFSET \ + 0x00020000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x100. */ +#endif +#else +/*!< Uncomment this line for user vector table remap in Sram else user remap + will be done in Flash. */ +/* #define VECT_TAB_SRAM */ +#if defined(VECT_TAB_SRAM) +#define VECT_TAB_BASE_ADDRESS \ + SRAM1_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#else +#define VECT_TAB_BASE_ADDRESS \ + FLASH_BASE /*!< Vector Table base address field. \ + This value must be a multiple of 0x200. */ +#define VECT_TAB_OFFSET \ + 0x00000000U /*!< Vector Table base offset field. \ + This value must be a multiple of 0x200. */ +#endif +#endif +#endif +#endif /** @addtogroup STM32WBxx_System_Private_Macros * @{ */ @@ -137,12 +185,12 @@ * @{ */ /* 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. + 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)*/ @@ -177,6 +225,18 @@ const uint32_t SmpsPrescalerTable[4UL][6UL] = { { 1UL, 3UL, 2UL, 2UL, 1UL, 2UL } /** @addtogroup STM32WBxx_System_Private_Functions * @{ */ +#if (OTA_SUPPORT == 1) +#if defined(__ICCARM__) +extern uint32_t __vector_table; +#define INTVECT_START ((uint32_t) &__vector_table) +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +extern void * __Vectors; +#define INTVECT_START ((uint32_t) &__Vectors) +#elif defined(__GNUC__) +extern void * g_pfnVectors; +#define INTVECT_START ((uint32_t) &g_pfnVectors) +#endif +#endif /** * @brief Setup the microcontroller system. @@ -187,10 +247,46 @@ void SystemInit(void) { OTP_ID0_t * p_otp; +#if (OTA_SUPPORT == 1) +#if defined(USER_VECT_TAB_ADDRESS) + /* Configure the Vector Table location add offset address ------------------*/ + /* Reuse information from map file */ + SCB->VTOR = INTVECT_START; /* Vector Table Relocation in Internal FLASH */ +#endif +#endif /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */ #endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00070000U; + + /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ + RCC->CR &= (uint32_t) 0xFAF6FEFBU; + + /*!< Reset LSI1 and LSI2 bits */ + RCC->CSR &= (uint32_t) 0xFFFFFFFAU; + + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t) 0xFFFFFFFEU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x22041000U; + +#if defined(STM32WB55xx) || defined(STM32WB5Mxx) + /* Reset PLLSAI1CFGR register */ + RCC->PLLSAI1CFGR = 0x22041000U; +#endif + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000; /** * Read HSE_Tuning from OTP @@ -296,7 +392,7 @@ void SystemCoreClockUpdate(void) case 0x0C: /* PLL used as system clock source */ /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN - SYSCLK = PLL_VCO / PLLR + SYSCLK = PLL_VCO / PLLR */ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL; diff --git a/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h index aeb0ac1b8913da..e1ff4e30648486 100644 --- a/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h +++ b/examples/platform/stm32/config_files/STM32WB5/FreeRTOSConfig.h @@ -76,7 +76,7 @@ extern uint32_t SystemCoreClock; #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configUSE_TICKLESS_IDLE 0 +#define configUSE_TICKLESS_IDLE 2 /* 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. */ @@ -172,19 +172,20 @@ standard names. */ /* 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 +/*#define configGENERATE_RUN_TIME_STATS 1 -#if (configGENERATE_RUN_TIME_STATS == 1) +#if( configGENERATE_RUN_TIME_STATS == 1 ) -extern void RTOS_AppConfigureTimerForRuntimeStats(); + extern void RTOS_AppConfigureTimerForRuntimeStats(); -extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); + extern uint32_t RTOS_AppGetRuntimeCounterValueFromISR(); -#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() RTOS_AppConfigureTimerForRuntimeStats() -#define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() + #define portGET_RUN_TIME_COUNTER_VALUE() RTOS_AppGetRuntimeCounterValueFromISR() #endif +*/ /* USER CODE END Defines */ diff --git a/examples/platform/stm32/config_files/STM32WB5/matter_config.h b/examples/platform/stm32/config_files/STM32WB5/matter_config.h index e89e44b64fda3b..987b9273e3af5d 100644 --- a/examples/platform/stm32/config_files/STM32WB5/matter_config.h +++ b/examples/platform/stm32/config_files/STM32WB5/matter_config.h @@ -1,19 +1,29 @@ -/** - ****************************************************************************** - * @file matter_config.h - * @author MCD Application Team - * @brief config file for mbedtls - ****************************************************************************** - * @attention - * - * Copyright (c) 2019-2021 STMicroelectronics. - * All rights reserved. +/* + * Copyright (c) 2020, The OpenThread Authors. + * 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. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder 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. */ #pragma once @@ -67,10 +77,7 @@ extern "C" { #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 @@ -114,9 +121,9 @@ extern "C" { #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 */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maximum fragment length in bytes */ #else -#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maximum fragment length in bytes */ #endif #define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 @@ -134,6 +141,7 @@ extern "C" { #include "mbedtls/check_config.h" #include "mbedtls/config_psa.h" +int mbedtls_ssl_safer_memcmp(const void * a, const void * b, size_t n); #ifdef __cplusplus } #endif diff --git a/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld index 56292a5b88ac1b..81e0246bd94d76 100644 --- a/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld +++ b/examples/platform/stm32/ldscripts/STM32WB5MMGHX_FLASH.ld @@ -1,198 +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 - - - - - - -} - - - - +/* +****************************************************************************** +** +** 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/src/platform/stm32/BLEManagerImpl.cpp b/src/platform/stm32/BLEManagerImpl.cpp index fc24ebc64ac006..7a040a5fb93ba3 100644 --- a/src/platform/stm32/BLEManagerImpl.cpp +++ b/src/platform/stm32/BLEManagerImpl.cpp @@ -24,7 +24,8 @@ /* this file behaves like a config.h, comes first */ #include -#include +#include +#include #include #include @@ -445,7 +446,15 @@ CHIP_ERROR BLEManagerImpl::StartAdvertising(void) mFlags.Clear(Flags::kRestartAdvertising); - APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + APP_BLE_Adv_Request(APP_BLE_FAST_ADV); + } + else + { + APP_BLE_Adv_Request(APP_BLE_LP_ADV); + } + // Flag updated asynchronously by BLE host callback mFlags.Set(Flags::kAdvertising); @@ -700,16 +709,8 @@ 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 advertisement"); - sInstance.StopAdvertising(); - sInstance.mFlags.Set(Flags::kRestartAdvertising); - } - else if (BLEMgrImpl().mFlags.Has(Flags::kAdvertising)) - { - // Advertisement time expired. Stop advertising - ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertisement"); - BLEMgr().SetAdvertisingEnabled(false); + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); } } diff --git a/src/platform/stm32/BUILD.gn b/src/platform/stm32/BUILD.gn index 43f656d0eca988..9b2ed9008c858a 100644 --- a/src/platform/stm32/BUILD.gn +++ b/src/platform/stm32/BUILD.gn @@ -10,7 +10,7 @@ # 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. +# limitations under the License. import("//build_overrides/chip.gni") import("//build_overrides/pigweed.gni") @@ -32,6 +32,7 @@ if (chip_enable_openthread) { } static_library("stm32") { + friend = [ ":lighting_app" ] deps = [ "${chip_root}/src/setup_payload" ] if (stm32_board == "STM32WB5MM-DK") { @@ -48,6 +49,8 @@ static_library("stm32") { "CHIPPlatformConfig.h", "ConfigurationManagerImpl.cpp", "ConfigurationManagerImpl.h", + "DeviceInfoProviderImpl.cpp", + "DeviceInfoProviderImpl.h", "DiagnosticDataProviderImpl.cpp", "DiagnosticDataProviderImpl.h", "FactoryDataProvider.cpp", @@ -55,6 +58,8 @@ static_library("stm32") { "InetPlatformConfig.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", + "OTAImageProcessorImpl.cpp", + "OTAImageProcessorImpl.h", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", "STM32Config.cpp", @@ -67,7 +72,10 @@ static_library("stm32") { deps += [ "${chip_root}/src/platform/logging:headers" ] } - public = [ "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h" ] + public = [ + "${chip_root}/src/credentials/DeviceAttestationCredsProvider.h", + "${chip_root}/src/credentials/examples/ExampleDACs.h", + ] public_deps = [ "${chip_root}/src/crypto", "${chip_root}/src/platform:platform_base", diff --git a/src/platform/stm32/CHIPDevicePlatformConfig.h b/src/platform/stm32/CHIPDevicePlatformConfig.h index aee9ec36a2b73a..6fe4c14eb26a3c 100644 --- a/src/platform/stm32/CHIPDevicePlatformConfig.h +++ b/src/platform/stm32/CHIPDevicePlatformConfig.h @@ -36,7 +36,6 @@ #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 #if CHIP_ENABLE_OPENTHREAD @@ -56,7 +55,10 @@ // ========== Platform-specific Configuration Overrides ========= -#define CHIP_DEVICE_CONFIG_CHIP_TASK_NAME "STM32WB TASK" +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "STMicroelectronics" +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "STM32WB Demo App" + +#define CHIP_DEVICE_CONFIG_CHIP_TASK_NAME "STM32 TASK" #define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (8 * 1024) /** diff --git a/src/platform/stm32/CHIPMem-Platform.cpp b/src/platform/stm32/CHIPMem-Platform.cpp index 2e37bafe7cf1b8..b9bf90f429f444 100644 --- a/src/platform/stm32/CHIPMem-Platform.cpp +++ b/src/platform/stm32/CHIPMem-Platform.cpp @@ -162,6 +162,20 @@ static void VerifyInitialized(const char * func) } } +static size_t MemoryBlockSize(void * ptr) +{ + + uint8_t * p = static_cast(ptr); + // Subtract the size of the header from the pointer + p -= sizeof(size_t); + // Read the size of the memory block from the header + size_t size = *reinterpret_cast(p); + // Add the size of the header to the size of the memory block + size += sizeof(size_t); + + return size; +} + CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) { if (memoryInitialized++ > 0) @@ -211,10 +225,31 @@ void * MemoryCalloc(size_t num, size_t size) void * MemoryRealloc(void * p, size_t size) { - VERIFY_INITIALIZED(); + void * new_ptr; + if (size == 0) + { + MemoryFree(p); + return NULL; + } - p = realloc(p, size); - return p; + new_ptr = MemoryAlloc(size); + if (new_ptr == NULL) + { + return NULL; + } + + if (p != NULL) + { + size_t copy_size = MemoryBlockSize(p); + if (copy_size > size) + { + copy_size = size; + } + memcpy(new_ptr, p, copy_size); + MemoryFree(p); + } + + return new_ptr; } void MemoryFree(void * p) diff --git a/src/platform/stm32/ConfigurationManagerImpl.cpp b/src/platform/stm32/ConfigurationManagerImpl.cpp index da8638460a78f3..cbfa37cf3c3272 100644 --- a/src/platform/stm32/ConfigurationManagerImpl.cpp +++ b/src/platform/stm32/ConfigurationManagerImpl.cpp @@ -164,5 +164,10 @@ ConfigurationManager & ConfigurationMgrImpl() return ConfigurationManagerImpl::GetDefaultInstance(); } +CHIP_ERROR ConfigurationManagerImpl::GetCountryCode(char * buf, size_t bufSize, size_t & codeLen) +{ + return STM32Config::ReadConfigValueStr(STM32Config::kConfigKey_CountryCode, buf, bufSize, codeLen); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/stm32/ConfigurationManagerImpl.h b/src/platform/stm32/ConfigurationManagerImpl.h index 78b885581ce151..46b5b6a1247de2 100644 --- a/src/platform/stm32/ConfigurationManagerImpl.h +++ b/src/platform/stm32/ConfigurationManagerImpl.h @@ -34,7 +34,7 @@ namespace DeviceLayer { */ // class ConfigurationManagerImpl final : public Internal::GenericConfigurationManagerImpl, -// public Internal::STM32Config +// public Internal::STM32Config class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl { public: @@ -66,6 +66,7 @@ class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImp 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; + CHIP_ERROR GetCountryCode(char * buf, size_t bufSize, size_t & codeLen) override; // ===== Private members reserved for use by this class only. diff --git a/src/platform/stm32/DeviceInfoProviderImpl.cpp b/src/platform/stm32/DeviceInfoProviderImpl.cpp new file mode 100644 index 00000000000000..5524b770c0585a --- /dev/null +++ b/src/platform/stm32/DeviceInfoProviderImpl.cpp @@ -0,0 +1,374 @@ +/* + * + * 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 + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { + +namespace { +constexpr TLV::Tag kLabelNameTag = TLV::ContextTag(0); +constexpr TLV::Tag kLabelValueTag = TLV::ContextTag(1); +} // anonymous namespace + +DeviceInfoProviderImpl & DeviceInfoProviderImpl::GetDefaultInstance() +{ + static DeviceInfoProviderImpl sInstance; + return sInstance; +} + +DeviceInfoProvider::FixedLabelIterator * DeviceInfoProviderImpl::IterateFixedLabel(EndpointId endpoint) +{ + return chip::Platform::New(endpoint); +} + +DeviceInfoProviderImpl::FixedLabelIteratorImpl::FixedLabelIteratorImpl(EndpointId endpoint) : mEndpoint(endpoint) +{ + mIndex = 0; +} + +size_t DeviceInfoProviderImpl::FixedLabelIteratorImpl::Count() +{ + // A hardcoded labelList on all endpoints. + return 4; +} + +bool DeviceInfoProviderImpl::FixedLabelIteratorImpl::Next(FixedLabelType & output) +{ + bool retval = true; + + // A hardcoded list for testing only + CHIP_ERROR err = CHIP_NO_ERROR; + + const char * labelPtr = nullptr; + const char * valuePtr = nullptr; + + VerifyOrReturnError(mIndex < 4, false); + + ChipLogProgress(DeviceLayer, "Get the fixed label with index:%u at endpoint:%d", static_cast(mIndex), mEndpoint); + + switch (mIndex) + { + case 0: + labelPtr = "room"; + valuePtr = "bedroom 2"; + break; + case 1: + labelPtr = "orientation"; + valuePtr = "North"; + break; + case 2: + labelPtr = "floor"; + valuePtr = "2"; + break; + case 3: + labelPtr = "direction"; + valuePtr = "up"; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(std::strlen(labelPtr) <= kMaxLabelNameLength, false); + VerifyOrReturnError(std::strlen(valuePtr) <= kMaxLabelValueLength, false); + + Platform::CopyString(mFixedLabelNameBuf, kMaxLabelNameLength + 1, labelPtr); + Platform::CopyString(mFixedLabelValueBuf, kMaxLabelValueLength + 1, valuePtr); + + output.label = CharSpan::fromCharString(mFixedLabelNameBuf); + output.value = CharSpan::fromCharString(mFixedLabelValueBuf); + + mIndex++; + + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelLength(EndpointId endpoint, size_t val) +{ + return mStorage->SyncSetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, + static_cast(sizeof(val))); +} + +CHIP_ERROR DeviceInfoProviderImpl::GetUserLabelLength(EndpointId endpoint, size_t & val) +{ + uint16_t len = static_cast(sizeof(val)); + + return mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::UserLabelLengthKey(endpoint).KeyName(), &val, len); +} + +CHIP_ERROR DeviceInfoProviderImpl::SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) +{ + VerifyOrReturnError(CanCastTo(index), CHIP_ERROR_INVALID_ARGUMENT); + + uint8_t buf[UserLabelTLVMaxSize()]; + TLV::TLVWriter writer; + writer.Init(buf); + + TLV::TLVType outerType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerType)); + ReturnErrorOnFailure(writer.PutString(kLabelNameTag, userLabel.label)); + ReturnErrorOnFailure(writer.PutString(kLabelValueTag, userLabel.value)); + ReturnErrorOnFailure(writer.EndContainer(outerType)); + + return mStorage->SyncSetKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast(index)).KeyName(), buf, + static_cast(writer.GetLengthWritten())); +} + +CHIP_ERROR DeviceInfoProviderImpl::DeleteUserLabelAt(EndpointId endpoint, size_t index) +{ + return mStorage->SyncDeleteKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(endpoint, static_cast(index)).KeyName()); +} + +DeviceInfoProvider::UserLabelIterator * DeviceInfoProviderImpl::IterateUserLabel(EndpointId endpoint) +{ + return chip::Platform::New(*this, endpoint); +} + +DeviceInfoProviderImpl::UserLabelIteratorImpl::UserLabelIteratorImpl(DeviceInfoProviderImpl & provider, EndpointId endpoint) : + mProvider(provider), mEndpoint(endpoint) +{ + size_t total = 0; + + ReturnOnFailure(mProvider.GetUserLabelLength(mEndpoint, total)); + mTotal = total; + mIndex = 0; +} + +bool DeviceInfoProviderImpl::UserLabelIteratorImpl::Next(UserLabelType & output) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(mIndex < mTotal, false); + VerifyOrReturnError(CanCastTo(mIndex), false); + + uint8_t buf[UserLabelTLVMaxSize()]; + uint16_t len = static_cast(sizeof(buf)); + + err = mProvider.mStorage->SyncGetKeyValue( + DefaultStorageKeyAllocator::UserLabelIndexKey(mEndpoint, static_cast(mIndex)).KeyName(), buf, len); + VerifyOrReturnError(err == CHIP_NO_ERROR, false); + + TLV::ContiguousBufferTLVReader reader; + reader.Init(buf); + err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag()); + VerifyOrReturnError(err == CHIP_NO_ERROR, false); + + TLV::TLVType containerType; + VerifyOrReturnError(reader.EnterContainer(containerType) == CHIP_NO_ERROR, false); + + chip::CharSpan label; + chip::CharSpan value; + + VerifyOrReturnError(reader.Next(kLabelNameTag) == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.Get(label) == CHIP_NO_ERROR, false); + + VerifyOrReturnError(reader.Next(kLabelValueTag) == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.Get(value) == CHIP_NO_ERROR, false); + + VerifyOrReturnError(reader.VerifyEndOfContainer() == CHIP_NO_ERROR, false); + VerifyOrReturnError(reader.ExitContainer(containerType) == CHIP_NO_ERROR, false); + + Platform::CopyString(mUserLabelNameBuf, label); + Platform::CopyString(mUserLabelValueBuf, value); + + output.label = CharSpan::fromCharString(mUserLabelNameBuf); + output.value = CharSpan::fromCharString(mUserLabelValueBuf); + + mIndex++; + + return true; +} + +DeviceInfoProvider::SupportedLocalesIterator * DeviceInfoProviderImpl::IterateSupportedLocales() +{ + return chip::Platform::New(); +} + +size_t DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Count() +{ + // Hardcoded list of locales + // {("en-US"), ("de-DE"), ("fr-FR"), ("en-GB"), ("es-ES"), ("zh-CN"), ("it-IT"), ("ja-JP")} + + return 8; +} + +bool DeviceInfoProviderImpl::SupportedLocalesIteratorImpl::Next(CharSpan & output) +{ + bool retval = true; + + // Hardcoded list of locales + CHIP_ERROR err = CHIP_NO_ERROR; + + const char * activeLocalePtr = nullptr; + + VerifyOrReturnError(mIndex < 8, false); + + switch (mIndex) + { + case 0: + activeLocalePtr = "en-US"; + break; + case 1: + activeLocalePtr = "de-DE"; + break; + case 2: + activeLocalePtr = "fr-FR"; + break; + case 3: + activeLocalePtr = "en-GB"; + break; + case 4: + activeLocalePtr = "es-ES"; + break; + case 5: + activeLocalePtr = "zh-CN"; + break; + case 6: + activeLocalePtr = "it-IT"; + break; + case 7: + activeLocalePtr = "ja-JP"; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(std::strlen(activeLocalePtr) <= kMaxActiveLocaleLength, false); + + Platform::CopyString(mActiveLocaleBuf, kMaxActiveLocaleLength + 1, activeLocalePtr); + + output = CharSpan::fromCharString(mActiveLocaleBuf); + + mIndex++; + + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +DeviceInfoProvider::SupportedCalendarTypesIterator * DeviceInfoProviderImpl::IterateSupportedCalendarTypes() +{ + return chip::Platform::New(); +} + +size_t DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Count() +{ + // Hardcoded list of strings + // {("kBuddhist"), ("kChinese"), ("kCoptic"), ("kEthiopian"), ("kGregorian"), ("kHebrew"), ("kIndian"), ("kJapanese"), + // ("kKorean"), ("kPersian"), ("kTaiwanese"), ("kIslamic")} + + return 12; +} + +bool DeviceInfoProviderImpl::SupportedCalendarTypesIteratorImpl::Next(CalendarType & output) +{ + bool retval = true; + + // Hardcoded list of Strings that are valid values for the Calendar Types. + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrReturnError(mIndex < 12, false); + + switch (mIndex) + { + case 0: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kBuddhist; + break; + case 1: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kChinese; + break; + case 2: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kCoptic; + break; + case 3: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kEthiopian; + break; + case 4: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kGregorian; + break; + case 5: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kHebrew; + break; + case 6: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kIndian; + break; + case 7: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kJapanese; + break; + case 8: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kKorean; + break; + case 9: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kPersian; + break; + case 10: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kTaiwanese; + break; + case 11: + output = app::Clusters::TimeFormatLocalization::CalendarTypeEnum::kIslamic; + break; + default: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + } + + if (err == CHIP_NO_ERROR) + { + mIndex++; + retval = true; + } + else + { + retval = false; + } + + return retval; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DeviceInfoProviderImpl.h b/src/platform/stm32/DeviceInfoProviderImpl.h new file mode 100644 index 00000000000000..30e153e2815537 --- /dev/null +++ b/src/platform/stm32/DeviceInfoProviderImpl.h @@ -0,0 +1,107 @@ +/* + * + * 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 + +namespace chip { +namespace DeviceLayer { + +class DeviceInfoProviderImpl : public DeviceInfoProvider +{ +public: + DeviceInfoProviderImpl() = default; + ~DeviceInfoProviderImpl() override {} + + // Iterators + FixedLabelIterator * IterateFixedLabel(EndpointId endpoint) override; + UserLabelIterator * IterateUserLabel(EndpointId endpoint) override; + SupportedLocalesIterator * IterateSupportedLocales() override; + SupportedCalendarTypesIterator * IterateSupportedCalendarTypes() override; + + static DeviceInfoProviderImpl & GetDefaultInstance(); + +protected: + class FixedLabelIteratorImpl : public FixedLabelIterator + { + public: + FixedLabelIteratorImpl(EndpointId endpoint); + size_t Count() override; + bool Next(FixedLabelType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + EndpointId mEndpoint = 0; + size_t mIndex = 0; + char mFixedLabelNameBuf[kMaxLabelNameLength + 1]; + char mFixedLabelValueBuf[kMaxLabelValueLength + 1]; + }; + + class UserLabelIteratorImpl : public UserLabelIterator + { + public: + UserLabelIteratorImpl(DeviceInfoProviderImpl & provider, EndpointId endpoint); + size_t Count() override { return mTotal; } + bool Next(UserLabelType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + DeviceInfoProviderImpl & mProvider; + EndpointId mEndpoint = 0; + size_t mIndex = 0; + size_t mTotal = 0; + char mUserLabelNameBuf[kMaxLabelNameLength + 1]; + char mUserLabelValueBuf[kMaxLabelValueLength + 1]; + }; + + class SupportedLocalesIteratorImpl : public SupportedLocalesIterator + { + public: + SupportedLocalesIteratorImpl() = default; + size_t Count() override; + bool Next(CharSpan & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + size_t mIndex = 0; + char mActiveLocaleBuf[kMaxActiveLocaleLength + 1]; + }; + + class SupportedCalendarTypesIteratorImpl : public SupportedCalendarTypesIterator + { + public: + SupportedCalendarTypesIteratorImpl() = default; + size_t Count() override; + bool Next(CalendarType & output) override; + void Release() override { chip::Platform::Delete(this); } + + private: + size_t mIndex = 0; + }; + + CHIP_ERROR SetUserLabelLength(EndpointId endpoint, size_t val) override; + CHIP_ERROR GetUserLabelLength(EndpointId endpoint, size_t & val) override; + CHIP_ERROR SetUserLabelAt(EndpointId endpoint, size_t index, const UserLabelType & userLabel) override; + CHIP_ERROR DeleteUserLabelAt(EndpointId endpoint, size_t index) override; + +private: + static constexpr size_t UserLabelTLVMaxSize() { return TLV::EstimateStructOverhead(kMaxLabelNameLength, kMaxLabelValueLength); } +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/stm32/DiagnosticDataProviderImpl.h b/src/platform/stm32/DiagnosticDataProviderImpl.h index 85ac3fc206f8ae..eb843ea9a3d140 100644 --- a/src/platform/stm32/DiagnosticDataProviderImpl.h +++ b/src/platform/stm32/DiagnosticDataProviderImpl.h @@ -30,7 +30,7 @@ namespace chip { namespace DeviceLayer { /** - * Concrete implementation of the PlatformManager singleton object for stm32 platforms. + * Concrete implementation of the PlatformManager singleton object for STM32 platforms. */ class DiagnosticDataProviderImpl : public DiagnosticDataProvider diff --git a/src/platform/stm32/FactoryDataProvider.cpp b/src/platform/stm32/FactoryDataProvider.cpp index fc8e072836fd41..8b3d0af05a6ec7 100644 --- a/src/platform/stm32/FactoryDataProvider.cpp +++ b/src/platform/stm32/FactoryDataProvider.cpp @@ -17,12 +17,21 @@ #include "FactoryDataProvider.h" +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) +#include +#endif + #include #include #include #include #include +#ifdef USE_STM32WBXX_DAC_CRYPTO +#include +#include +#endif + namespace chip { namespace {} // namespace @@ -33,6 +42,24 @@ CHIP_ERROR FactoryDataProvider::Init() return CHIP_NO_ERROR; } +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) +CHIP_ERROR FactoryDataProvider::MapSTM32WBError(FACTORYDATA_StatusTypeDef err) +{ + switch (err) + { + case DATAFACTORY_OK: + return CHIP_NO_ERROR; + case DATAFACTORY_BUFFER_TOO_SMALL: + return CHIP_ERROR_BUFFER_TOO_SMALL; + case DATAFACTORY_PARAM_ERROR: + return CHIP_ERROR_INVALID_ARGUMENT; + default: + break; + } + return CHIP_ERROR_INTERNAL; +} +#endif + FactoryDataProvider & FactoryDataProvider::GetDefaultInstance() { static FactoryDataProvider sInstance; @@ -61,96 +88,159 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan private_key, ByteSpan public_key, Crypto: 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); +#ifdef USE_STM32WBXX_DAC_CRYPTO + otError otCksDAC_error; + uint8_t signature_bytes[Crypto::kP256_ECDSA_Signature_Length_Raw]; +#endif VerifyOrReturnError(!outSignBuffer.empty(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(!messageToSign.empty(), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); +#ifdef USE_STM32WBXX_DAC_CRYPTO + + otCksDAC_error = + otCksDacSignature(messageToSign.data(), messageToSign.size(), DevelopmentCerts::kDacPublicKey.data(), &signature_bytes[0]); + memcpy(signature.Bytes(), &signature_bytes[0], Crypto::kP256_ECDSA_Signature_Length_Raw); + signature.SetLength(Crypto::kP256_ECDSA_Signature_Length_Raw); + + if (otCksDAC_error != OT_ERROR_NONE) + { + ChipLogProgress(Crypto, "DAC signature unexpected failure"); + return CHIP_ERROR_INTERNAL; + } + +#else // 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)); +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorOnFailure(LoadKeypairFromRaw(DevelopmentCerts::kDacPrivateKey, DevelopmentCerts::kDacPublicKey, keypair)); - return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + uint8_t Privatekeybuffer[PRIVATE_KEY_LEN]; + uint8_t Publickeybuffer[PUBLIC_KEY_LEN]; + uint32_t tlvDataLength; // Dummy value keys values are fix + FACTORYDATA_StatusTypeDef err; + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_PRIVATE_KEY, Privatekeybuffer, PRIVATE_KEY_LEN, &tlvDataLength); + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_PUBLIC_KEY, Publickeybuffer, PUBLIC_KEY_LEN, &tlvDataLength); + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(Privatekeybuffer), ByteSpan(Publickeybuffer), keypair)); +#endif + + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(messageToSign.data(), messageToSign.size(), signature)); #endif + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); } CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) setupDiscriminator = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SETUP_DISCRIMINATOR, (uint8_t *) &setupDiscriminator, sizeof(setupDiscriminator), + &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) constexpr uint32_t kDefaultTestVerifierIterationCount = 1000; iterationCount = kDefaultTestVerifierIterationCount; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_ITERATION_COUNT, (uint8_t *) &iterationCount, sizeof(iterationCount), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) setupPasscode = CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_SETUP_PASSCODE, (uint8_t *) &setupPasscode, sizeof(setupPasscode), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) vendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_VENDOR_ID, (uint8_t *) &vendorId, sizeof(vendorId), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) productId = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_ID, (uint8_t *) &productId, sizeof(productId), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) hardwareVersion = CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION; return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_HARDWARE_VERSION, (uint8_t *) &hardwareVersion, sizeof(hardwareVersion), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } @@ -176,32 +266,68 @@ CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + + memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME)); +#else + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_VENDOR_NAME, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + +#endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME)); +#else + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_NAME, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); +#endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) memcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, bufSize); return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SERIAL_NUMBER, (uint8_t *) buf, bufSize, &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING, + sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING)); + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierSpan, size_t & verifierLen) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) 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, @@ -217,16 +343,24 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierSpa } memcpy(verifierSpan.data(), &kDefaultTestVerifier[0], verifierLen); verifierSpan.reduce_size(verifierLen); - return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_VERIFIER, verifierSpan.data(), verifierSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + verifierSpan.reduce_size(tlvDataLength); + verifierLen = tlvDataLength; #endif + return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBufferSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) //-> format_version = 1 //-> vendor_id = 0xFFF1 //-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, @@ -276,7 +410,15 @@ CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & ou return CopySpanToMutableSpan(ByteSpan{ kCdForAllExamples }, outBufferSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_CERTIFICATION_DECLARATION, outBufferSpan.data(), outBufferSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + outBufferSpan.reduce_size(tlvDataLength); + return CHIP_NO_ERROR; #endif } @@ -287,7 +429,7 @@ CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & firmwar CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & attestationCertSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) 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, @@ -318,13 +460,23 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & attes return CopySpanToMutableSpan(ByteSpan(kDevelopmentDAC_Cert_FFF1_8004), attestationCertSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_DEVICE_ATTESTATION_CERTIFICATE, attestationCertSpan.data(), attestationCertSpan.size(), + &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + attestationCertSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & intermediateCertSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) 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, @@ -354,13 +506,23 @@ CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByt return CopySpanToMutableSpan(ByteSpan(kDevelopmentPAI_Cert_FFF1), intermediateCertSpan); #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_PRODUCT_ATTESTATION_INTERMEDIATE_CERTIFICATE, intermediateCertSpan.data(), + intermediateCertSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + intermediateCertSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltSpan) { -#if !CONFIG_STM32_FACTORY_DATA_ENABLE +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) static const uint8_t kDefaultTestVerifierSalt[16] = { 0x53, 0x50, 0x41, 0x4b, 0x45, 0x32, 0x50, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x53, 0x61, 0x6c, 0x74, }; @@ -374,7 +536,16 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltSpan) saltSpan.reduce_size(saltLen); return CHIP_NO_ERROR; #else - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + FACTORYDATA_StatusTypeDef err; + uint32_t tlvDataLength; + + err = FACTORYDATA_GetValue(TAG_ID_SPAKE2_SALT, saltSpan.data(), saltSpan.size(), &tlvDataLength); + + VerifyOrReturnError(DATAFACTORY_OK == err, MapSTM32WBError(err)); + + saltSpan.reduce_size(tlvDataLength); + + return CHIP_NO_ERROR; #endif } diff --git a/src/platform/stm32/FactoryDataProvider.h b/src/platform/stm32/FactoryDataProvider.h index 2882b989e8902d..e9522734dca9d2 100644 --- a/src/platform/stm32/FactoryDataProvider.h +++ b/src/platform/stm32/FactoryDataProvider.h @@ -17,6 +17,10 @@ #pragma once +#include "app_conf.h" +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) +#include "stm32_factorydata.h" +#endif #include #include #include @@ -63,6 +67,11 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia // ===== Members functions that are platform-specific CHIP_ERROR GetEnableKey(MutableByteSpan & enableKey); + +protected: +#if (CONFIG_STM32_FACTORY_DATA_ENABLE == 1) + static CHIP_ERROR MapSTM32WBError(FACTORYDATA_StatusTypeDef err); +#endif }; } // namespace DeviceLayer diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.cpp b/src/platform/stm32/KeyValueStoreManagerImpl.cpp index b68ea2c1c9adc9..723b97318eba49 100644 --- a/src/platform/stm32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/stm32/KeyValueStoreManagerImpl.cpp @@ -23,7 +23,6 @@ #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 { diff --git a/src/platform/stm32/KeyValueStoreManagerImpl.h b/src/platform/stm32/KeyValueStoreManagerImpl.h index 335ffb2b907df9..614bae7da594d2 100644 --- a/src/platform/stm32/KeyValueStoreManagerImpl.h +++ b/src/platform/stm32/KeyValueStoreManagerImpl.h @@ -16,8 +16,8 @@ * limitations under the License. */ -#ifndef MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ -#define MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ +#ifndef MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ +#define MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ #pragma once @@ -79,4 +79,4 @@ inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) } // namespace DeviceLayer } // namespace chip -#endif /* MIDDLEWARES_MATTER_PLATFORM_STM32WB_KEYVALUESTOREMANAGERIMPL_H_ */ +#endif /* MIDDLEWARES_MATTER_PLATFORM_STM32_KEYVALUESTOREMANAGERIMPL_H_ */ diff --git a/src/platform/stm32/OTAImageProcessorImpl.cpp b/src/platform/stm32/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..76363befebb005 --- /dev/null +++ b/src/platform/stm32/OTAImageProcessorImpl.cpp @@ -0,0 +1,439 @@ +/* + * + * 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 "app_common.h" +#if (OTA_SUPPORT == 1) +#include +#include + +#include "OTAImageProcessorImpl.h" +#include "ota.h" +#include "sfu_fwimg_regions.h" +#include "stm_ext_flash.h" +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +#include "mapping_fwimg.h" +#include "mapping_sbsfu.h" +#elif defined(__ICCARM__) || defined(__GNUC__) +#include "mapping_export.h" +#endif /* __CC_ARM || __ARMCC_VERSION */ +#include "sfu_standalone_loader.h" + +#define STM_HEADER_SIZE 8 +static uint32_t mCPU1Size; +static uint32_t mCPU2Size; +static uint32_t mDownloadedBytesCPU2; +static uint8_t mSwitchDwlSlot; + +namespace chip { + +bool OTAImageProcessorImpl::IsFirstImageRun() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return false; + } + + return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; +} + +CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() +{ + ChipLogProgress(DeviceLayer, "OTA Confirm current image"); + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + uint32_t currentVersion; + uint32_t targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion, + targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + + // Get OTA status - under what circumstances does prepared break? + // what happens if a prepare is pending and another one is invoked + // Should we store the state here and wait until we receive notification + + mHeaderParser.Init(); + + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) +{ + ChipLogProgress(DeviceLayer, "OTA Process Header"); + if (mHeaderParser.IsInitialized()) + { + OTAImageHeader header; + CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); + + // Needs more data to decode the header + ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + ReturnErrorOnFailure(error); + + mParams.totalFileBytes = header.mPayloadSize; + mHeaderParser.Clear(); + + // Load Ota_ImageHeader_t header structure and call application callback to validate image header + Ota_ImageHeader_t OtaImgHeader; + this->mSwVer = header.mSoftwareVersion; // Store software version in imageProcessor as well + OtaImgHeader.vendorId = header.mVendorId; + OtaImgHeader.productId = header.mProductId; + OtaImgHeader.softwareVersion = header.mSoftwareVersion; + OtaImgHeader.minApplicableVersion = header.mMinApplicableVersion.ValueOr(0); + OtaImgHeader.maxApplicableVersion = header.mMaxApplicableVersion.ValueOr(0); + + if (true != OtaHeaderValidation(OtaImgHeader)) + { + return CHIP_ERROR_INCORRECT_STATE; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + ChipLogProgress(SoftwareUpdate, "Applying - resetting device"); + + if (mCPU2Size == 0) + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_INSTALL_REQ; // install only CPU1 + } + else if (mCPU1Size == 0) + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_BYPASS_REQ; // install only CPU2 + } + else + { + STANDALONE_LOADER_STATE = STANDALONE_LOADER_BYPASS_REQ_AND_INSTALL_REQ; // install CPU1 and CPU2 + } + NVIC_SystemReset(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + CHIP_ERROR err = ProcessHeader(block); + ChipLogProgress(DeviceLayer, "OTA Process Block"); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Matter image header parser error %s", chip::ErrorStr(err)); + this->mDownloader->EndDownload(CHIP_ERROR_INVALID_FILE_IDENTIFIER); + return err; + } + + // Store block data for HandleProcessBlock to access + err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + ChipLogProgress(DeviceLayer, "OTA Prepare DL"); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + // running this in a thread so won't block main event loop + ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload"); + + mSwitchDwlSlot = false; // start with dwl_slot1 for CPU1 + + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_1_START, SLOT_SIZE(SLOT_DWL_1)); + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_4_START, SLOT_SIZE(SLOT_DWL_4)); + + // Initialize tracking variables + imageProcessor->mParams.downloadedBytes = 0; + mDownloadedBytesCPU2 = 0; + imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + ChipLogProgress(SoftwareUpdate, "HandleFinalize"); + + imageProcessor->ReleaseBlock(); + // Start from scratch + imageProcessor->mParams.downloadedBytes = 0; +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + ChipLogProgress(SoftwareUpdate, "HandleAbort"); + + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_1_START, SLOT_SIZE(SLOT_DWL_1)); + STM_EXT_FLASH_Delete_Image(EXTERNAL_FLASH_ADDRESS + SLOT_DWL_4_START, SLOT_SIZE(SLOT_DWL_4)); + imageProcessor->ReleaseBlock(); + // Start from scratch + imageProcessor->mParams.downloadedBytes = 0; + mDownloadedBytesCPU2 = 0; + mSwitchDwlSlot = false; // start with dwl_slot1 for CPU1 +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + STM_OTA_StatusTypeDef status; + auto * imageProcessor = reinterpret_cast(context); + + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + if (mSwitchDwlSlot == false) + { // CPU1 write in DWL_SLOT 1 + if (imageProcessor->mParams.downloadedBytes == 0) + { // get STM_Header + uint8_t STMHeader[STM_HEADER_SIZE]; + + memcpy(STMHeader, reinterpret_cast(imageProcessor->mBlock.data()), sizeof(STMHeader)); + + // retrieve the cpu1/2 size with STM header + mCPU1Size = STMHeader[0] + ((STMHeader[1]) << 8) + ((STMHeader[2]) << 16) + ((STMHeader[3]) << 24); + mCPU2Size = STMHeader[4] + ((STMHeader[5]) << 8) + ((STMHeader[6]) << 16) + ((STMHeader[7]) << 24); + + // check the header + if ((mCPU1Size > SLOT_SIZE(SLOT_DWL_1)) || (mCPU2Size > SLOT_SIZE(SLOT_DWL_4)) || (mCPU2Size + mCPU1Size == 0)) + { + ChipLogError(SoftwareUpdate, "Flash decode failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_DECODE_FAILED); + return; + } + + if (mCPU1Size == 0) + { // update only CPU2 + // write in DWL_SLOT1 data without STM header + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()) + STM_HEADER_SIZE, + static_cast(imageProcessor->mBlock.size()) - STM_HEADER_SIZE); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size() - STM_HEADER_SIZE; + mSwitchDwlSlot = true; // switch to DWL_SLOT 4 for all the next data + mDownloadedBytesCPU2 = imageProcessor->mBlock.size() - STM_HEADER_SIZE; // update the bytes write in Dwl_slot4 + } + else + { + + // write in DWL_SLOT1 data without STM header + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()) + STM_HEADER_SIZE, + static_cast(imageProcessor->mBlock.size()) - STM_HEADER_SIZE); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size() - STM_HEADER_SIZE; + } + } + else if ((imageProcessor->mParams.downloadedBytes + static_cast(imageProcessor->mBlock.size())) >= mCPU1Size) + { + + // split the block in 2 for Dwl_slot1 and Dwl_slot4 + uint32_t CPU2BlockStart = + imageProcessor->mParams.downloadedBytes + static_cast(imageProcessor->mBlock.size()) - mCPU1Size; + uint32_t CPU1BlockEnd = static_cast(imageProcessor->mBlock.size()) - CPU2BlockStart; + + if (CPU2BlockStart + CPU1BlockEnd == static_cast(imageProcessor->mBlock.size())) + { + mDownloadedBytesCPU2 = 0; + + // CPU1 write in DWL_SLOT 1 + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()), CPU1BlockEnd); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + if (mCPU2Size != 0) + { + // CPU2 write in DWL_SLOT 4 + status = STM_EXT_FLASH_WriteChunk( + mDownloadedBytesCPU2 + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()) + CPU1BlockEnd, CPU2BlockStart); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + mSwitchDwlSlot = true; // switch to DWL_SLOT 4 for all the next data + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); // keep track of all bytes dwl + mDownloadedBytesCPU2 = CPU2BlockStart; // update the bytes write in Dwl_slot4 + } + } + else + { + ChipLogError(SoftwareUpdate, "Flash decode failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_DECODE_FAILED); + return; + } + } + else + { // CPU1 write in DWL_SLOT 1 + status = STM_EXT_FLASH_WriteChunk(imageProcessor->mParams.downloadedBytes + SLOT_DWL_1_START, + reinterpret_cast(imageProcessor->mBlock.data()), + static_cast(imageProcessor->mBlock.size())); + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); + } + } + else + { // CPU2 write in DWL_SLOT 4 + status = STM_EXT_FLASH_WriteChunk(mDownloadedBytesCPU2 + SLOT_DWL_4_START, + reinterpret_cast(imageProcessor->mBlock.data()), + static_cast(imageProcessor->mBlock.size())); + + if (status != STM_EXT_FLASH_OK) + { + ChipLogError(SoftwareUpdate, "Flash write failed"); + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); // keep track of all bytes dwl + mDownloadedBytesCPU2 += imageProcessor->mBlock.size(); // update the bytes write in Dwl_slot4 + } + + imageProcessor->mDownloader->FetchNextData(); +} + +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if (!IsSpanUsable(block)) + { + ReleaseBlock(); + return CHIP_NO_ERROR; + } + if (mBlock.size() < block.size()) + { + if (!mBlock.empty()) + { + ReleaseBlock(); + } + uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); + if (mBlock_ptr == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + mBlock = MutableByteSpan(mBlock_ptr, block.size()); + } + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +} // namespace chip +#endif diff --git a/src/platform/stm32/OTAImageProcessorImpl.h b/src/platform/stm32/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..493aa23842e816 --- /dev/null +++ b/src/platform/stm32/OTAImageProcessorImpl.h @@ -0,0 +1,68 @@ +/* + * + * 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 + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR ProcessHeader(ByteSpan & block); + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + bool IsFirstImageRun() override; + CHIP_ERROR ConfirmCurrentImage() override; + + void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + std::uint32_t mSwVer; + std::uint32_t mHwVer; + + MutableByteSpan mBlock; + OTADownloader * mDownloader = nullptr; + OTAImageHeaderParser mHeaderParser; +}; + +} // namespace chip diff --git a/src/platform/stm32/PlatformManagerImpl.cpp b/src/platform/stm32/PlatformManagerImpl.cpp index 60148b07f6e4ca..4c8d25dcd5cb60 100644 --- a/src/platform/stm32/PlatformManagerImpl.cpp +++ b/src/platform/stm32/PlatformManagerImpl.cpp @@ -34,6 +34,7 @@ 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) diff --git a/src/platform/stm32/PlatformManagerImpl.h b/src/platform/stm32/PlatformManagerImpl.h index 8de9bfa4a24f48..0ed24ce93f9d9e 100644 --- a/src/platform/stm32/PlatformManagerImpl.h +++ b/src/platform/stm32/PlatformManagerImpl.h @@ -31,7 +31,7 @@ namespace chip { namespace DeviceLayer { /** - * Concrete implementation of the PlatformManager singleton object for the stm32 platform. + * Concrete implementation of the PlatformManager singleton object for the STM32 platform. */ class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS { @@ -49,7 +49,6 @@ class PlatformManagerImpl final : public PlatformManager, public Internal::Gener // ===== 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. @@ -90,7 +89,7 @@ inline PlatformManager & PlatformMgr(void) * 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. + * that are specific to the STM32 platform. */ inline PlatformManagerImpl & PlatformMgrImpl(void) { diff --git a/src/platform/stm32/STM32Config.cpp b/src/platform/stm32/STM32Config.cpp index cf1a6bdc652e19..6b1134dcf0fdf2 100644 --- a/src/platform/stm32/STM32Config.cpp +++ b/src/platform/stm32/STM32Config.cpp @@ -29,42 +29,61 @@ CHIP_ERROR STM32Config::Init() return CHIP_NO_ERROR; } -template -CHIP_ERROR STM32Config::ReadConfigValue(Key key, T & val) +CHIP_ERROR STM32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - uint8_t * buffer_key[35] = { 0 }; - size_t * read_by_size = NULL; + + uint8_t buffer_key[35] = { 0 }; sprintf((char *) buffer_key, "Config%i", key); - NM_GetKeyValue((void *) &val, (char *) buffer_key, sizeof(val), read_by_size, SECTOR_NO_SECURE); + return PrintError(NM_GetKeyValue(buf, (char *) buffer_key, bufSize, &outLen, SECTOR_SECURE)); +} - return CHIP_NO_ERROR; +CHIP_ERROR STM32Config::ReadConfigValue(Key key, bool & val) +{ + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; + + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(bool), &Out_Length, SECTOR_SECURE)); } -CHIP_ERROR STM32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint32_t & val) { + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; - return ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(uint32_t), &Out_Length, SECTOR_SECURE)); } -CHIP_ERROR STM32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +CHIP_ERROR STM32Config::ReadConfigValue(Key key, uint64_t & val) { + uint8_t buffer_key[35] = { 0 }; + size_t Out_Length; - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + sprintf((char *) buffer_key, "Config%i", key); + return PrintError( + NM_GetKeyValue(reinterpret_cast(&val), (char *) buffer_key, sizeof(uint64_t), &Out_Length, SECTOR_SECURE)); } -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::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + + return ReadConfigValueBin(key, reinterpret_cast(buf), bufSize, outLen); +} CHIP_ERROR STM32Config::WriteConfigValue(Key key, uint32_t val) { - uint8_t * buffer_key[35] = { 0 }; - size_t * read_by_size = NULL; - + uint8_t buffer_key[35] = { 0 }; + uint8_t buffer_convert[4]; + buffer_convert[0] = val; + buffer_convert[1] = val >> 8; + buffer_convert[2] = val >> 16; + buffer_convert[3] = val >> 24; sprintf((char *) buffer_key, "Config%i", key); - NM_SetKeyValue((char *) &val, (char *) buffer_key, sizeof(val), SECTOR_NO_SECURE); - return CHIP_NO_ERROR; + return PrintError(NM_SetKeyValue((char *) buffer_convert, (char *) buffer_key, sizeof(uint32_t), SECTOR_SECURE)); } CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str) @@ -79,12 +98,10 @@ CHIP_ERROR STM32Config::WriteConfigValueStr(Key key, const char * str, size_t st 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; + uint8_t buffer_key[35] = { 0 }; sprintf((char *) buffer_key, "Config%i", key); - NM_SetKeyValue((char *) data, (char *) buffer_key, dataLen, SECTOR_NO_SECURE); - return CHIP_NO_ERROR; + return PrintError(NM_SetKeyValue((char *) data, (char *) buffer_key, dataLen, SECTOR_SECURE)); } bool STM32Config::ConfigValueExists(Key key) @@ -100,6 +117,55 @@ CHIP_ERROR STM32Config::FactoryResetConfig(void) void STM32Config::RunConfigUnitTest(void) {} +CHIP_ERROR STM32Config::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; + + case NVM_PARAM_ERROR: + 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 Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/stm32/STM32Config.h b/src/platform/stm32/STM32Config.h index 98ddb844616342..f1df1dc7638861 100644 --- a/src/platform/stm32/STM32Config.h +++ b/src/platform/stm32/STM32Config.h @@ -23,6 +23,7 @@ #pragma once +#include "flash_wb.h" #include namespace chip { @@ -71,11 +72,11 @@ class STM32Config 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 ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); 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); @@ -86,6 +87,7 @@ class STM32Config static bool ConfigValueExists(Key key); static CHIP_ERROR FactoryResetConfig(void); static void RunConfigUnitTest(void); + static CHIP_ERROR PrintError(NVM_StatusTypeDef err); }; } // namespace Internal diff --git a/src/platform/stm32/args.gni b/src/platform/stm32/args.gni index 56fd4e52bab0d6..4357e8ea8fa20f 100644 --- a/src/platform/stm32/args.gni +++ b/src/platform/stm32/args.gni @@ -10,7 +10,7 @@ # 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. +# limitations under the License. import("//build_overrides/chip.gni") import("//build_overrides/stm32_sdk.gni") diff --git a/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper b/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper index 0c79564e0d8c0a..6d3cba0fc32eaf 100644 --- a/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper +++ b/third_party/st/FAMILY/BOARD/STM32WB5MM-DK_sdk.gn_helper @@ -19,20 +19,23 @@ declare_args() { SOURCES = [ # BOARD APPLICATION SRC(in examples/platform/stm32/common/STM32WB5MM-DK/) + "${stm32_board_src}/Src/app_debug.c", "${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/stm_ext_flash.c", + "${stm32_board_src}/Src/stm32_factorydata.c", "${stm32_board_src}/Src/stm32_lpm_if.c", + "${stm32_board_src}/Src/stm32wb5mm_dk_qspi.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}/Src/otp.c", "${stm32_board_src}/STM32_WPAN/Target/hw_ipcc.c", "${chip_root}/examples/platform/stm32/config_files/STM32WB5/matter_config.h", @@ -46,6 +49,7 @@ SOURCES = [ #BSP COMPONENTS "${components_ssd1315}/ssd1315_reg.c", "${components_ssd1315}/ssd1315.c", + "${components_s25fl128s}/s25fl128s.c", # BOARD UTILITIES "${stm32_lpm_util}/stm32_lpm.c", diff --git a/third_party/st/STM32CubeWB b/third_party/st/STM32CubeWB index d23878380596ba..82988c4a028fbc 160000 --- a/third_party/st/STM32CubeWB +++ b/third_party/st/STM32CubeWB @@ -1 +1 @@ -Subproject commit d23878380596ba031e33fcfa4841ff91aa1ab024 +Subproject commit 82988c4a028fbc63d85fb44b813535c290f71822