diff --git a/docs/guides/esp32/factory_data.md b/docs/guides/esp32/factory_data.md index 9818eec9880964..179fb2e315a9c0 100644 --- a/docs/guides/esp32/factory_data.md +++ b/docs/guides/esp32/factory_data.md @@ -34,6 +34,9 @@ Following data can be added to the manufacturing partition using - Fixed Labels - Supported locales - Supported calendar types + - Supported modes + - Note: As per spec at max size of label should be 64 and `\0` will be + added at the end. ### Configuration Options diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 4b2f6a464e2933..70f17774c00d77 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/common" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/shell_extension" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/lock" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32/mode-support" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/util" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/reporting" @@ -91,6 +92,9 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src" ) + +set(EXCLUDE_SRCS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp") + if (CONFIG_ENABLE_PW_RPC) # Append additional directories for RPC build set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}" @@ -119,7 +123,7 @@ endif() idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST} SRC_DIRS ${SRC_DIRS_LIST} - EXCLUDE_SRCS ${EXCLUDE_SRCS_LIST} + EXCLUDE_SRCS ${EXCLUDE_SRCS} PRIV_REQUIRES ${PRIV_REQUIRES_LIST}) get_filename_component(CHIP_ROOT ${CMAKE_SOURCE_DIR}/third_party/connectedhomeip REALPATH) diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp new file mode 100644 index 00000000000000..ec752cd8be67ba --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.cpp @@ -0,0 +1,209 @@ +/* + * + * Copyright (c) 2023 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 "static-supported-modes-manager.h" +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::DeviceLayer::Internal; +using namespace chip::app::Clusters::ModeSelect; +using chip::Protocols::InteractionModel::Status; + +using ModeOptionStructType = Structs::ModeOptionStruct::Type; +using SemanticTag = Structs::SemanticTagStruct::Type; +template +using List = app::DataModel::List; + +const StaticSupportedModesManager StaticSupportedModesManager::instance = StaticSupportedModesManager(); + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::epModeOptionsProviderList[FIXED_ENDPOINT_COUNT]; + +void StaticSupportedModesManager::InitEndpointArray() +{ + for (int i = 0; i < FIXED_ENDPOINT_COUNT; i++) + { + epModeOptionsProviderList[i] = ModeOptionsProvider(); + } +} + +SupportedModesManager::ModeOptionsProvider StaticSupportedModesManager::getModeOptionsProvider(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr && epModeOptionsProviderList[endpointId].end() != nullptr) + { + return ModeOptionsProvider(epModeOptionsProviderList[endpointId].begin(), epModeOptionsProviderList[endpointId].end()); + } + + ModeOptionStructType * modeOptionStructList = nullptr; + SemanticTag * semanticTags = nullptr; + + char keyBuf[ESP32Config::kMaxConfigKeyNameLength]; + uint32_t supportedModeCount = 0; + + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesCount(keyBuf, sizeof(keyBuf), endpointId) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + ESP32Config::Key countKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(countKey, supportedModeCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr)); + + modeOptionStructList = new ModeOptionStructType[supportedModeCount]; + if (modeOptionStructList == nullptr) + { + return ModeOptionsProvider(nullptr, nullptr); + } + + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); + + for (int index = 0; index < supportedModeCount; index++) + { + Structs::ModeOptionStruct::Type option; + uint32_t supportedModeMode = 0; + uint32_t semanticTagCount = 0; + size_t outLen = 0; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesLabel(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key labelKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, nullptr, 0, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + char * modeLabel = new char[outLen + 1]; + if (modeLabel == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + + VerifyOrReturnValue(ESP32Config::ReadConfigValueStr(labelKey, modeLabel, outLen + 1, outLen) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SupportedModesValue(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key modeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(labelKey, supportedModeMode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagsCount(keyBuf, sizeof(keyBuf), endpointId, index) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stCountKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stCountKey, semanticTagCount) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + semanticTags = new SemanticTag[semanticTagCount]; + if (semanticTags == nullptr) + { + CleanUp(endpointId); + return ModeOptionsProvider(nullptr, nullptr); + } + for (auto stIndex = 0; stIndex < semanticTagCount; stIndex++) + { + + uint32_t semanticTagValue = 0; + uint32_t semanticTagMfgCode = 0; + SemanticTag tag; + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagValue(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stValueKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stValueKey, semanticTagValue) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + memset(keyBuf, 0, sizeof(char) * ESP32Config::kMaxConfigKeyNameLength); + VerifyOrReturnValue(ESP32Config::KeyAllocator::SemanticTagMfgCode(keyBuf, sizeof(keyBuf), endpointId, index, stIndex) == + CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + ESP32Config::Key stMfgCodeKey(ESP32Config::kConfigNamespace_ChipFactory, keyBuf); + VerifyOrReturnValue(ESP32Config::ReadConfigValue(stMfgCodeKey, semanticTagMfgCode) == CHIP_NO_ERROR, + ModeOptionsProvider(nullptr, nullptr), CleanUp(endpointId)); + + tag.value = static_cast(semanticTagValue); + tag.mfgCode = static_cast(semanticTagMfgCode); + semanticTags[stIndex] = tag; + } + + option.label = chip::CharSpan::fromCharString(modeLabel); + option.mode = static_cast(supportedModeMode); + option.semanticTags = DataModel::List(semanticTags, semanticTagCount); + + modeOptionStructList[index] = option; + } + + return ModeOptionsProvider(modeOptionStructList, modeOptionStructList + supportedModeCount); +} + +Status StaticSupportedModesManager::getModeOptionByMode(unsigned short endpointId, unsigned char mode, + const ModeOptionStructType ** dataPtr) const +{ + auto modeOptionsProvider = this->getModeOptionsProvider(endpointId); + if (modeOptionsProvider.begin() == nullptr) + { + return Status::UnsupportedCluster; + } + auto * begin = modeOptionsProvider.begin(); + auto * end = modeOptionsProvider.end(); + + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + if (modeOption.mode == mode) + { + *dataPtr = &modeOption; + return Status::Success; + } + } + emberAfPrintln(EMBER_AF_PRINT_DEBUG, "Cannot find the mode %u", mode); + return Status::InvalidCommand; +} + +const ModeSelect::SupportedModesManager * ModeSelect::getSupportedModesManager() +{ + return &StaticSupportedModesManager::instance; +} + +void StaticSupportedModesManager::FreeSupportedModes(EndpointId endpointId) const +{ + if (epModeOptionsProviderList[endpointId].begin() != nullptr) + { + auto * begin = epModeOptionsProviderList[endpointId].begin(); + auto * end = epModeOptionsProviderList[endpointId].end(); + for (auto * it = begin; it != end; ++it) + { + auto & modeOption = *it; + delete[] modeOption.label.data(); + delete[] modeOption.semanticTags.data(); + } + delete[] begin; + } + epModeOptionsProviderList[endpointId] = ModeOptionsProvider(); +} + +void StaticSupportedModesManager::CleanUp(EndpointId endpointId) const +{ + ChipLogError(Zcl, "Supported mode data is in incorrect format"); + FreeSupportedModes(endpointId); +} diff --git a/examples/platform/esp32/mode-support/static-supported-modes-manager.h b/examples/platform/esp32/mode-support/static-supported-modes-manager.h new file mode 100644 index 00000000000000..689c9d059f4ab7 --- /dev/null +++ b/examples/platform/esp32/mode-support/static-supported-modes-manager.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2023 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 + +namespace chip { +namespace app { +namespace Clusters { +namespace ModeSelect { + +class StaticSupportedModesManager : public chip::app::Clusters::ModeSelect::SupportedModesManager +{ +private: + using ModeOptionStructType = Structs::ModeOptionStruct::Type; + using SemanticTag = Structs::SemanticTagStruct::Type; + + static ModeOptionsProvider epModeOptionsProviderList[FIXED_ENDPOINT_COUNT]; + + void InitEndpointArray(); + + void FreeSupportedModes(EndpointId endpointId) const; + +public: + static const StaticSupportedModesManager instance; + + SupportedModesManager::ModeOptionsProvider getModeOptionsProvider(EndpointId endpointId) const override; + + Protocols::InteractionModel::Status getModeOptionByMode(EndpointId endpointId, uint8_t mode, + const ModeOptionStructType ** dataPtr) const override; + + void CleanUp(EndpointId endpointId) const; + + StaticSupportedModesManager() { InitEndpointArray(); } + + ~StaticSupportedModesManager() + { + for (int i = 0; i < FIXED_ENDPOINT_COUNT; i++) + { + FreeSupportedModes(i); + } + } + + static inline const StaticSupportedModesManager & getStaticSupportedModesManagerInstance() { return instance; } +}; + +const SupportedModesManager * getSupportedModesManager(); + +} // namespace ModeSelect +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/platform/silabs/efr32/display/lcd.cpp b/examples/platform/silabs/efr32/display/lcd.cpp index 37ccb0dedbb1d5..561c02451686ee 100644 --- a/examples/platform/silabs/efr32/display/lcd.cpp +++ b/examples/platform/silabs/efr32/display/lcd.cpp @@ -71,12 +71,6 @@ CHIP_ERROR SilabsLCD::Init(uint8_t * name, bool initialState) err = CHIP_ERROR_INTERNAL; } -#if (defined(EFR32MG24) && defined(WF200_WIFI)) - if (pr_type != LCD) - { - pr_type = LCD; - } -#endif /* Initialize the DMD module for the DISPLAY device driver. */ status = DMD_init(0); if (DMD_OK != status) diff --git a/examples/platform/silabs/efr32/spi_multiplex.c b/examples/platform/silabs/efr32/spi_multiplex.c index 137c3973aa846e..6b8d6539d760c5 100644 --- a/examples/platform/silabs/efr32/spi_multiplex.c +++ b/examples/platform/silabs/efr32/spi_multiplex.c @@ -38,6 +38,11 @@ *****************************************************************************/ void spi_drv_reinit(uint32_t baudrate) { + if (USART_BaudrateGet(USART0) == baudrate) + { + // USART synced to baudrate already + return; + } // USART is used in MG24 + WF200 combination USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT; usartInit.msbf = true; @@ -50,29 +55,6 @@ void spi_drv_reinit(uint32_t baudrate) USART_InitSync(USART0, &usartInit); } -/**************************************************************************** - * @fn void set_spi_baudrate() - * @brief - * Setting the appropriate SPI baudrate - * @param[in] None - * @return returns void - *****************************************************************************/ -void set_spi_baudrate(peripheraltype_t pr_type) -{ - if (pr_type == LCD) - { - spi_drv_reinit(LCD_BIT_RATE); - } - else if (pr_type == EXP_HDR) - { - spi_drv_reinit(EXP_HDR_BIT_RATE); - } - else if (pr_type == EXT_SPIFLASH) - { - spi_drv_reinit(SPI_FLASH_BIT_RATE); - } -} - /**************************************************************************** * @fn void spiflash_cs_assert() * @brief @@ -110,14 +92,10 @@ void pre_bootloader_spi_transfer(void) { return; } - /* - * CS for Expansion header controlled within GSDK, - * however we need to ensure CS for Expansion header is High/disabled before use of EXT SPI Flash - */ - sl_wfx_host_spi_cs_deassert(); /* * Assert CS pin for EXT SPI Flash */ + spi_drv_reinit(SL_BIT_RATE_SPI_FLASH); spiflash_cs_assert(); } @@ -150,11 +128,7 @@ void pre_lcd_spi_transfer(void) { return; } - if (pr_type != LCD) - { - pr_type = LCD; - set_spi_baudrate(pr_type); - } + spi_drv_reinit(SL_BIT_RATE_LCD); /*LCD CS is handled as part of LCD gsdk*/ } @@ -208,7 +182,6 @@ void post_uart_transfer(void) return; } GPIO_PinModeSet(gpioPortA, 8, gpioModeInputPull, 1); - set_spi_baudrate(EXP_HDR); xSemaphoreGive(spi_sem_sync_hdl); sl_wfx_host_enable_platform_interrupt(); sl_wfx_enable_irq(); diff --git a/examples/platform/silabs/efr32/spi_multiplex.h b/examples/platform/silabs/efr32/spi_multiplex.h index 865e93ff4d8b36..29835962a4dd85 100644 --- a/examples/platform/silabs/efr32/spi_multiplex.h +++ b/examples/platform/silabs/efr32/spi_multiplex.h @@ -25,23 +25,26 @@ extern "C" { #include "sl_mx25_flash_shutdown_usart_config.h" #include "sl_spidrv_exp_config.h" #include "sl_wfx_host_api.h" +#include "spidrv.h" -#define LCD_BIT_RATE 1100000 -#define EXP_HDR_BIT_RATE 16000000 -#define SPI_FLASH_BIT_RATE 16000000 - -typedef enum PERIPHERAL_TYPE -{ - EXP_HDR = 0, - LCD, - EXT_SPIFLASH, -} peripheraltype_t; +#define SL_BIT_RATE_LCD 1100000 +#define SL_BIT_RATE_EXP_HDR 16000000 +#define SL_BIT_RATE_SPI_FLASH 16000000 +#define SL_BIT_RATE_UART_CONSOLE 16000000 extern SemaphoreHandle_t spi_sem_sync_hdl; -extern peripheraltype_t pr_type; + +#ifdef RS911X_WIFI +extern SPIDRV_Handle_t sl_spidrv_eusart_exp_handle; +#define SL_SPIDRV_HANDLE sl_spidrv_eusart_exp_handle +#endif + +#ifdef WF200_WIFI +extern SPIDRV_Handle_t sl_spidrv_exp_handle; +#define SL_SPIDRV_HANDLE sl_spidrv_exp_handle +#endif void spi_drv_reinit(uint32_t); -void set_spi_baudrate(peripheraltype_t); void spiflash_cs_assert(void); void spiflash_cs_deassert(void); diff --git a/examples/platform/silabs/efr32/wf200/efr_spi.c b/examples/platform/silabs/efr32/wf200/efr_spi.c index 7422ec686f0b9d..927b9a5fb892fa 100644 --- a/examples/platform/silabs/efr32/wf200/efr_spi.c +++ b/examples/platform/silabs/efr32/wf200/efr_spi.c @@ -49,13 +49,11 @@ #include "sl_power_manager.h" #endif -#if defined(EFR32MG24) +#if SL_WIFI #include "spi_multiplex.h" StaticSemaphore_t spi_sem_peripharal; SemaphoreHandle_t spi_sem_sync_hdl; -peripheraltype_t pr_type = EXP_HDR; #endif -extern SPIDRV_Handle_t sl_spidrv_exp_handle; #define USART SL_WFX_HOST_PINOUT_SPI_PERIPHERAL @@ -90,8 +88,8 @@ sl_status_t sl_wfx_host_init_bus(void) spi_enabled = true; /* Assign allocated DMA channel */ - tx_dma_channel = sl_spidrv_exp_handle->txDMACh; - rx_dma_channel = sl_spidrv_exp_handle->rxDMACh; + tx_dma_channel = SL_SPIDRV_HANDLE->txDMACh; + rx_dma_channel = SL_SPIDRV_HANDLE->rxDMACh; /* * Route EUSART1 MOSI, MISO, and SCLK to the specified pins. CS is @@ -116,7 +114,7 @@ sl_status_t sl_wfx_host_init_bus(void) #if defined(EFR32MG24) spi_sem_sync_hdl = xSemaphoreCreateBinaryStatic(&spi_sem_peripharal); xSemaphoreGive(spi_sem_sync_hdl); -#endif +#endif /* EFR32MG24 */ return SL_STATUS_OK; } @@ -130,6 +128,7 @@ sl_status_t sl_wfx_host_init_bus(void) sl_status_t sl_wfx_host_deinit_bus(void) { vSemaphoreDelete(spi_sem); + vSemaphoreDelete(spi_sem_sync_hdl); // Stop DMAs. DMADRV_StopTransfer(rx_dma_channel); DMADRV_StopTransfer(tx_dma_channel); @@ -149,6 +148,12 @@ sl_status_t sl_wfx_host_deinit_bus(void) *****************************************************************************/ sl_status_t sl_wfx_host_spi_cs_assert() { + configASSERT(spi_sem_sync_hdl); + if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE) + { + return SL_STATUS_TIMEOUT; + } + spi_drv_reinit(SL_BIT_RATE_EXP_HDR); GPIO_PinOutClear(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN); return SL_STATUS_OK; } @@ -163,6 +168,7 @@ sl_status_t sl_wfx_host_spi_cs_assert() sl_status_t sl_wfx_host_spi_cs_deassert() { GPIO_PinOutSet(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN); + xSemaphoreGive(spi_sem_sync_hdl); return SL_STATUS_OK; } @@ -258,19 +264,6 @@ void transmitDMA(uint8_t * buffer, uint16_t buffer_length) sl_status_t sl_wfx_host_spi_transfer_no_cs_assert(sl_wfx_host_bus_transfer_type_t type, uint8_t * header, uint16_t header_length, uint8_t * buffer, uint16_t buffer_length) { - sl_status_t result = SL_STATUS_FAIL; -#if defined(EFR32MG24) - if (pr_type != EXP_HDR) - { - pr_type = EXP_HDR; - set_spi_baudrate(pr_type); - } - if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE) - { - return SL_STATUS_TIMEOUT; - } - sl_wfx_host_spi_cs_assert(); -#endif const bool is_read = (type == SL_WFX_BUS_READ); while (!(MY_USART->STATUS & USART_STATUS_TXBL)) @@ -298,34 +291,29 @@ sl_status_t sl_wfx_host_spi_transfer_no_cs_assert(sl_wfx_host_bus_transfer_type_ if (buffer_length > 0) { MY_USART->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; - if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) + // Reset the semaphore + configASSERT(spi_sem); + if (xSemaphoreTake(spi_sem, portMAX_DELAY) != pdTRUE) { - if (is_read) - { - receiveDMA(buffer, buffer_length); - result = SL_STATUS_OK; - } - else - { - transmitDMA(buffer, buffer_length); - result = SL_STATUS_OK; - } + return SL_STATUS_TIMEOUT; + } - if (xSemaphoreTake(spi_sem, portMAX_DELAY) == pdTRUE) - { - xSemaphoreGive(spi_sem); - } + if (is_read) + { + receiveDMA(buffer, buffer_length); } else { - result = SL_STATUS_TIMEOUT; + transmitDMA(buffer, buffer_length); + } + // wait for dma_complete by using the same spi_semaphore + if (xSemaphoreTake(spi_sem, portMAX_DELAY) != pdTRUE) + { + return SL_STATUS_TIMEOUT; } + xSemaphoreGive(spi_sem); } -#if defined(EFR32MG24) - sl_wfx_host_spi_cs_deassert(); - xSemaphoreGive(spi_sem_sync_hdl); -#endif - return result; + return SL_STATUS_OK; } /**************************************************************************** diff --git a/scripts/tools/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index fac1c274e70a67..f5744720c6fc6c 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -226,6 +226,32 @@ def get_fixed_label_dict(fixed_labels): return fl_dict +# get_supported_modes_dict() converts the list of strings to per endpoint dictionaries. +# example input : ['0/label1/1/"1\0x8000, 2\0x8000", 1/label2/1/"1\0x8000, 2\0x8000"'] +# example outout : {'1': [{'Label': 'label1', 'Mode': 0, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}, {'Label': 'label2', 'Mode': 1, 'Semantic_Tag': [{'value': 1, 'mfgCode': 32768}, {'value': 2, 'mfgCode': 32768}]}]} + + +def get_supported_modes_dict(supported_modes): + output_dict = {} + + for mode_str in supported_modes: + mode_label_strs = mode_str.split('/') + mode = mode_label_strs[0] + label = mode_label_strs[1] + ep = mode_label_strs[2] + + semantic_tag_strs = mode_label_strs[3].split(', ') + semantic_tags = [{"value": int(v.split('\\')[0]), "mfgCode": int(v.split('\\')[1], 16)} for v in semantic_tag_strs] + + mode_dict = {"Label": label, "Mode": int(mode), "Semantic_Tag": semantic_tags} + + if ep in output_dict: + output_dict[ep].append(mode_dict) + else: + output_dict[ep] = [mode_dict] + + return output_dict + def check_str_range(s, min_len, max_len, name): if s and ((len(s) < min_len) or (len(s) > max_len)): @@ -358,6 +384,60 @@ def populate_factory_data(args, spake2p_params): FACTORY_DATA.update({'fl-k/{:x}/{:x}'.format(int(key), i): _label_key}) FACTORY_DATA.update({'fl-v/{:x}/{:x}'.format(int(key), i): _label_value}) + # SupportedModes are stored as multiple entries + # - sm-sz/ : number of supported modes for the endpoint + # - sm-label// : supported modes label key for the endpoint and index + # - sm-mode// : supported modes mode key for the endpoint and index + # - sm-st-sz// : supported modes SemanticTag key for the endpoint and index + # - st-v/// : semantic tag value key for the endpoint and index and ind + # - st-mfg/// : semantic tag mfg code key for the endpoint and index and ind + if (args.supported_modes is not None): + dictionary = get_supported_modes_dict(args.supported_modes) + for ep in dictionary.keys(): + _sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(dictionary[ep]) + } + FACTORY_DATA.update({'sm-sz/{:x}'.format(int(ep)): _sz}) + for i in range(len(dictionary[ep])): + item = dictionary[ep][i] + _label = { + 'type': 'data', + 'encoding': 'string', + 'value': item["Label"] + } + _mode = { + 'type': 'data', + 'encoding': 'u32', + 'value': item["Mode"] + } + _st_sz = { + 'type': 'data', + 'encoding': 'u32', + 'value': len(item["Semantic_Tag"]) + } + FACTORY_DATA.update({'sm-label/{:x}/{:x}'.format(int(ep), i): _label}) + FACTORY_DATA.update({'sm-mode/{:x}/{:x}'.format(int(ep), i): _mode}) + FACTORY_DATA.update({'sm-st-sz/{:x}/{:x}'.format(int(ep), i): _st_sz}) + + for j in range(len(item["Semantic_Tag"])): + entry = item["Semantic_Tag"][j] + + _value = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["value"] + } + _mfg_code = { + 'type': 'data', + 'encoding': 'u32', + 'value': entry["mfgCode"] + } + + FACTORY_DATA.update({'st-v/{:x}/{:x}/{:x}'.format(int(ep), i, j): _value}) + FACTORY_DATA.update({'st-mfg/{:x}/{:x}/{:x}'.format(int(ep), i, j): _mfg_code}) + def gen_raw_ec_keypair_from_der(key_file, pubkey_raw_file, privkey_raw_file): with open(key_file, 'rb') as f: @@ -467,6 +547,8 @@ def any_base_int(s): return int(s, 0) parser.add_argument('--locales', nargs='+', help='List of supported locales, Language Tag as defined by BCP47, eg. en-US en-GB') parser.add_argument('--fixed-labels', nargs='+', help='List of fixed labels, eg: "0/orientation/up" "1/orientation/down" "2/orientation/down"') + parser.add_argument('--supported-modes', type=str, nargs='+', required=False, + help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') parser.add_argument('-s', '--size', type=any_base_int, default=0x6000, help='The size of the partition.bin, default: 0x6000') diff --git a/src/app/clusters/mode-select-server/supported-modes-manager.h b/src/app/clusters/mode-select-server/supported-modes-manager.h index 497a604497200a..4a6ccd20c5f60a 100644 --- a/src/app/clusters/mode-select-server/supported-modes-manager.h +++ b/src/app/clusters/mode-select-server/supported-modes-manager.h @@ -20,9 +20,6 @@ #include #include -#include -#include -#include #include namespace chip { @@ -56,6 +53,8 @@ class SupportedModesManager */ inline pointer end() const { return mEnd; } + ModeOptionsProvider() : mBegin(nullptr), mEnd(nullptr) {} + ModeOptionsProvider(const pointer aBegin, const pointer aEnd) : mBegin(aBegin), mEnd(aEnd) {} pointer mBegin; diff --git a/src/platform/ESP32/ESP32Config.h b/src/platform/ESP32/ESP32Config.h index c85303c2197555..e07d98eba27594 100644 --- a/src/platform/ESP32/ESP32Config.h +++ b/src/platform/ESP32/ESP32Config.h @@ -180,6 +180,39 @@ class ESP32Config::KeyAllocator VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); return snprintf(key, size, "fl-v/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; } + + // Supported modes + + static CHIP_ERROR SupportedModesCount(char * key, size_t size, uint16_t endpoint) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-sz/%x", endpoint) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SupportedModesLabel(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-label/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SupportedModesValue(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-mode/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagsCount(char * key, size_t size, uint16_t endpoint, uint16_t index) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "sm-st-sz/%x/%x", endpoint, index) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagValue(char * key, size_t size, uint16_t endpoint, uint16_t index, uint16_t ind) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "st-v/%x/%x/%x", endpoint, index, ind) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } + static CHIP_ERROR SemanticTagMfgCode(char * key, size_t size, uint16_t endpoint, uint16_t index, uint16_t ind) + { + VerifyOrReturnError(key, CHIP_ERROR_INVALID_ARGUMENT); + return snprintf(key, size, "st-mfg/%x/%x/%x", endpoint, index, ind) > 0 ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + } }; } // namespace Internal