From c038765b7918c9674217ce60c409891b7fba8fc9 Mon Sep 17 00:00:00 2001 From: Haiwen Xia Date: Wed, 26 Nov 2025 13:26:01 +0800 Subject: [PATCH 01/54] telink: tl3238x: add new soc. - add tl3238x into matter. Signed-off-by: Haiwen Xia --- config/telink/chip-module/Kconfig.defaults | 36 ++++++------ .../telink/project_include/OpenThreadConfig.h | 4 +- scripts/build/build/targets.py | 3 + scripts/build/builders/telink.py | 9 +++ .../build/testdata/all_targets_linux_x64.txt | 2 +- .../telink/CHIPDevicePlatformConfig.h | 58 +++++++++---------- src/platform/telink/CHIPPlatformConfig.h | 6 +- src/platform/telink/SystemPlatformConfig.h | 7 ++- 8 files changed, 69 insertions(+), 56 deletions(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index 2ebfd483d0f1..a6ba7d85b554 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -69,17 +69,17 @@ config POSIX_MAX_FDS # Application stack size config MAIN_STACK_SIZE default 4864 if SOC_RISCV_TELINK_W91 - default 3240 if PM || SOC_RISCV_TELINK_TL321X + default 3240 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 4096 config INIT_STACKS default y config IDLE_STACK_SIZE - default 560 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 560 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 config ISR_STACK_SIZE - default 800 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 800 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 config SYSTEM_WORKQUEUE_STACK_SIZE default 664 if PM && !SOC_RISCV_TELINK_W91 @@ -89,7 +89,7 @@ config HEAP_MEM_POOL_SIZE default 1280 config COMMON_LIBC_MALLOC_ARENA_SIZE - default 19000 if SOC_RISCV_TELINK_TL321X && !ZEPHYR_VERSION_3_3 + default 19000 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X && !ZEPHYR_VERSION_3_3 default 29448 if SOC_RISCV_TELINK_W91 default 20716 @@ -103,19 +103,19 @@ config NET_IF_MCAST_IPV6_ADDR_COUNT # Network buffers config NET_PKT_RX_COUNT - default 4 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 4 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 default 8 config NET_PKT_TX_COUNT - default 4 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 4 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 default 8 config NET_BUF_RX_COUNT - default 12 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 12 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 default 32 config NET_BUF_TX_COUNT - default 12 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_W91 + default 12 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 default 32 config GPIO @@ -144,15 +144,15 @@ config BT_MAX_CONN default 1 config BT_L2CAP_TX_MTU - default 103 if SOC_RISCV_TELINK_TL321X + default 103 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 247 config BT_BUF_ACL_RX_SIZE - default 107 if SOC_RISCV_TELINK_TL321X + default 107 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 251 config BT_BUF_ACL_TX_SIZE - default 107 if SOC_RISCV_TELINK_TL321X + default 107 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 251 config BT_BUF_EVT_RX_COUNT @@ -214,12 +214,12 @@ config PWM endif -if BOARD_TL7218X_RETENTION || BOARD_TL3218X_RETENTION || BOARD_TL3218X +if BOARD_TL7218X_RETENTION || BOARD_TL3218X_RETENTION || BOARD_TL3218X || BOARD_TL3238X_RETENTION || BOARD_TL3238X config SOC_SERIES_RISCV_TELINK_TLX_NON_RETENTION_RAM_CODE default n if PM config TELINK_TLX_MATTER_RETENTION_LAYOUT - default y if PM || BOARD_TL3218X + default y if PM || BOARD_TL3218X || BOARD_TL3238X config PWM default n if PM @@ -228,7 +228,7 @@ endif # Board non-retention config if BOARD_TLSR9118BDK40D || BOARD_TLSR9118BDK40D_V1 || \ - BOARD_TLSR9528A || BOARD_TLSR9518ADK80D || BOARD_TL3218X || BOARD_TL7218X + BOARD_TLSR9528A || BOARD_TLSR9518ADK80D || BOARD_TL3218X || BOARD_TL3238X || BOARD_TL7218X config PWM default y endif @@ -268,7 +268,7 @@ config NVS_LOOKUP_CACHE default y config NVS_LOOKUP_CACHE_SIZE - default 400 if SOC_RISCV_TELINK_TL321X + default 400 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 2048 if !PM || SOC_RISCV_TELINK_W91 # Set multiplicator of Name Value Storage (NVS) as 1 to reach NVS sector size 4KB @@ -321,7 +321,7 @@ config IEEE802154_TLX_OPTIMIZATION Improve RF performance in IEEE 802.15.4 communication on TLX SoCs. config OPENTHREAD_THREAD_STACK_SIZE - default 2400 if PM || SOC_RISCV_TELINK_TL321X + default 2400 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X config OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE default 440 if PM @@ -345,11 +345,11 @@ endif # NET_L2_OPENTHREAD config NET_TX_STACK_SIZE default 1200 if SOC_RISCV_TELINK_W91 - default 600 if PM || SOC_RISCV_TELINK_TL321X + default 600 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X config NET_RX_STACK_SIZE default 2048 if SOC_RISCV_TELINK_W91 - default 664 if PM || SOC_RISCV_TELINK_TL321X + default 664 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X # Disable certain parts of Zephyr IPv6 stack config NET_IPV6_NBR_CACHE diff --git a/examples/platform/telink/project_include/OpenThreadConfig.h b/examples/platform/telink/project_include/OpenThreadConfig.h index 0e23617e28e2..e34698f27717 100644 --- a/examples/platform/telink/project_include/OpenThreadConfig.h +++ b/examples/platform/telink/project_include/OpenThreadConfig.h @@ -27,13 +27,13 @@ /* Number of message buffers reduced to save RAM */ #undef OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS -#if CONFIG_PM || CONFIG_SOC_RISCV_TELINK_TL321X +#if CONFIG_PM || CONFIG_SOC_RISCV_TELINK_TL321X || CONFIG_SOC_RISCV_TELINK_TL323X #define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 22 #else #define OPENTHREAD_CONFIG_NUM_MESSAGE_BUFFERS 44 #endif -#if CONFIG_SOC_RISCV_TELINK_TL321X +#if CONFIG_SOC_RISCV_TELINK_TL321X || CONFIG_SOC_RISCV_TELINK_TL323X #undef OPENTHREAD_CONFIG_MLE_MAX_CHILDREN #define OPENTHREAD_CONFIG_MLE_MAX_CHILDREN 5 #endif diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index f11bdbe00357..5dea986983d5 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -774,6 +774,9 @@ def BuildTelinkTarget(): TargetPart('tl3218x', board=TelinkBoard.TL3218X), TargetPart('tl3218x_ml3m', board=TelinkBoard.TL3218X_ML3M), TargetPart('tl3218x_retention', board=TelinkBoard.TL3218X_RETENTION), + TargetPart('tl3238x', board=TelinkBoard.TL3238X), + TargetPart('tl3238x_ml3m', board=TelinkBoard.TL3238X_ML3M), + TargetPart('tl3238x_retention', board=TelinkBoard.TL3238X_RETENTION), TargetPart('tl7218x', board=TelinkBoard.TL7218X), TargetPart('tl7218x_ml7g', board=TelinkBoard.TL7218X_ML7G), TargetPart('tl7218x_ml7m', board=TelinkBoard.TL7218X_ML7M), diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index fa6bf58f43a7..f55fac704900 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -121,6 +121,9 @@ class TelinkBoard(Enum): TL3218X = auto() TL3218X_ML3M = auto() TL3218X_RETENTION = auto() + TL3238X = auto() + TL3238X_ML3M = auto() + TL3238X_RETENTION = auto() TL7218X = auto() TL7218X_ML7G = auto() TL7218X_ML7M = auto() @@ -141,6 +144,12 @@ def GnArgName(self): return 'tl3218x_ml3m' elif self == TelinkBoard.TL3218X_RETENTION: return 'tl3218x_retention' + elif self == TelinkBoard.TL3238X: + return 'tl3238x' + elif self == TelinkBoard.TL3238X_ML3M: + return 'tl3238x_ml3m' + elif self == TelinkBoard.TL3238X_RETENTION: + return 'tl3238x_retention' elif self == TelinkBoard.TL7218X: return 'tl7218x' elif self == TelinkBoard.TL7218X_ML7G: diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index bd1c6fe8c5e3..add7ccf9b02e 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -21,4 +21,4 @@ qpg-qpg6200-{light,light-switch,lock,persistent-storage,shell,thermostat}[-updat realtek-{rtl8777g,rtl87x2g}-{all-clusters,light-switch,lighting,lock,ota-requestor,thermostat,window} stm32-stm32wb5mm-dk-light tizen-{arm,arm64}-{all-clusters,chip-tool,light,tests}[-asan][-coverage][-no-ble][-no-thread][-no-wifi][-ubsan][-with-ui] -telink-{tl3218x,tl3218x_ml3m,tl3218x_retention,tl7218x,tl7218x_ml7g,tl7218x_ml7m,tl7218x_retention,tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-4mb][-compress-lzma][-dfu-smp][-factory-data][-mars][-ota][-precompiled-ot][-rpc][-shell][-tflm][-thread-analyzer][-usb] +telink-{tl3218x,tl3218x_ml3m,tl3218x_retention,tl3238x,tl3238x_ml3m,tl3238x_retention,tl7218x,tl7218x_ml7g,tl7218x_ml7m,tl7218x_retention,tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-4mb][-compress-lzma][-dfu-smp][-factory-data][-mars][-ota][-precompiled-ot][-rpc][-shell][-tflm][-thread-analyzer][-usb] diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 8229b781a22a..14adaf851f67 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -108,7 +108,8 @@ #define CHIP_DEVICE_CONFIG_ENABLE_ETHERNET 0 #endif // CHIP_DEVICE_CONFIG_ENABLE_ETHERNET -#if defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION) +#if defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_TL323X) || \ + defined(CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION) #define CHIP_DEVICE_CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE (256) #define CHIP_DEVICE_CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE (256) #define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (256) @@ -177,34 +178,33 @@ #define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ { \ 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ - 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ - 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ - 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ - 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ - 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ - 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ - 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ - 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ - 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ - 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ - 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ - 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ - 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ - 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ - 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ - 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ - 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ - 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ - 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ - 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ - 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ - 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ - 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ - 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ - 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ - 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ - 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ - 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, \ + 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x62, \ + 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, \ + 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, \ + 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, \ + 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, \ + 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, \ + 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, \ + 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, \ + 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, \ + 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, \ + 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, \ + 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, \ + 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, \ + 0x4b, 0x80, 0x05, 0x4c, 0x80, 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, \ + 0x05, 0x52, 0x80, 0x05, 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, \ + 0x80, 0x05, 0x59, 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, \ + 0x5f, 0x80, 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, \ + 0x13, 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, 0x01, \ + 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, 0xf5, 0x04, \ + 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0a, 0x06, 0x08, \ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, 0xd1, 0xf4, 0x7a, 0x7d, \ + 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, 0x89, 0xde, 0x31, 0x92, 0xe6, \ + 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, \ + 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, \ + 0x7c \ } #endif diff --git a/src/platform/telink/CHIPPlatformConfig.h b/src/platform/telink/CHIPPlatformConfig.h index 27b2104c2480..d2c126d69aad 100644 --- a/src/platform/telink/CHIPPlatformConfig.h +++ b/src/platform/telink/CHIPPlatformConfig.h @@ -62,7 +62,7 @@ #define CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS 1 #endif // CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS -#ifdef CONFIG_SOC_RISCV_TELINK_TL321X +#if defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_TL323X) #ifndef CHIP_CONFIG_MAX_GROUP_DATA_PEERS #define CHIP_CONFIG_MAX_GROUP_DATA_PEERS 5 @@ -72,9 +72,9 @@ #define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_ENTRIES_PER_FABRIC 4 #endif // CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_ENTRIES_PER_FABRIC -#endif // CONFIG_SOC_RISCV_TELINK_TL321X +#endif // defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_TL323X) -#if defined CONFIG_PM || defined CONFIG_SOC_RISCV_TELINK_TL321X +#if defined CONFIG_PM || defined CONFIG_SOC_RISCV_TELINK_TL321X || defined CONFIG_SOC_RISCV_TELINK_TL323X #ifndef CHIP_CONFIG_MAX_GROUP_DATA_PEERS #define CHIP_CONFIG_MAX_GROUP_DATA_PEERS 7 diff --git a/src/platform/telink/SystemPlatformConfig.h b/src/platform/telink/SystemPlatformConfig.h index d32c260f7e64..37a4bcc5ed3c 100644 --- a/src/platform/telink/SystemPlatformConfig.h +++ b/src/platform/telink/SystemPlatformConfig.h @@ -44,8 +44,8 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 #endif // CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS -#if defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION) || \ - defined(CONFIG_SOC_RISCV_TELINK_W91) +#if defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_TL323X) || \ + defined(CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION) || defined(CONFIG_SOC_RISCV_TELINK_W91) #define CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_HEAP 1 #define CHIP_SYSTEM_PACKETBUFFER_FROM_CHIP_POOL 0 #define CHIP_SYSTEM_CONFIG_POOL_USE_HEAP 1 @@ -56,7 +56,8 @@ struct ChipDeviceEvent; #define CHIP_SYSTEM_CONFIG_USE_SOCKETS 1 // Reduce packet buffer pool size (default 15) to reduce ram consumption -#if defined(CONFIG_PM) || defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_W91) +#if defined(CONFIG_PM) || defined(CONFIG_SOC_RISCV_TELINK_TL321X) || defined(CONFIG_SOC_RISCV_TELINK_TL323X) || \ + defined(CONFIG_SOC_RISCV_TELINK_W91) #define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 0 #else #define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 8 From 546850d34da243ed205fa80d4a87d90df6d1f2d4 Mon Sep 17 00:00:00 2001 From: Haiwen Xia Date: Fri, 28 Nov 2025 09:27:49 +0800 Subject: [PATCH 02/54] telink: tl3238x: adjust boot setting . - close bootstrap and bootvalitdate. - adjust rf settings. Signed-off-by: Haiwen Xia --- config/telink/app/bootloader.conf | 4 ++-- config/telink/app/bootloader_compress_lzma.conf | 2 +- config/telink/chip-module/Kconfig.defaults | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/config/telink/app/bootloader.conf b/config/telink/app/bootloader.conf index cdc60a11c7a8..a8c3c0c7d8b7 100644 --- a/config/telink/app/bootloader.conf +++ b/config/telink/app/bootloader.conf @@ -16,7 +16,7 @@ # Enable this option in case if restoring the slot0 partition is expected from slot1 # partition in case if slot0 is not bootable or damaged -CONFIG_BOOT_BOOTSTRAP=y +CONFIG_BOOT_BOOTSTRAP=n # Enable this option in case if SWAP_MOVE logic need to be used CONFIG_BOOT_SWAP_USING_MOVE=y @@ -27,7 +27,7 @@ CONFIG_BOOT_SWAP_USING_SCRATCH=n # Enable this option in case if the whole slot0 image need to be validated # With disabled option the only image magic is validated -CONFIG_BOOT_VALIDATE_SLOT0=y +CONFIG_BOOT_VALIDATE_SLOT0=n # Required for Zephyr 3.3 and replased with CONFIG_BOOT_MAX_IMG_SECTORS_AUTO in new versions # Maximum number of image sectors supported by the bootloader. diff --git a/config/telink/app/bootloader_compress_lzma.conf b/config/telink/app/bootloader_compress_lzma.conf index 6cab83229bae..4ee33768e7d6 100644 --- a/config/telink/app/bootloader_compress_lzma.conf +++ b/config/telink/app/bootloader_compress_lzma.conf @@ -20,7 +20,7 @@ CONFIG_BOOT_UPGRADE_ONLY=y # Enable this option in case if the whole slot0 image need to be validated # With disabled option the only image magic is validated -CONFIG_BOOT_VALIDATE_SLOT0=y +CONFIG_BOOT_VALIDATE_SLOT0=n # Required for Zephyr 3.3 and replased with CONFIG_BOOT_MAX_IMG_SECTORS_AUTO in new versions # Maximum number of image sectors supported by the bootloader. diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index a6ba7d85b554..efb66a8c4b5a 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -333,9 +333,10 @@ config OPENTHREAD_SLAAC config OPENTHREAD_MANUAL_START default y +# 6 is the max rf level by Vant config OPENTHREAD_DEFAULT_TX_POWER - default 3 if PM - default 9 + default 6 if PM + default 11 config OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS default 2 if PM From 65f4ef5ebc53a7eb2db8cf1be1fc41752c60b96a Mon Sep 17 00:00:00 2001 From: Haiwen Xia Date: Fri, 28 Nov 2025 10:34:36 +0800 Subject: [PATCH 03/54] telink: tl3238x: add partition and dual mode logic. - add 2m partition for customer. - setting different discriminator. - add dual mode logic. - enable ota. Signed-off-by: Haiwen Xia --- examples/light-switch-app/telink/prj.conf | 8 +- examples/lighting-app/telink/prj.conf | 8 +- .../telink/common/include/AppTaskCommon.h | 25 +++++++ .../telink/common/src/AppTaskCommon.cpp | 66 +++++++++++++++- src/platform/telink/tl3238x_2m_flash.overlay | 75 +++++++++++++++++++ 5 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 src/platform/telink/tl3238x_2m_flash.overlay diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index f8bea0d44ace..fc66da20caee 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -29,7 +29,7 @@ CONFIG_CHIP_DEVICE_PRODUCT_ID=32772 CONFIG_BT_DEVICE_NAME="TelinkSwitch" # Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n +CONFIG_CHIP_OTA_REQUESTOR=y CONFIG_CHIP_DFU_OVER_BT_SMP=n CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 @@ -42,6 +42,10 @@ CONFIG_CHIP_FACTORY_DATA=n CONFIG_CHIP_FACTORY_DATA_BUILD=n CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n - +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=y + +#compress ota +CONFIG_COMPRESS_LZMA=y +CONFIG_LZMA=y \ No newline at end of file diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 3f4310ffa05d..d4165606225a 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -29,7 +29,7 @@ CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 CONFIG_BT_DEVICE_NAME="TelinkLight" # Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n +CONFIG_CHIP_OTA_REQUESTOR=y CONFIG_CHIP_DFU_OVER_BT_SMP=n CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 @@ -49,6 +49,10 @@ CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n # Enable PWM CONFIG_PWM=y - +CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=n + +#compress ota +CONFIG_COMPRESS_LZMA=y +CONFIG_LZMA=y \ No newline at end of file diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index 1867423aecfa..db7d7c99b4cb 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -39,6 +39,31 @@ #include +#include +#include +#include + +#define OPCODE_FACTORY_RESET 0 +#define OPCODE_SWITCH_ZIGBEE 1 // include init state and matter paired state. +#define OPCODE_MATTER_PAIRED 2 + +#define DUAL_MODE_PARTITION dual_mode_partition +#define DUAL_MODE_PARTITION_DEVICE FIXED_PARTITION_DEVICE(DUAL_MODE_PARTITION) +#define DUAL_MODE_PARTITION_OFFSET FIXED_PARTITION_OFFSET(DUAL_MODE_PARTITION) +#define DUAL_MODE_PARTITION_SIZE FIXED_PARTITION_SIZE(DUAL_MODE_PARTITION) +// init mode will jump to matter +#define MODE_VAL_INIT 0xff + +// after matter paired , it will go to matter, only if trigger action. +#define MODE_VAL_MATTER_PAIR 0x55 +#define ACTION_SWITCH_ZIGBEE 0xaa + +// after zb paired , it will go to zb, only if trigger action. +#define MODE_VAL_ZB_PAIR 0xaa +#define ACTION_SWITCH_MATTER 0x55 + +void dual_mode_switch(uint32_t op); + using namespace ::chip; using namespace ::chip::app; using namespace ::chip::Credentials; diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 1c42944b609f..0f1ce3f386b3 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -88,6 +88,60 @@ bool sIsNetworkEnabled = false; bool sIsNetworkAttached = false; bool sHaveBLEConnections = false; +#include +#include +#include +#include + +#define OPCODE_FACTORY_RESET 0 +#define OPCODE_SWITCH_ZIGBEE 1 // include init state and matter paired state. +#define OPCODE_MATTER_PAIRED 2 + +#define DUAL_MODE_PARTITION dual_mode_partition +#define DUAL_MODE_PARTITION_DEVICE FIXED_PARTITION_DEVICE(DUAL_MODE_PARTITION) +#define DUAL_MODE_PARTITION_OFFSET FIXED_PARTITION_OFFSET(DUAL_MODE_PARTITION) +#define DUAL_MODE_PARTITION_SIZE FIXED_PARTITION_SIZE(DUAL_MODE_PARTITION) +// init mode will jump to matter +#define MODE_VAL_INIT 0xff + +// after matter paired , it will go to matter, only if trigger action. +#define MODE_VAL_MATTER_PAIR 0x55 +#define ACTION_SWITCH_ZIGBEE 0xaa + +// after zb paired , it will go to zb, only if trigger action. +#define MODE_VAL_ZB_PAIR 0xaa +#define ACTION_SWITCH_MATTER 0x55 +void dual_mode_switch(int32_t op) +{ + uint8_t boot_flag[2] = { 0xff, 0xff }; + const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; + + flash_read(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, boot_flag, 2); + + if (op == OPCODE_FACTORY_RESET) + { + boot_flag[0] = MODE_VAL_INIT; + boot_flag[1] = MODE_VAL_INIT; + } + else if (op == OPCODE_SWITCH_ZIGBEE) + { + boot_flag[1] = ACTION_SWITCH_ZIGBEE; + } + else if (op == OPCODE_MATTER_PAIRED) + { + boot_flag[0] = MODE_VAL_MATTER_PAIR; + boot_flag[1] = MODE_VAL_INIT; + } + flash_erase(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, 4096); + flash_write(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, boot_flag, sizeof(boot_flag)); + + // need to reboot ,switch to bootloader + if (op == OPCODE_SWITCH_ZIGBEE) + { + sys_reboot(SYS_REBOOT_WARM); + } +} + #if APP_SET_DEVICE_INFO_PROVIDER chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; #endif @@ -167,6 +221,12 @@ class AppFabricTableDelegate : public FabricTable::Delegate ChipLogProgress(DeviceLayer, "Rebooting board"); sys_reboot(SYS_REBOOT_WARM); } + else + { + ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); + chip::Server::GetInstance().ScheduleFactoryReset(); + dual_mode_switch(OPCODE_FACTORY_RESET); + } } } }; @@ -566,7 +626,7 @@ void AppTaskCommon::StartBleAdvButtonEventHandler(void) void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent) { LOG_INF("StartBleAdvHandler"); - + dual_mode_switch(OPCODE_SWITCH_ZIGBEE); // Disable manual Matter service BLE advertising after device provisioning. if (sIsNetworkProvisioned) { @@ -612,6 +672,7 @@ void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent) sFactoryResetCntr = 0; chip::Server::GetInstance().ScheduleFactoryReset(); + dual_mode_switch(OPCODE_FACTORY_RESET); } } @@ -792,6 +853,9 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* Server::GetInstance().GetFailSafeContext().ForceFailSafeTimerExpiry(); } break; + case DeviceEventType::kCommissioningComplete: + dual_mode_switch(OPCODE_MATTER_PAIRED); + break; #if CHIP_DEVICE_CONFIG_ENABLE_THREAD case DeviceEventType::kDnssdInitialized: #if CONFIG_CHIP_OTA_REQUESTOR diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay new file mode 100644 index 000000000000..058ff51894dc --- /dev/null +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -0,0 +1,75 @@ +&flash { + reg = <0x20000000 0x200000>; + + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +// reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x15000>; + }; +// currently the reset flash is 0x1e0000- 0x15000() = 0x1cb000 = 1836k (the total of slot0,and slot1) +// tralor = 20k +// slot0_fw = (1836-20)/1.6/4*4 = 1132 (suppose as LZMA:60%) +// slot0 area = 1132+20 = 1152(0x120000) + slot0_partition: partition@15000 { + label = "image-0"; + reg = <0x15000 0x120000>; // total slot0 is 1152k + }; +// add information , increase part for matter & zigbee +// suppose the matter application layer is 30k, zigbee is 60k +// currently , basic matter fw is 813k, zigbee is 140k , so just suppose matter is 916k, and zigbee is 216, reserve 20k for matter ota trailor + slot0_matter_partition: partition@16000 { + label = "image-0-matter"; + reg = <0x15000 0xe5000>; // suppose matter is 916k (0xe5000) + }; + slot0_zb_partition: partition@fa000 { + label = "image-0-zb"; + reg = <0xfa000 0x36000>; // suppose zigbee is 216k (0x36000) + }; + slot0_trailor_partition: partition@130000 { + label = "image-0-trailor"; + reg = <0x130000 0x5000>; // suppose trailor is 20k + }; +// the total fw area is 1836k, and slot0 cost 1152, so the value is 1836 - 1152 = 684k (0xac000) */ + slot1_partition: partition@135000 { + label = "image-1"; + reg = <0x135000 0xab000>; + }; + user_rfu_partition: partition@1e0000 { + label = "user_rfu"; + reg = <0x1e0000 0x4000>; + }; + storage_partition: partition@1e4000 { + label = "matter-nvs"; + reg = <0x1e4000 0x8000>; // matter nvs part , total is 32k. + }; + zigbee_nvs_partition: partition@1ec000 { + label = "zigbee-nvs"; + reg = <0x1ec000 0xc000>; // zigbee nvs part , total is 48k. + }; + secure_partition: partition@1f8000 { + label = "secure"; + reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + dual_mode_partition: partition@1fa000 { + label = "dual-mode"; + reg = <0x1fa000 0x2000>; // user:store the mode info and the key info part.same as public area for dual mode + }; + dac_keypair_partition: partition@1fc000 { + label = "dac-keypair"; + reg = <0x1fc000 0x1000>; // store dac and key pair. + }; + factory_partition: partition@1fd000 { + label = "factory-data"; + reg = <0x1fd000 0x1000>; // factory data info + }; + vendor_partition: partition@1fe000 { + label = "vendor-data"; + reg = <0x1fe000 0x2000>; // mac and rf info. + }; + }; +}; From 0b3a5263a6d4ee246b804d8496aea75040e92b1d Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Fri, 19 Dec 2025 09:06:14 +0800 Subject: [PATCH 04/54] telink: tl3238x: enlarge the ble thread stack. - after change the ble controller , the thread need to enlarge in pm mode. Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index efb66a8c4b5a..1e505dbde513 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -181,6 +181,7 @@ if SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX config TL_BLE_CTRL_THREAD_STACK_SIZE default 648 if ZEPHYR_VERSION_3_3 default 768 if SOC_RISCV_TELINK_TL721X + default 840 if SOC_RISCV_TELINK_TL323X && !PM default 712 config TL_BLE_CTRL_MASTER_MAX_NUM From 5f95409db7eebb34500aac55cfe2dde85acf4a49 Mon Sep 17 00:00:00 2001 From: Serhii Salamakha Date: Thu, 18 Dec 2025 20:52:44 +0200 Subject: [PATCH 05/54] [Telink] Add BLE layer re-initialization if BLE was previously shut down (#42451) --- src/platform/telink/BLEManagerImpl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 501264540a27..56c3c3add938 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -335,6 +335,12 @@ CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void) ThreadStackMgrImpl().SetRadioBlocked(true); #endif + if (!BleLayer::IsInitialized()) + { + // Re-initializing the BLE layer after shutdown + ReturnErrorOnFailure(BleLayer::Init(this, this, &DeviceLayer::SystemLayer())); + } + // Init BLE err = bt_enable(NULL); VerifyOrReturnError(err == 0, MapErrorZephyr(err)); From cb6a4aa663420ab27a00010f29d707ec14ee7da6 Mon Sep 17 00:00:00 2001 From: Dmytro Huz <75682372+interfer@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:04:33 +0200 Subject: [PATCH 06/54] [Telink] Add persistent subscriptions by default (#42452) * [Telink] set persistent subscriptions by default Now included to all Telink targets. Persists Matter subscriptions on the publisher node. This feature allows a Matter node to faster get back to the previous operation after it went offline, for example, due to a power outage. That is, the node can use the persisted subscription information to quickly re-establish the previous subscriptions instead of waiting for the subscriber node to realize that the publisher is alive again. * [Telink] added dependenant configs & Buteo condition Exclude persistent subscription for Buteo with retention due to footprint. Added dependencies for CHIPPlatformConfig.h * Restyled by whitespace --------- Co-authored-by: Restyled.io --- config/telink/chip-module/CMakeLists.txt | 1 + config/telink/chip-module/Kconfig | 43 ++++++++++++++++++++++++ src/platform/telink/CHIPPlatformConfig.h | 22 +++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 39365b220992..31bc9ab18545 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -114,6 +114,7 @@ matter_add_gn_arg_bool ("chip_enable_icd_server" CONFIG_CHIP_EN matter_add_gn_arg_bool ("chip_enable_factory_data" CONFIG_CHIP_FACTORY_DATA) matter_add_gn_arg_bool ("chip_mdns_minimal" CONFIG_WIFI_W91) matter_add_gn_arg_bool ("chip_mdns_platform" CONFIG_NET_L2_OPENTHREAD) +matter_add_gn_arg_bool ("chip_persist_subscriptions" CONFIG_CHIP_PERSISTENT_SUBSCRIPTIONS) if (CONFIG_CHIP_ENABLE_ICD_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_lit" CONFIG_CHIP_ICD_LIT_SUPPORT) diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 521689d534bc..41129298635a 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -278,6 +278,49 @@ config CHIP_USE_MARS_SENSOR depends on SOC_RISCV_TELINK_B9X && (BOARD_TLSR9518ADK80D || BOARD_TLSR9518ADK80D_RETENTION) default n +config CHIP_PERSISTENT_SUBSCRIPTIONS + default n if BOARD_TL3218X_RETENTION + default y + # selecting experimental for this feature since there is an issue with multiple controllers. + select EXPERIMENTAL + +if CHIP_PERSISTENT_SUBSCRIPTIONS + +config CHIP_MAX_FABRICS + int "Maximum number of Matter fabrics" + default 5 + help + The maximum number of Matter fabrics that device can be joined to. + +config CHIP_MAX_ACTIVE_CASE_CLIENTS + int "Maximum number of outgoing CASE sessions" + default CHIP_MAX_FABRICS + help + The maximum number of outgoing CASE sessions that can be simultaneously handled by the end device. + +config CHIP_MAX_ACTIVE_DEVICES + int "Maximum number of simultaneous connections over CASE" + default CHIP_MAX_FABRICS + help + The maximum number of devices to which the Server implementers will be able to + concurrently connect over CASE and interact with. + +config CHIP_SUBSCRIPTION_RESUMPTION_MIN_RETRY_INTERVAL + int "Minimum subscription resumption interval in seconds" + default 20 + depends on CHIP_PERSISTENT_SUBSCRIPTIONS + help + The minimum interval in seconds before resuming a subscription that timed out. + +config CHIP_SUBSCRIPTION_RESUMPTION_RETRY_MULTIPLIER + int "The multiplier for subscription resumption retry in seconds" + default 40 + depends on CHIP_PERSISTENT_SUBSCRIPTIONS + help + The multiplier per subscription resumption retry attempt that is multiplied by the index of Fibonacci sequence + and added to CHIP_SUBSCRIPTION_RESUMPTION_MIN_RETRY_INTERVAL to obtain final wait time for next retry. +endif + config TFLM_FEATURE bool "Enable the TFLM micro speech feature" default n diff --git a/src/platform/telink/CHIPPlatformConfig.h b/src/platform/telink/CHIPPlatformConfig.h index d2c126d69aad..421578b65917 100644 --- a/src/platform/telink/CHIPPlatformConfig.h +++ b/src/platform/telink/CHIPPlatformConfig.h @@ -111,8 +111,28 @@ #endif // CONFIG_PM || CONFIG_SOC_RISCV_TELINK_TL321X #ifndef CHIP_CONFIG_MAX_FABRICS +#ifdef CONFIG_CHIP_MAX_FABRICS +#define CHIP_CONFIG_MAX_FABRICS CONFIG_CHIP_MAX_FABRICS +#else #define CHIP_CONFIG_MAX_FABRICS 5 -#endif +#endif // CONFIG_CHIP_MAX_FABRICS +#endif // CHIP_CONFIG_MAX_FABRICS + +#ifdef CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS +#define CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS +#endif // CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS + +#if !defined(CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES) && defined(CONFIG_CHIP_MAX_ACTIVE_DEVICES) +#define CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES CONFIG_CHIP_MAX_ACTIVE_DEVICES +#endif // CHIP_CONFIG_DEVICE_MAX_ACTIVE_DEVICES + +#ifdef CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_MIN_RETRY_INTERVAL +#define CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_MIN_RETRY_INTERVAL_SECS CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_MIN_RETRY_INTERVAL +#endif // CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_MIN_RETRY_INTERVAL + +#ifdef CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_RETRY_MULTIPLIER +#define CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION_WAIT_TIME_MULTIPLIER_SECS CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_RETRY_MULTIPLIER +#endif // CONFIG_CHIP_SUBSCRIPTION_RESUMPTION_RETRY_MULTIPLIER #ifdef CONFIG_CHIP_LOG_SIZE_OPTIMIZATION // Disable some of the too detailed log modules to save flash From 7e61f49b1e4b05a73085362451908d63ce16ceb2 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 25 Dec 2025 13:10:39 +0800 Subject: [PATCH 07/54] telink: tl3238x: open ota and lzma for contact-sensor. - open ota and add lzma. Signed-off-by: haiwen.xia --- examples/contact-sensor-app/telink/prj.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index 7e6094d78e2c..5b7ce94f3253 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -29,7 +29,7 @@ CONFIG_CHIP_DEVICE_PRODUCT_ID=32774 CONFIG_BT_DEVICE_NAME="TelinkSensor" # Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n +CONFIG_CHIP_OTA_REQUESTOR=y CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 # Disable CHIP shell support @@ -42,3 +42,7 @@ CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n # Enable Power Management CONFIG_PM=y + +#compress ota +CONFIG_COMPRESS_LZMA=y +CONFIG_LZMA=y From 6bb3ce0a30c9f3b3313cb60e2d241850fb3d27a2 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 25 Dec 2025 13:11:48 +0800 Subject: [PATCH 08/54] telink: tl3238x: enlarge malloc. - enlarge heap size for tl3238x. Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index 1e505dbde513..4d5f377598ad 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -89,7 +89,7 @@ config HEAP_MEM_POOL_SIZE default 1280 config COMMON_LIBC_MALLOC_ARENA_SIZE - default 19000 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X && !ZEPHYR_VERSION_3_3 + default 19000 if SOC_RISCV_TELINK_TL321X && !ZEPHYR_VERSION_3_3 default 29448 if SOC_RISCV_TELINK_W91 default 20716 From 1195c99e7370b5ce60e370fcc721f51acbeef2aa Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Fri, 26 Dec 2025 11:07:15 +0800 Subject: [PATCH 09/54] telink: tl3238x: enlarge ble thread . - enlarge ble thread stack for jenkins alarm to 100%. Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index 4d5f377598ad..e78d77369f57 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -181,7 +181,7 @@ if SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX config TL_BLE_CTRL_THREAD_STACK_SIZE default 648 if ZEPHYR_VERSION_3_3 default 768 if SOC_RISCV_TELINK_TL721X - default 840 if SOC_RISCV_TELINK_TL323X && !PM + default 840 if SOC_RISCV_TELINK_TL323X default 712 config TL_BLE_CTRL_MASTER_MAX_NUM From ffdf490ce955eecc5fb9b921ab985a042874a906 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 6 Jan 2026 10:43:21 +0800 Subject: [PATCH 10/54] telink: tl3238x: adjust rf settings and clean code . - ajust the rf power to 3dbm. - add the extra code for tlx optimization. - add the demo setting for ICD MODE. Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 2 +- examples/light-switch-app/telink/prj.conf | 7 ++++++- .../GenericThreadStackManagerImpl_OpenThread.hpp | 13 +++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index e78d77369f57..ab4488e02099 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -336,7 +336,7 @@ config OPENTHREAD_MANUAL_START # 6 is the max rf level by Vant config OPENTHREAD_DEFAULT_TX_POWER - default 6 if PM + default 3 if PM default 11 config OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index fc66da20caee..55a0e92613ea 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -48,4 +48,9 @@ CONFIG_PM=y #compress ota CONFIG_COMPRESS_LZMA=y -CONFIG_LZMA=y \ No newline at end of file +CONFIG_LZMA=y + +#ICD SETTING INFO +#CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +#CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 +#CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 \ No newline at end of file diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index cca1dcd587f5..d7c5887f5ee7 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -65,6 +65,10 @@ extern "C" void otSysProcessDrivers(otInstance * aInstance); extern "C" void otAppCliInit(otInstance * aInstance); #endif +#if defined CONFIG_IEEE802154_TLX_OPTIMIZATION +bool isThreadCommissioned = false; +#endif /* CONFIG_IEEE802154_TLX_OPTIMIZATION */ + namespace chip { namespace DeviceLayer { namespace Internal { @@ -358,6 +362,15 @@ bool GenericThreadStackManagerImpl_OpenThread::_IsThreadAttached() curRole = otThreadGetDeviceRole(mOTInst); Impl()->UnlockThreadStack(); +#if defined CONFIG_IEEE802154_TLX_OPTIMIZATION + + if ((curRole != OT_DEVICE_ROLE_DISABLED && curRole != OT_DEVICE_ROLE_DETACHED)) + { + if (isThreadCommissioned == false) + isThreadCommissioned = true; + } +#endif /* CONFIG_IEEE802154_TLX_OPTIMIZATION */ + return (curRole != OT_DEVICE_ROLE_DISABLED && curRole != OT_DEVICE_ROLE_DETACHED); } From b992f92331bca066edf3c7922868b10cf3b173a0 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 7 Jan 2026 20:03:36 +0800 Subject: [PATCH 11/54] telink: tl3238x: adjust openthread queue . - after adjust the ot queue for ram section changes . Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index ab4488e02099..bee9d9491863 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -325,7 +325,7 @@ config OPENTHREAD_THREAD_STACK_SIZE default 2400 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X config OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE - default 440 if PM + default 608 if PM default 608 config OPENTHREAD_SLAAC From 4ee7b59ae0599397856d634198d8e14f87b629fb Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 8 Jan 2026 11:04:09 +0800 Subject: [PATCH 12/54] telink: tl3238x: clean code . - clean code for dumplicate partition . Signed-off-by: haiwen.xia --- src/platform/telink/tl3238x_2m_flash.overlay | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay index 058ff51894dc..9e9886e30976 100644 --- a/src/platform/telink/tl3238x_2m_flash.overlay +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -22,7 +22,7 @@ // add information , increase part for matter & zigbee // suppose the matter application layer is 30k, zigbee is 60k // currently , basic matter fw is 813k, zigbee is 140k , so just suppose matter is 916k, and zigbee is 216, reserve 20k for matter ota trailor - slot0_matter_partition: partition@16000 { + slot0_matter_partition: partition@15000_1 { label = "image-0-matter"; reg = <0x15000 0xe5000>; // suppose matter is 916k (0xe5000) }; From b0535dc038032707ccd5810efb1cd134dea85d64 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Fri, 9 Jan 2026 15:55:54 +0800 Subject: [PATCH 13/54] telink: tl3238x: add lowpower settings . - update ICD parameters for light-switch . Signed-off-by: haiwen.xia --- examples/light-switch-app/telink/prj.conf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 55a0e92613ea..897e102b468e 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -51,6 +51,7 @@ CONFIG_COMPRESS_LZMA=y CONFIG_LZMA=y #ICD SETTING INFO -#CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 -#CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 -#CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 \ No newline at end of file +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 +CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 +CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 \ No newline at end of file From 2deebc63b70d9134d7af86fa15697a14baba195a Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 13 Jan 2026 11:20:22 +0800 Subject: [PATCH 14/54] telink: tl3238x: add the config of dual mode . - select different dual mode ,if none means matter only mode . Signed-off-by: haiwen.xia --- config/telink/chip-module/CMakeLists.txt | 2 +- scripts/build/build/targets.py | 1 + scripts/build/builders/telink.py | 5 +++++ scripts/build/testdata/all_targets_linux_x64.txt | 2 +- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 31bc9ab18545..05a9679d3a53 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -185,7 +185,7 @@ if (CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_RISCV_TELINK_B9X OR CONFIG_SOC_RIS add_custom_target(build_mcuboot ALL COMMAND west build -b ${BASE_BOARD} -d build_mcuboot ${ZEPHYR_BASE}/../bootloader/mcuboot/boot/zephyr - -- -DOVERLAY_CONFIG=${GLOBAL_BOOT_CONF_OVERLAY_FILE} -DDTC_OVERLAY_FILE="${GLOBAL_BOOT_DTC_OVERLAY_FILE};${FLASH_DTC_OVERLAY_FILE};${USB_BOOT_DTC_OVERLAY_FILE};${MARS_BOOT_DTC_OVERLAY_FILE}" + -- -DCONFIG_DUAL_MODE=${CONFIG_DUAL_MODE} -DOVERLAY_CONFIG=${GLOBAL_BOOT_CONF_OVERLAY_FILE} -DDTC_OVERLAY_FILE="${GLOBAL_BOOT_DTC_OVERLAY_FILE};${FLASH_DTC_OVERLAY_FILE};${USB_BOOT_DTC_OVERLAY_FILE};${MARS_BOOT_DTC_OVERLAY_FILE}" COMMAND cp ${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin ${PROJECT_BINARY_DIR}/mcuboot.bin ) diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 5dea986983d5..d547ea6e3c3f 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -815,6 +815,7 @@ def BuildTelinkTarget(): target.AppendModifier('thread-analyzer', thread_analyzer_config=True) target.AppendModifier('precompiled-ot', precompiled_ot_config=True) target.AppendModifier('tflm', tflm_config=True) + target.AppendModifier('dual-mode', dual_mode_config=0) return target diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index f55fac704900..752307582510 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -181,6 +181,7 @@ def __init__(self, thread_analyzer_config: bool = False, precompiled_ot_config: bool = False, tflm_config: bool = False, + dual_mode_config: int = 0, ): super(TelinkBuilder, self).__init__(root, runner) self.app = app @@ -197,6 +198,7 @@ def __init__(self, self.thread_analyzer_config = thread_analyzer_config self.precompiled_ot_config = precompiled_ot_config self.tflm_config = tflm_config + self.dual_mode_config = dual_mode_config def get_cmd_prefixes(self): if not self._runner.dry_run: @@ -253,6 +255,9 @@ def generate(self): if self.tflm_config: flags.append("-DCONFIG_TFLM_FEATURE=y") + if self.dual_mode_config: + flags.append("-DCONFIG_DUAL_MODE=0") + if self.options.pregen_dir: flags.append(f"-DCHIP_CODEGEN_PREGEN_DIR={shlex.quote(self.options.pregen_dir)}") diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index add7ccf9b02e..bc6df68027f0 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -21,4 +21,4 @@ qpg-qpg6200-{light,light-switch,lock,persistent-storage,shell,thermostat}[-updat realtek-{rtl8777g,rtl87x2g}-{all-clusters,light-switch,lighting,lock,ota-requestor,thermostat,window} stm32-stm32wb5mm-dk-light tizen-{arm,arm64}-{all-clusters,chip-tool,light,tests}[-asan][-coverage][-no-ble][-no-thread][-no-wifi][-ubsan][-with-ui] -telink-{tl3218x,tl3218x_ml3m,tl3218x_retention,tl3238x,tl3238x_ml3m,tl3238x_retention,tl7218x,tl7218x_ml7g,tl7218x_ml7m,tl7218x_retention,tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-4mb][-compress-lzma][-dfu-smp][-factory-data][-mars][-ota][-precompiled-ot][-rpc][-shell][-tflm][-thread-analyzer][-usb] +telink-{tl3218x,tl3218x_ml3m,tl3218x_retention,tl3238x,tl3238x_ml3m,tl3238x_retention,tl7218x,tl7218x_ml7g,tl7218x_ml7m,tl7218x_retention,tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-4mb][-compress-lzma][-dfu-smp][-dual-mode][-factory-data][-mars][-ota][-precompiled-ot][-rpc][-shell][-tflm][-thread-analyzer][-usb] From e098525b62c1c06e14a0024919024164a716d20f Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 13 Jan 2026 11:22:09 +0800 Subject: [PATCH 15/54] telink: tl3238x: add applicaton for switch . - add switch setting and code logic . Signed-off-by: haiwen.xia --- examples/light-switch-app/telink/prj.conf | 8 +++++++- examples/lighting-app/telink/prj.conf | 8 +++++++- examples/platform/telink/common/src/AppTaskCommon.cpp | 10 ++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 897e102b468e..08f52e3a8e96 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -54,4 +54,10 @@ CONFIG_LZMA=y CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 -CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 \ No newline at end of file +CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 + +#matter switch mode +# config NORMAL_MODE 0 independent matter mode +# ACTION_DUAL_MODE 1 matter action switch mode ,such as by button +# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. +CONFIG_DUAL_MODE=0 \ No newline at end of file diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index d4165606225a..4d55b053374e 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -55,4 +55,10 @@ CONFIG_PM=n #compress ota CONFIG_COMPRESS_LZMA=y -CONFIG_LZMA=y \ No newline at end of file +CONFIG_LZMA=y + +# matter switch mode +# config NORMAL_MODE 0 independent matter mode +# ACTION_DUAL_MODE 1 matter action switch mode ,such as by button +# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. +CONFIG_DUAL_MODE=1 \ No newline at end of file diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 0f1ce3f386b3..c6071bca7eb3 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -88,6 +88,7 @@ bool sIsNetworkEnabled = false; bool sIsNetworkAttached = false; bool sHaveBLEConnections = false; +#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE #include #include #include @@ -141,6 +142,7 @@ void dual_mode_switch(int32_t op) sys_reboot(SYS_REBOOT_WARM); } } +#endif #if APP_SET_DEVICE_INFO_PROVIDER chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; @@ -225,7 +227,9 @@ class AppFabricTableDelegate : public FabricTable::Delegate { ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); chip::Server::GetInstance().ScheduleFactoryReset(); + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_FACTORY_RESET); + #endif } } } @@ -626,7 +630,9 @@ void AppTaskCommon::StartBleAdvButtonEventHandler(void) void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent) { LOG_INF("StartBleAdvHandler"); + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_SWITCH_ZIGBEE); + #endif // Disable manual Matter service BLE advertising after device provisioning. if (sIsNetworkProvisioned) { @@ -672,7 +678,9 @@ void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent) sFactoryResetCntr = 0; chip::Server::GetInstance().ScheduleFactoryReset(); + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_FACTORY_RESET); + #endif } } @@ -854,7 +862,9 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* } break; case DeviceEventType::kCommissioningComplete: + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_MATTER_PAIRED); + #endif break; #if CHIP_DEVICE_CONFIG_ENABLE_THREAD case DeviceEventType::kDnssdInitialized: From 23558b6eeaa656da90e534b56b02a369680a915a Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 13 Jan 2026 11:24:07 +0800 Subject: [PATCH 16/54] telink: tl3238x: add the flash partition table . - add the 2m_lzma partition and origin 4m partition . Signed-off-by: Fengtai Xie --- examples/platform/telink/common.cmake | 8 +- src/platform/telink/tl3238x_2m_flash.overlay | 30 ++------ .../telink/tl3238x_2m_lzma_flash.overlay | 75 +++++++++++++++++++ src/platform/telink/tl3238x_4m_flash.overlay | 70 +++++++++++++++++ 4 files changed, 157 insertions(+), 26 deletions(-) create mode 100644 src/platform/telink/tl3238x_2m_lzma_flash.overlay create mode 100644 src/platform/telink/tl3238x_4m_flash.overlay diff --git a/examples/platform/telink/common.cmake b/examples/platform/telink/common.cmake index 0b79e1f15eef..9762d89fa973 100644 --- a/examples/platform/telink/common.cmake +++ b/examples/platform/telink/common.cmake @@ -117,8 +117,10 @@ else() unset(USB_CONF_OVERLAY_FILE) endif() +set(FIRMWARE_COMPRESS_LZMA "") if(${CONFIG_COMPRESS_LZMA} MATCHES y) set(BOOT_CONF_OVERLAY_FILE "${CHIP_ROOT}/config/telink/app/bootloader_compress_lzma.conf") + set(FIRMWARE_COMPRESS_LZMA "lzma_") else() set(BOOT_CONF_OVERLAY_FILE "${CHIP_ROOT}/config/telink/app/bootloader.conf") endif() @@ -155,7 +157,11 @@ if(NOT EXISTS "${GLOBAL_DTC_OVERLAY_FILE}") unset(GLOBAL_DTC_OVERLAY_FILE) endif() -set(FLASH_DTC_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BASE_BOARD}_${FLASH_SIZE}_flash.overlay") +if(${BASE_BOARD} MATCHES "tl3238x") + set(FLASH_DTC_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BASE_BOARD}_${FLASH_SIZE}_${FIRMWARE_COMPRESS_LZMA}flash.overlay") +else() + set(FLASH_DTC_OVERLAY_FILE "${CHIP_ROOT}/src/platform/telink/${BASE_BOARD}_${FLASH_SIZE}_flash.overlay") +endif() if(NOT EXISTS "${FLASH_DTC_OVERLAY_FILE}") message(STATUS "${FLASH_DTC_OVERLAY_FILE} doesn't exist") unset(FLASH_DTC_OVERLAY_FILE) diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay index 9e9886e30976..afd6deb77a71 100644 --- a/src/platform/telink/tl3238x_2m_flash.overlay +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -9,35 +9,15 @@ // reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x15000>; + reg = <0x00000000 0x16000>; }; -// currently the reset flash is 0x1e0000- 0x15000() = 0x1cb000 = 1836k (the total of slot0,and slot1) -// tralor = 20k -// slot0_fw = (1836-20)/1.6/4*4 = 1132 (suppose as LZMA:60%) -// slot0 area = 1132+20 = 1152(0x120000) - slot0_partition: partition@15000 { + slot0_partition: partition@16000 { label = "image-0"; - reg = <0x15000 0x120000>; // total slot0 is 1152k + reg = <0x16000 0xe5000>; // total slot0 is 916k }; -// add information , increase part for matter & zigbee -// suppose the matter application layer is 30k, zigbee is 60k -// currently , basic matter fw is 813k, zigbee is 140k , so just suppose matter is 916k, and zigbee is 216, reserve 20k for matter ota trailor - slot0_matter_partition: partition@15000_1 { - label = "image-0-matter"; - reg = <0x15000 0xe5000>; // suppose matter is 916k (0xe5000) - }; - slot0_zb_partition: partition@fa000 { - label = "image-0-zb"; - reg = <0xfa000 0x36000>; // suppose zigbee is 216k (0x36000) - }; - slot0_trailor_partition: partition@130000 { - label = "image-0-trailor"; - reg = <0x130000 0x5000>; // suppose trailor is 20k - }; -// the total fw area is 1836k, and slot0 cost 1152, so the value is 1836 - 1152 = 684k (0xac000) */ - slot1_partition: partition@135000 { + slot1_partition: partition@fb000 { label = "image-1"; - reg = <0x135000 0xab000>; + reg = <0xfb000 0xe5000>; // total slot1 is 916k }; user_rfu_partition: partition@1e0000 { label = "user_rfu"; diff --git a/src/platform/telink/tl3238x_2m_lzma_flash.overlay b/src/platform/telink/tl3238x_2m_lzma_flash.overlay new file mode 100644 index 000000000000..9e9886e30976 --- /dev/null +++ b/src/platform/telink/tl3238x_2m_lzma_flash.overlay @@ -0,0 +1,75 @@ +&flash { + reg = <0x20000000 0x200000>; + + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +// reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x15000>; + }; +// currently the reset flash is 0x1e0000- 0x15000() = 0x1cb000 = 1836k (the total of slot0,and slot1) +// tralor = 20k +// slot0_fw = (1836-20)/1.6/4*4 = 1132 (suppose as LZMA:60%) +// slot0 area = 1132+20 = 1152(0x120000) + slot0_partition: partition@15000 { + label = "image-0"; + reg = <0x15000 0x120000>; // total slot0 is 1152k + }; +// add information , increase part for matter & zigbee +// suppose the matter application layer is 30k, zigbee is 60k +// currently , basic matter fw is 813k, zigbee is 140k , so just suppose matter is 916k, and zigbee is 216, reserve 20k for matter ota trailor + slot0_matter_partition: partition@15000_1 { + label = "image-0-matter"; + reg = <0x15000 0xe5000>; // suppose matter is 916k (0xe5000) + }; + slot0_zb_partition: partition@fa000 { + label = "image-0-zb"; + reg = <0xfa000 0x36000>; // suppose zigbee is 216k (0x36000) + }; + slot0_trailor_partition: partition@130000 { + label = "image-0-trailor"; + reg = <0x130000 0x5000>; // suppose trailor is 20k + }; +// the total fw area is 1836k, and slot0 cost 1152, so the value is 1836 - 1152 = 684k (0xac000) */ + slot1_partition: partition@135000 { + label = "image-1"; + reg = <0x135000 0xab000>; + }; + user_rfu_partition: partition@1e0000 { + label = "user_rfu"; + reg = <0x1e0000 0x4000>; + }; + storage_partition: partition@1e4000 { + label = "matter-nvs"; + reg = <0x1e4000 0x8000>; // matter nvs part , total is 32k. + }; + zigbee_nvs_partition: partition@1ec000 { + label = "zigbee-nvs"; + reg = <0x1ec000 0xc000>; // zigbee nvs part , total is 48k. + }; + secure_partition: partition@1f8000 { + label = "secure"; + reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + dual_mode_partition: partition@1fa000 { + label = "dual-mode"; + reg = <0x1fa000 0x2000>; // user:store the mode info and the key info part.same as public area for dual mode + }; + dac_keypair_partition: partition@1fc000 { + label = "dac-keypair"; + reg = <0x1fc000 0x1000>; // store dac and key pair. + }; + factory_partition: partition@1fd000 { + label = "factory-data"; + reg = <0x1fd000 0x1000>; // factory data info + }; + vendor_partition: partition@1fe000 { + label = "vendor-data"; + reg = <0x1fe000 0x2000>; // mac and rf info. + }; + }; +}; diff --git a/src/platform/telink/tl3238x_4m_flash.overlay b/src/platform/telink/tl3238x_4m_flash.overlay new file mode 100644 index 000000000000..02ead8922059 --- /dev/null +++ b/src/platform/telink/tl3238x_4m_flash.overlay @@ -0,0 +1,70 @@ +&flash { + reg = <0x20000000 0x400000>; + + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +// reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x16000>; + }; + slot0_partition: partition@16000 { + label = "image-0"; + reg = <0x16000 0x1e5000>; // total slot0 is 1940k + }; +// add information , increase part for matter & zigbee +// currently , matter slot0 is 1640k, zigbee is 276k ,reserve 20k for matter ota trailor + slot0_matter_partition: partition@16000_1 { + label = "image-0-matter"; + reg = <0x16000 0x19a000>; // suppose matter is 1640k (0x19a000) + }; + slot0_zb_partition: partition@1b0000 { + label = "image-0-zb"; + reg = <0x1b0000 0x46000>; // suppose zigbee is 280k (0x46000) + }; + slot0_trailor_partition: partition@1f6000 { + label = "image-0-trailor"; + reg = <0x1f6000 0x5000>; // suppose trailor is 20k + }; +// the total fw area is 1940k */ + slot1_partition: partition@1fb000 { + label = "image-1"; + reg = <0x1fb000 0x1e5000>; + }; + user_rfu_partition: partition@3e0000 { + label = "user_rfu"; + reg = <0x3e0000 0x4000>; + }; + storage_partition: partition@3e4000 { + label = "matter-nvs"; + reg = <0x3e4000 0x8000>; // matter nvs part , total is 32k. + }; + zigbee_nvs_partition: partition@3ec000 { + label = "zigbee-nvs"; + reg = <0x3ec000 0xc000>; // zigbee nvs part , total is 48k. + }; + secure_partition: partition@3f8000 { + label = "secure"; + reg = <0x3f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + dual_mode_partition: partition@3fa000 { + label = "dual-mode"; + reg = <0x3fa000 0x2000>; // user:store the mode info and the key info part.same as public area for dual mode + }; + dac_keypair_partition: partition@3fc000 { + label = "dac-keypair"; + reg = <0x3fc000 0x1000>; // store dac and key pair. + }; + factory_partition: partition@3fd000 { + label = "factory-data"; + reg = <0x3fd000 0x1000>; // factory data info + }; + vendor_partition: partition@3fe000 { + label = "vendor-data"; + reg = <0x3fe000 0x2000>; // mac and rf info. + }; + }; +}; From 51df158f95be2674c009a83db7cf2ed8adcccbe1 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 13 Jan 2026 19:05:58 +0800 Subject: [PATCH 17/54] telink: tl3238x: add auto-switch mode for dual mode . - update application code for auto-switch mode . - clean code. Signed-off-by: haiwen.xia --- examples/light-switch-app/telink/prj.conf | 2 +- .../telink/common/include/AppTaskCommon.h | 4 +- .../telink/common/src/AppTaskCommon.cpp | 140 +++++++++++++++++- src/platform/telink/tl3238x_2m_flash.overlay | 10 +- 4 files changed, 146 insertions(+), 10 deletions(-) diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 08f52e3a8e96..3bc87e5b6fba 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -60,4 +60,4 @@ CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. -CONFIG_DUAL_MODE=0 \ No newline at end of file +CONFIG_DUAL_MODE=1 \ No newline at end of file diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index db7d7c99b4cb..fadd9d0b2349 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -134,7 +134,9 @@ class AppTaskCommon virtual void LinkPwms(PwmManager & pwmManager); void InitButtons(void); virtual void LinkButtons(ButtonManager & buttonManager); - +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + static void DnssTimerTimeoutCallback(k_timer * timer); +#endif static void FactoryResetTimerTimeoutCallback(k_timer * timer); static void FactoryResetTimerEventHandler(AppEvent * aEvent); static void FactoryResetButtonEventHandler(void); diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index c6071bca7eb3..a8400af39f1c 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -88,7 +88,7 @@ bool sIsNetworkEnabled = false; bool sIsNetworkAttached = false; bool sHaveBLEConnections = false; -#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE +#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE || CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE #include #include #include @@ -112,6 +112,11 @@ bool sHaveBLEConnections = false; // after zb paired , it will go to zb, only if trigger action. #define MODE_VAL_ZB_PAIR 0xaa #define ACTION_SWITCH_MATTER 0x55 + +#endif + +#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE + void dual_mode_switch(int32_t op) { uint8_t boot_flag[2] = { 0xff, 0xff }; @@ -142,6 +147,79 @@ void dual_mode_switch(int32_t op) sys_reboot(SYS_REBOOT_WARM); } } + +#elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + +//#include + +#define USER_MATTER_BACK_ZB 0xa0 // only commisiion fail will back to zb +#define USER_ZB_SW_VAL 0xaa + +typedef struct{ + uint8_t val; + uint8_t on_net; +} user_para_t; + +uint8_t sBoot_zb = 0; +user_para_t user_para; + +#define ZB_NVS_PARTITION zigbee_nvs_partition +#define ZB_NVS_SEC_SIZE FIXED_PARTITION_SIZE(ZB_NVS_PARTITION) + +#define ZB_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZB_NVS_PARTITION) +#define ZB_NVS_START_ADR FIXED_PARTITION_OFFSET(ZB_NVS_PARTITION) + + +const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; +const struct device * zb_para_dev = ZB_NVS_PARTITION_DEVICE; +constexpr int kDnssTimeout = 60000; +static k_timer sDnssTimer; + +void FactoryResetExtHandler(void) +{ + // Erase the user parameters partition to reset mode settings + flash_erase(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, DUAL_MODE_PARTITION_SIZE); + // Erase ZigBee NVS data during factory reset + flash_erase(zb_para_dev, ZB_NVS_START_ADR, ZB_NVS_SEC_SIZE); +} + +uint8_t dual_mode_switch_from_zb() +{ + flash_read(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &user_para, sizeof(user_para)); + if (user_para.val == USER_ZB_SW_VAL){ + return 1; + } +} + +void dual_mode_auto_switch(int32_t op) +{ + uint8_t boot_flag = 0xff; + const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; + + flash_read(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &boot_flag, 1); + + if (op == OPCODE_FACTORY_RESET) + { + FactoryResetExtHandler(); + } + else if (op == OPCODE_SWITCH_ZIGBEE) + { + boot_flag = USER_MATTER_BACK_ZB; + } + else if (op == OPCODE_MATTER_PAIRED) + { + boot_flag = MODE_VAL_MATTER_PAIR; + } + flash_erase(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, 4096); + flash_write(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &boot_flag, sizeof(boot_flag)); + + // need to reboot ,switch to bootloader + if (op == OPCODE_SWITCH_ZIGBEE) + { + sys_reboot(SYS_REBOOT_WARM); + } +} + #endif #if APP_SET_DEVICE_INFO_PROVIDER @@ -225,11 +303,13 @@ class AppFabricTableDelegate : public FabricTable::Delegate } else { - ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); - chip::Server::GetInstance().ScheduleFactoryReset(); #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_FACTORY_RESET); + #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + dual_mode_auto_switch(OPCODE_FACTORY_RESET); #endif + ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); + chip::Server::GetInstance().ScheduleFactoryReset(); } } } @@ -277,6 +357,25 @@ void AppTaskCommon::PowerOnFactoryReset(void) } #endif /* CONFIG_CHIP_ENABLE_POWER_ON_FACTORY_RESET */ +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE +void AppTaskCommon::DnssTimerTimeoutCallback(k_timer * timer) +{ + if (!timer) + { + return; + } + /* + * If Dnss initialization takes longer than 60 seconds, + * the device will reboot and revert to Zigbee mode. + */ + if (sBoot_zb) + { + printk("Matter: DnssTimer expired. Rebooting...\n"); + dual_mode_auto_switch(OPCODE_SWITCH_ZIGBEE); + } +} +#endif + CHIP_ERROR AppTaskCommon::StartApp(void) { CHIP_ERROR err = GetAppTask().Init(); @@ -287,6 +386,15 @@ CHIP_ERROR AppTaskCommon::StartApp(void) return err; } +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + if(dual_mode_switch_from_zb()){ + sBoot_zb = 1; + k_timer_init(&sDnssTimer, &DnssTimerTimeoutCallback, nullptr); + k_timer_start(&sDnssTimer, K_MSEC(kDnssTimeout), K_NO_WAIT); + printk("Matter: Started DNS protection timer."); + } +#endif + AppEvent event = {}; #if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE @@ -864,8 +972,27 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* case DeviceEventType::kCommissioningComplete: #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_MATTER_PAIRED); + #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + dual_mode_auto_switch(OPCODE_MATTER_PAIRED); #endif + printk("Commissioning complete; Matter commissioned flag set.\n"); + break; + +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + case DeviceEventType::kFailSafeTimerExpired: + /* Reset to Zigbee mode if commissioning fails */ + if (sBoot_zb) + { + dual_mode_auto_switch(OPCODE_SWITCH_ZIGBEE); + printk("FailSafeTimer expired; Matter commissioning failed. Rebooting to Zigbee mode...\n"); + } + else + { + printk("FailSafeTimer expired; Matter commissioning failed.\n"); + } break; +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD case DeviceEventType::kDnssdInitialized: #if CONFIG_CHIP_OTA_REQUESTOR @@ -878,6 +1005,13 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* #endif /* CONFIG_BOOTLOADER_MCUBOOT */ #if CONFIG_CHIP_OTA_REQUESTOR } +#endif +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + if (sBoot_zb) + { + k_timer_stop(&sDnssTimer); + printk("DnssTimer stopped; DNS-SD has been initialized.\n"); + } #endif break; case DeviceEventType::kThreadStateChange: diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay index afd6deb77a71..2352450cc755 100644 --- a/src/platform/telink/tl3238x_2m_flash.overlay +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -9,15 +9,15 @@ // reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x16000>; + reg = <0x00000000 0x15000>; }; - slot0_partition: partition@16000 { + slot0_partition: partition@15000 { label = "image-0"; - reg = <0x16000 0xe5000>; // total slot0 is 916k + reg = <0x15000 0xe5000>; // total slot0 is 916k }; - slot1_partition: partition@fb000 { + slot1_partition: partition@fa000 { label = "image-1"; - reg = <0xfb000 0xe5000>; // total slot1 is 916k + reg = <0xfa000 0xe6000>; // total slot1 is 916k }; user_rfu_partition: partition@1e0000 { label = "user_rfu"; From c8a0f1580c539dbbb3a9214a7289b5511f1a16fb Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 15 Jan 2026 16:19:34 +0800 Subject: [PATCH 18/54] telink: tl3238x: fix ota mode . - bootloader will use const overlay ,so should keep the bootloader and application use the same . Signed-off-by: haiwen.xia --- src/platform/telink/tl3238x_2m_flash.overlay | 26 +++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay index 2352450cc755..9e9886e30976 100644 --- a/src/platform/telink/tl3238x_2m_flash.overlay +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -11,13 +11,33 @@ label = "mcuboot"; reg = <0x00000000 0x15000>; }; +// currently the reset flash is 0x1e0000- 0x15000() = 0x1cb000 = 1836k (the total of slot0,and slot1) +// tralor = 20k +// slot0_fw = (1836-20)/1.6/4*4 = 1132 (suppose as LZMA:60%) +// slot0 area = 1132+20 = 1152(0x120000) slot0_partition: partition@15000 { label = "image-0"; - reg = <0x15000 0xe5000>; // total slot0 is 916k + reg = <0x15000 0x120000>; // total slot0 is 1152k }; - slot1_partition: partition@fa000 { +// add information , increase part for matter & zigbee +// suppose the matter application layer is 30k, zigbee is 60k +// currently , basic matter fw is 813k, zigbee is 140k , so just suppose matter is 916k, and zigbee is 216, reserve 20k for matter ota trailor + slot0_matter_partition: partition@15000_1 { + label = "image-0-matter"; + reg = <0x15000 0xe5000>; // suppose matter is 916k (0xe5000) + }; + slot0_zb_partition: partition@fa000 { + label = "image-0-zb"; + reg = <0xfa000 0x36000>; // suppose zigbee is 216k (0x36000) + }; + slot0_trailor_partition: partition@130000 { + label = "image-0-trailor"; + reg = <0x130000 0x5000>; // suppose trailor is 20k + }; +// the total fw area is 1836k, and slot0 cost 1152, so the value is 1836 - 1152 = 684k (0xac000) */ + slot1_partition: partition@135000 { label = "image-1"; - reg = <0xfa000 0xe6000>; // total slot1 is 916k + reg = <0x135000 0xab000>; }; user_rfu_partition: partition@1e0000 { label = "user_rfu"; From fdd8001fb60a133311c06d539ad3a09cb6c8e51c Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 15 Jan 2026 16:20:49 +0800 Subject: [PATCH 19/54] telink: tl3238x: open the tlx optimization mode . - in pm mode ,should open optimize mode to save power . Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 1 + 1 file changed, 1 insertion(+) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index bee9d9491863..9a4e7ed821b0 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -317,6 +317,7 @@ config OPENTHREAD_CSMABACKOFF_OPTIMIZATION config IEEE802154_TLX_OPTIMIZATION bool "Optimize 802.15.4 RF performance for TLX SoCs" + default y if PM && SOC_RISCV_TELINK_TL323X default n help Improve RF performance in IEEE 802.15.4 communication on TLX SoCs. From 0da6e6e12d07fca94c54f26c3e229dc973d0ab1a Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Tue, 20 Jan 2026 13:23:46 +0800 Subject: [PATCH 20/54] telink: tl3238x: open the tlx optimization mode . - in pm mode ,should open optimize mode to save power . Signed-off-by: haiwen.xia --- examples/lighting-app/telink/prj.conf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 4d55b053374e..666efa58b5c1 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -54,11 +54,11 @@ CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 CONFIG_PM=n #compress ota -CONFIG_COMPRESS_LZMA=y -CONFIG_LZMA=y +CONFIG_COMPRESS_LZMA=n +CONFIG_LZMA=n # matter switch mode # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button -# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. -CONFIG_DUAL_MODE=1 \ No newline at end of file +# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code.should use 4m flash +CONFIG_DUAL_MODE=2 \ No newline at end of file From 40a440d48670941f580c6a8a192adb47f933b8d6 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 21 Jan 2026 17:15:36 +0800 Subject: [PATCH 21/54] telink: tl3238x: add 2m partition for no lzma mode. - need to use 2m back up file to replace 2m partition . Signed-off-by: haiwen.xia --- .../telink/tl3238x_2m_flash_backup.overlay | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/platform/telink/tl3238x_2m_flash_backup.overlay diff --git a/src/platform/telink/tl3238x_2m_flash_backup.overlay b/src/platform/telink/tl3238x_2m_flash_backup.overlay new file mode 100644 index 000000000000..2352450cc755 --- /dev/null +++ b/src/platform/telink/tl3238x_2m_flash_backup.overlay @@ -0,0 +1,55 @@ +&flash { + reg = <0x20000000 0x200000>; + + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +// reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x15000>; + }; + slot0_partition: partition@15000 { + label = "image-0"; + reg = <0x15000 0xe5000>; // total slot0 is 916k + }; + slot1_partition: partition@fa000 { + label = "image-1"; + reg = <0xfa000 0xe6000>; // total slot1 is 916k + }; + user_rfu_partition: partition@1e0000 { + label = "user_rfu"; + reg = <0x1e0000 0x4000>; + }; + storage_partition: partition@1e4000 { + label = "matter-nvs"; + reg = <0x1e4000 0x8000>; // matter nvs part , total is 32k. + }; + zigbee_nvs_partition: partition@1ec000 { + label = "zigbee-nvs"; + reg = <0x1ec000 0xc000>; // zigbee nvs part , total is 48k. + }; + secure_partition: partition@1f8000 { + label = "secure"; + reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + dual_mode_partition: partition@1fa000 { + label = "dual-mode"; + reg = <0x1fa000 0x2000>; // user:store the mode info and the key info part.same as public area for dual mode + }; + dac_keypair_partition: partition@1fc000 { + label = "dac-keypair"; + reg = <0x1fc000 0x1000>; // store dac and key pair. + }; + factory_partition: partition@1fd000 { + label = "factory-data"; + reg = <0x1fd000 0x1000>; // factory data info + }; + vendor_partition: partition@1fe000 { + label = "vendor-data"; + reg = <0x1fe000 0x2000>; // mac and rf info. + }; + }; +}; From 6cd6d1c61dcf51c8668ed08076a47e73bcd37647 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 22 Jan 2026 10:51:53 +0800 Subject: [PATCH 22/54] telink: tl3238x: open dfu over smp by default. - open ble ota by default for pm mode and non-pm mode . Signed-off-by: haiwen.xia --- examples/light-switch-app/telink/prj.conf | 4 ++-- examples/lighting-app/telink/prj.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 3bc87e5b6fba..8bd46cd7dbe2 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -30,8 +30,8 @@ CONFIG_BT_DEVICE_NAME="TelinkSwitch" # Disable Matter OTA DFU CONFIG_CHIP_OTA_REQUESTOR=y -CONFIG_CHIP_DFU_OVER_BT_SMP=n -CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n +CONFIG_CHIP_DFU_OVER_BT_SMP=y +CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=y CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 # Disable CHIP shell support diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 666efa58b5c1..32cd0ffe9b58 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -30,8 +30,8 @@ CONFIG_BT_DEVICE_NAME="TelinkLight" # Disable Matter OTA DFU CONFIG_CHIP_OTA_REQUESTOR=y -CONFIG_CHIP_DFU_OVER_BT_SMP=n -CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n +CONFIG_CHIP_DFU_OVER_BT_SMP=y +CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=y CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 CONFIG_TELINK_OTA_BUTTON_TEST=n From 6b18c4b15338a5cfc8851fed896279975f51e0ce Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Fri, 23 Jan 2026 10:49:20 +0800 Subject: [PATCH 23/54] telink: tl3238x: add openthread patch file. - in pm mode , should apply this patch to modules/lib/openthread . Signed-off-by: haiwen.xia --- .../openthread/csma_next_operation.patch | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 third_party_patches/openthread/csma_next_operation.patch diff --git a/third_party_patches/openthread/csma_next_operation.patch b/third_party_patches/openthread/csma_next_operation.patch new file mode 100644 index 000000000000..66db5d5fb2da --- /dev/null +++ b/third_party_patches/openthread/csma_next_operation.patch @@ -0,0 +1,43 @@ +diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp +index 225ad30f5..29b4d7414 100644 +--- a/src/core/mac/mac.cpp ++++ b/src/core/mac/mac.cpp +@@ -40,6 +40,24 @@ + #include "instance/instance.hpp" + #include "utils/static_counter.hpp" + ++ ++#define CONFIG_OPENTHREAD_CSMABACKOFF_OPTIMIZATION 1 ++ ++#if CONFIG_OPENTHREAD_CSMABACKOFF_OPTIMIZATION ++bool get_pm_standby_flag(void) ++{ ++ bool pm_flag; ++ #if CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION ++ extern bool b9x_deep_sleep_retention; ++ pm_flag = b9x_deep_sleep_retention; ++ #elif CONFIG_SOC_SERIES_RISCV_TELINK_TLX_RETENTION ++ extern bool tlx_deep_sleep_retention; ++ pm_flag = tlx_deep_sleep_retention; ++ #endif ++ return pm_flag; ++} ++#endif ++ + namespace ot { + namespace Mac { + +@@ -629,6 +647,13 @@ void Mac::StartOperation(Operation aOperation) + + if (mOperation == kOperationIdle) + { ++#if CONFIG_OPENTHREAD_CSMABACKOFF_OPTIMIZATION ++ bool ot_deep_sleep_flag = !get_pm_standby_flag(); ++ if(ot_deep_sleep_flag){ ++ ot_deep_sleep_flag = false; ++ PerformNextOperation(); ++ }else ++#endif /* CONFIG_OPENTHREAD_CSMABACKOFF_OPTIMIZATION */ + mOperationTask.Post(); + } + } From a9cc6edcd2022f496b8bef3bd826a8abd1ad79d3 Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Thu, 15 Jan 2026 15:16:20 +0200 Subject: [PATCH 24/54] [Telink] Register DeviceInfoProvider before Server::Init (#42665) --- examples/platform/telink/common/src/AppTaskCommon.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index a8400af39f1c..08123788026d 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022-2024 Project CHIP Authors + * Copyright (c) 2022-2026 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -491,16 +491,15 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void) VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); #endif (void) initParams.InitializeStaticResourcesBeforeServerInit(); +#if APP_SET_DEVICE_INFO_PROVIDER + gExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); + chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); +#endif initParams.dataModelProvider = CodegenDataModelProviderInstance(initParams.persistentStorageDelegate); initParams.appDelegate = &sCallbacks; initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); -#if APP_SET_DEVICE_INFO_PROVIDER - gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); - chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); -#endif - ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); From 297ec45e60fd90340b657b1883993cae517d3c52 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Sat, 24 Jan 2026 14:20:00 +0800 Subject: [PATCH 25/54] telink: tl3238x: fix the auto switch logic. - fix the logic for zigbee switch to matter. Signed-off-by: haiwen.xia --- examples/platform/telink/common/src/AppTaskCommon.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 08123788026d..6ae16f84e1a8 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -204,15 +204,17 @@ void dual_mode_auto_switch(int32_t op) } else if (op == OPCODE_SWITCH_ZIGBEE) { + /*if commission fail should keep the state of others , directly write from 0xAA to 0xA0*/ boot_flag = USER_MATTER_BACK_ZB; + flash_write(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &boot_flag, sizeof(boot_flag)); } else if (op == OPCODE_MATTER_PAIRED) { boot_flag = MODE_VAL_MATTER_PAIR; + flash_erase(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, 4096); + flash_write(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &boot_flag, sizeof(boot_flag)); } - flash_erase(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, 4096); - flash_write(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &boot_flag, sizeof(boot_flag)); - + // need to reboot ,switch to bootloader if (op == OPCODE_SWITCH_ZIGBEE) { From e85387931eb07f3f091f89287d6477aedfcb93ab Mon Sep 17 00:00:00 2001 From: haiwentelink <125550736+haiwentelink@users.noreply.github.com> Date: Wed, 28 Jan 2026 20:40:35 +0800 Subject: [PATCH 26/54] Develop tl3238x develop production (#414) - add optional argument --secure-programming-verification and --chip-id to generate factory data and independent DAC. - remove redundant Config SECURE_PROGRAMMING in Kconfig.defaults. - Add gatt service for read chip-id when adv and conn. - Update CONFIG_SECURE_PROGRAMMING. - update logging in mfg_tool.py - Add aes_decryption_be for TL3238 - Add GetDACData for separate DAC partition - Add logging to print DAC key pairs and cert - Add testing factory data blocks - directly use the flash adr as the pointer for the dac cert part. - use efuse_get_ieee_addr instead of efuse_get_chip_id - append 8 bytes of '0x00' at the end of mac addr to generated chip_id - Need update efuse_get_ieee_addr return from void to drv_api_status_e - Enhance the Manufacturing Date handling to support extended string formats (e.g., 20250825CNLS0413) while maintaining compatibility with the previous numeric format (YYYY-MM-DD). - Some modifications are Matter public implementation changes, use as reference to implement your own requirements. - Verification command: ./chip-tool basicinformation read manufacturing-date 1 0 - remove PKI certs - remove factory data - update prj.conf files. - clean code for parse factory data and prj.conf. - fix the bugs for the impl of manufacutring_string. Signed-off-by: haiwen.xia --------- Signed-off-by: jinmiao.yu Signed-off-by: Jinmiao Yu Signed-off-by: Fengtai Xie Signed-off-by: pulin1103 Signed-off-by: Damien Ji Signed-off-by: haiwen.xia Signed-off-by: Hao Wu Co-authored-by: jinmiao.yu Co-authored-by: hao.wu Co-authored-by: Fengtai Xie Co-authored-by: pulin1103 Co-authored-by: Damien Ji --- .github/workflows/examples-telink.yaml | 4 +- config/telink/chip-module/Kconfig | 9 ++ examples/light-switch-app/telink/prj.conf | 11 +- examples/lighting-app/telink/prj.conf | 12 +- scripts/tools/telink/mfg_tool.py | 141 ++++++++++++++++-- scripts/tools/telink/process_binaries.py | 3 +- .../BasicInformationCluster.cpp | 8 +- .../platform/DeviceInstanceInfoProvider.h | 16 ++ .../GenericConfigurationManagerImpl.ipp | 5 + src/platform/telink/BLEManagerImpl.cpp | 40 ++++- src/platform/telink/BLEManagerImpl.h | 5 + .../telink/CHIPDevicePlatformConfig.h | 12 ++ src/platform/telink/FactoryDataParser.c | 117 +++++++++++++-- src/platform/telink/FactoryDataParser.h | 15 ++ src/platform/telink/FactoryDataProvider.cpp | 69 ++++++++- src/platform/telink/FactoryDataProvider.h | 1 + 16 files changed, 434 insertions(+), 34 deletions(-) diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 7cce89a97693..bc6d25a1a577 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -57,8 +57,8 @@ jobs: with: gh-context: ${{ toJson(github) }} - # - name: Update Zephyr version 4.1.0 (develop) to specific revision (for developers purpose) - # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 86fb5f1142c99e04abc923f4c0aa5fafb2ea9ace" + - name: Update Zephyr version 4.1.0 (develop) to specific revision (for developers purpose) + run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 42f57a7692969193ece78fde32354c6208043c25" - name: Build tools required for Factory Data # Run test for master and all PRs diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 41129298635a..f351d90e6c14 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -324,3 +324,12 @@ endif config TFLM_FEATURE bool "Enable the TFLM micro speech feature" default n + +config SECURE_PROGRAMMING + bool "Enable reading DAC and keys from the DAC partition" + depends on CHIP_FACTORY_DATA + default n + +config EXPOSE_CHIP_ID_VIA_BLE + bool "Enable CHIP-ID via ble" + default n diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 8bd46cd7dbe2..798d760ba99c 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -42,7 +42,7 @@ CONFIG_CHIP_FACTORY_DATA=n CONFIG_CHIP_FACTORY_DATA_BUILD=n CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n -CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 +# CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=y @@ -60,4 +60,11 @@ CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. -CONFIG_DUAL_MODE=1 \ No newline at end of file +CONFIG_DUAL_MODE=1 + +# open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE +# init should be n +CONFIG_SECURE_PROGRAMMING=n + +# Enable CHIP-ID via ble +CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 32cd0ffe9b58..7452a8d7e01b 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -47,6 +47,10 @@ CONFIG_CHIP_FACTORY_DATA_BUILD=n CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n +# open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE +# init should be n +CONFIG_SECURE_PROGRAMMING=n + # Enable PWM CONFIG_PWM=y CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 @@ -61,4 +65,10 @@ CONFIG_LZMA=n # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code.should use 4m flash -CONFIG_DUAL_MODE=2 \ No newline at end of file +CONFIG_DUAL_MODE=2 + +# Enable Independent Button +CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE=n + +# Enable CHIP-ID via ble +CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n diff --git a/scripts/tools/telink/mfg_tool.py b/scripts/tools/telink/mfg_tool.py index 2920ba08f613..483dc54c8ede 100755 --- a/scripts/tools/telink/mfg_tool.py +++ b/scripts/tools/telink/mfg_tool.py @@ -34,6 +34,9 @@ import pyqrcode from intelhex import IntelHex +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from cryptography.hazmat.backends import default_backend + TOOLS = { 'spake2p': None, 'chip-cert': None, @@ -58,7 +61,6 @@ NVS_MEMORY = {} - def nvs_memory_append(key, value): if isinstance(value, str): NVS_MEMORY[key] = value.encode("utf-8") @@ -458,10 +460,15 @@ def write_device_unique_data(args, out_dirs, pai_cert): dacs = use_dac_cert_from_args(args, out_dirs) else: dacs = generate_dac_cert(int(row['Index']), args, out_dirs, int(row['Discriminator']), - int(row['PIN Code']), pai_cert['key_pem'], pai_cert['cert_pem']) + int(row['PIN Code']), pai_cert['key_pem'], pai_cert['cert_pem']) + dac_cert_storage = read_der_file(dacs[0]) + dac_key_storage = read_key_bin_file(dacs[1]) + if args.secure_programming_verification == False: + nvs_memory_append('dac_cert', dac_cert_storage) + nvs_memory_append('dac_key', dac_key_storage) + else: + log.info("Secure programming verification enabled; DAC and its keys are not stored directly into factory data") - nvs_memory_append('dac_cert', read_der_file(dacs[0])) - nvs_memory_append('dac_key', read_key_bin_file(dacs[1])) nvs_memory_append('pai_cert', read_der_file(pai_cert['cert_der'])) nvs_memory_append('cert_dclrn', read_der_file(args.cert_dclrn)) @@ -474,17 +481,100 @@ def write_device_unique_data(args, out_dirs, pai_cert): return dacs +def aes_encrypt(key, data): + # Ensure data is 16 bytes (AES block size) + assert len(data) == 16, "Data block for AES must be 16 bytes." + assert len(key) == 16, "AES key must be 16 bytes (128 bits)." + + cipher = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) + encryptor = cipher.encryptor() + return encryptor.update(data) + encryptor.finalize() + +def save_dac_cert_and_keys(dac_cert, dac_key, chip_id, file_path): + with open(file_path, 'wb') as f: + # Write DAC private key length (2 bytes, little-endian) + dac_key_len = len(dac_key) + f.write(dac_key_len.to_bytes(2, 'little')) + + # Encrypt DAC private key in two 16-byte segments + encrypted_key_part1 = aes_encrypt(chip_id, dac_key[:16]) + encrypted_key_part2 = aes_encrypt(chip_id, dac_key[16:32]) + + # Write the encrypted DAC private key parts (32 bytes total) + f.write(encrypted_key_part1) + f.write(encrypted_key_part2) + + # Pad the file with 0xFF to reach the 100th byte + f.write(b'\xFF' * (100 - f.tell())) + + # Write DAC certificate length (2 bytes, little-endian) + dac_cert_len = len(dac_cert) + f.write(dac_cert_len.to_bytes(2, 'little')) -def generate_partition(args, out_dirs): - log.info("Generating partition image: offset: 0x%08X size: 0x%08X", args.offset, args.size) + # Write DAC certificate data + f.write(dac_cert) + + print(f"DAC certificate and key have been saved to {file_path}") + +def generate_partition(args, dacs_cert, out_dirs): + log.info('Generating partition image: offset: 0x{:X} size: 0x{:X}'.format(args.offset, args.size)) cbor_data = cbor.dumps(NVS_MEMORY) # Create hex file if len(cbor_data) > args.size: raise ValueError("generated CBOR file exceeds declared maximum partition size! {} > {}".format(len(cbor_data), args.size)) ih = IntelHex() ih.putsz(args.offset, cbor_data) - ih.write_hex_file(os.sep.join([out_dirs['output'], 'factory_data.hex']), True) - ih.tobinfile(os.sep.join([out_dirs['output'], 'factory_data.bin'])) + # ih.write_hex_file(os.sep.join([out_dirs['output'], 'factory_data.hex']), True) + # ih.tobinfile(os.sep.join([out_dirs['output'], 'factory_data.bin'])) + + output_dir = out_dirs['output'] + hex_file_path = os.path.join(output_dir, 'factory_data.hex') + bin_file_path = os.path.join(output_dir, 'factory_data.bin') + ih.write_hex_file(hex_file_path, True) + ih.tobinfile(bin_file_path) + + if args.secure_programming_verification: + dac_cert_key_file_path = os.path.join(output_dir, 'dac_cert_key.bin') + dac_cert_storage = read_der_file(dacs_cert[0]) + log.info("dac_cert_storaget (Hex): {}".format(dac_cert_storage.hex())) + dac_key_storage = read_key_bin_file(dacs_cert[1]) + log.info("dac_key_storage (Hex): {}".format(dac_key_storage.hex())) + chip_id_bytes = bytes.fromhex(args.chip_id) + log.info("chip_id_bytes (Hex): {}".format(chip_id_bytes.hex())) + save_dac_cert_and_keys(dac_cert_storage, dac_key_storage, chip_id_bytes, dac_cert_key_file_path) + log.info(f"DAC certificate and key have been saved to {dac_cert_key_file_path}") + + with open(os.sep.join([out_dirs['output'], 'pin_disc.csv']), 'r') as csvf: + pin_disc_dict = csv.DictReader(csvf) + row = pin_disc_dict.__next__() + + # Extract Discriminator, PID, and VID + discriminator = int(row['Discriminator']) + pid = args.product_id + vid = args.vendor_id + + log.info("Discriminator = {}".format(discriminator)) + log.info("PID = 0x{:X}".format(pid)) + log.info("VID = 0x{:X}".format(vid)) + + # Convert Discriminator, PID, and VID to bytes + discriminator_bytes = discriminator.to_bytes(2, byteorder='little') + pid_bytes = pid.to_bytes(2, byteorder='little') + vid_bytes = vid.to_bytes(2, byteorder='little') + + # Read the existing binary data + with open(bin_file_path, 'rb') as bin_file: + bin_data = bin_file.read() + + # Prepend the hex data to the binary data + extended_data = discriminator_bytes + pid_bytes + vid_bytes + bin_data + + # Write the combined data to a new file + ext_bin_file_path = os.path.join(output_dir, 'factory_data_ext.bin') + with open(ext_bin_file_path, 'wb') as ext_bin_file: + ext_bin_file.write(extended_data) + + log.info(f"Extended binary data written to {ext_bin_file_path}") def generate_json_summary(args, out_dirs, pai_certs, dacs_cert, serial_num: str): @@ -547,7 +637,10 @@ def add_additional_kv(args, serial_num): nvs_memory_append('rd_uid', args.rd_id_uid) # Add the serial-num - nvs_memory_append('sn', serial_num) + if args.disable_serial_num_storage: + log.info("Secure programming verification enabled; skipping serial-num") + else: + nvs_memory_append('sn', serial_num) nvs_memory_append('version', FACTORY_DATA_VERSION) @@ -604,7 +697,7 @@ def base64_str(s): return base64.b64decode(s) help='Commissionable device discovery networking technology. \ 0:WiFi-SoftAP, 1:BLE, 2:On-network. Default is BLE.', choices=[0, 1, 2]) - # Device insrance information + # Device instance information dev_inst_args = parser.add_argument_group('Device instance information options') dev_inst_args.add_argument('-v', '--vendor-id', type=allow_any_int, required=False, help='Vendor id') dev_inst_args.add_argument('--vendor-name', type=str, required=False, help='Vendor name') @@ -649,8 +742,34 @@ def base64_str(s): return base64.b64decode(s) help='Partition offset - an address in devices NVM memory, where factory data will be stored') part_gen_args.add_argument('--size', type=allow_any_int, help='The maximum partition size') + secure_args = parser.add_argument_group('Secure programming verification options') + secure_args.add_argument("--secure-programming-verification", action="store_true", + help="Enable secure programming mode. When set, the script will perform additional steps for secure programming verification.") + secure_args.add_argument("--chip-id", required=False, type=str, help="Chip ID in hex format (32 hex characters).") + secure_args.add_argument("--disable_serial_num_storage", action="store_true", + help="Disable storage of serial-num in factorydata.") + args = parser.parse_args() + if args.secure_programming_verification: + if not args.chip_id: + log.error("--chip-id is required when --secure-programming-verification is enabled.") + sys.exit(1) + + if args.count > 1: + log.error("--count cannot be greater than 1 when --secure-programming-verification is enabled.") + sys.exit(1) + + # Additional validation on chip-id format + if args.chip_id: + try: + chip_id_bytes = bytes.fromhex(args.chip_id) + if len(chip_id_bytes) != 16: + raise ValueError() + except ValueError: + log.error("--chip-id must be a valid 16-byte hex string (32 hex characters).") + sys.exit(1) + # Validate in-tree parameter if args.count > 1 and args.in_tree: log.error("Option --in-tree can not be use together with --count > 1") @@ -746,7 +865,7 @@ def main(): if args.paa or args.pai: pai_cert = setup_root_certificates(args, out_dirs) dacs_cert = write_device_unique_data(args, out_dirs, pai_cert) - generate_partition(args, out_dirs) + generate_partition(args, dacs_cert, out_dirs) generate_json_summary(args, out_dirs, pai_cert, dacs_cert, serial_num_str) dev_sn_file.close() diff --git a/scripts/tools/telink/process_binaries.py b/scripts/tools/telink/process_binaries.py index 2b36f384f5fd..4d5fe7ce7f9d 100755 --- a/scripts/tools/telink/process_binaries.py +++ b/scripts/tools/telink/process_binaries.py @@ -179,7 +179,8 @@ def compress_lzma_firmware(input_file, output_file): print(f"Image footer is written to {dfu_output_name}") print("Image for DFU over BLE SMP is ready!") - os.remove('empty.txt') + # to avoid need -p compile every time. + #os.remove('empty.txt') if build_conf.getboolean('CONFIG_TELINK_OTA_BUTTON_TEST'): merge_binaries('merged.bin', build_conf['CONFIG_SIGNED_OTA_IMAGE_FILE_NAME'], diff --git a/src/app/clusters/basic-information/BasicInformationCluster.cpp b/src/app/clusters/basic-information/BasicInformationCluster.cpp index e59056b9cc1d..26199776807b 100644 --- a/src/app/clusters/basic-information/BasicInformationCluster.cpp +++ b/src/app/clusters/basic-information/BasicInformationCluster.cpp @@ -163,8 +163,11 @@ inline CHIP_ERROR ReadManufacturingDate(DeviceInstanceInfoProvider * deviceInfoP uint16_t manufacturingYear; uint8_t manufacturingMonth; uint8_t manufacturingDayOfMonth; + #if CONFIG_SECURE_PROGRAMMING + CHIP_ERROR status = deviceInfoProvider->GetManufacturingDateString(manufacturingDateString, sizeof(manufacturingDateString)); + #else CHIP_ERROR status = deviceInfoProvider->GetManufacturingDate(manufacturingYear, manufacturingMonth, manufacturingDayOfMonth); - + #endif // TODO: Remove defaulting once proper runtime defaulting of unimplemented factory data is done if (status == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND || status == CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE) { @@ -175,9 +178,6 @@ inline CHIP_ERROR ReadManufacturingDate(DeviceInstanceInfoProvider * deviceInfoP } ReturnErrorOnFailure(status); - // Format is YYYYMMDD - snprintf(manufacturingDateString, sizeof(manufacturingDateString), "%04u%02u%02u", manufacturingYear, manufacturingMonth, - manufacturingDayOfMonth); return aEncoder.Encode(CharSpan(manufacturingDateString, strnlen(manufacturingDateString, kMaxLen))); } diff --git a/src/include/platform/DeviceInstanceInfoProvider.h b/src/include/platform/DeviceInstanceInfoProvider.h index e1312f727972..1414aeb752d0 100644 --- a/src/include/platform/DeviceInstanceInfoProvider.h +++ b/src/include/platform/DeviceInstanceInfoProvider.h @@ -131,6 +131,22 @@ class DeviceInstanceInfoProvider */ virtual CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) = 0; + /** + * @brief Obtain a manufacturing date string from the device's factory data. + * + * @param[in, out] buf Buffer to copy string. + * On CHIP_NO_ERROR return from this function this buffer will be null-terminated. + * On error CHIP_ERROR_BUFFER_TOO_SMALL there is no guarantee that buffer will be null-terminated. + * @param[in] bufSize Size of data, including the null terminator, that can be written to buf. + * This size should be +1 higher than maximum possible string. + * @returns CHIP_NO_ERROR on success, or another CHIP_ERROR from the underlying implementation + * if access fails. + */ + virtual CHIP_ERROR GetManufacturingDateString(char * buf, size_t bufSize) + { + return CHIP_ERROR_NOT_IMPLEMENTED; + } + /** * @brief Obtain a Hardware Version from the device's factory data. * diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp index a8831bd6a4e7..44ced290efc3 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp @@ -799,6 +799,11 @@ void GenericConfigurationManagerImpl::LogDeviceConfig() { ChipLogProgress(DeviceLayer, " Manufacturing Date: (not set)"); } + + /* Add print: Modify Manufacturing Date Format. Delete if it is not needed */ + char mfgDate[ConfigurationManager::kMaxManufacturingDateLength + 1]; + err = deviceInstanceInfoProvider->GetManufacturingDateString(mfgDate, sizeof(mfgDate)); + ChipLogProgress(DeviceLayer, " Manufacturing Date String: %s", (err == CHIP_NO_ERROR) ? mfgDate : "(not set)"); } { diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 56c3c3add938..50fe137844e4 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -87,6 +87,11 @@ const bt_uuid_128 UUID128_CHIPoBLEChar_C3 = BT_UUID_INIT_128(0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0x63, 0x64); #endif +#if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE +const bt_uuid_128 UUID128_CHIPoBLEChar_ChipID = + BT_UUID_INIT_128(0x04, 0x8F, 0x21, 0x83, 0x8A, 0x74, 0x7D, 0xB8, 0xF2, 0x45, 0x72, 0x87, 0x38, 0x02, 0xA1, 0x01); +#endif + bt_uuid_16 UUID16_CHIPoBLEService = BT_UUID_INIT_16(0xFFF6); _bt_gatt_ccc CHIPoBLEChar_TX_CCC = BT_GATT_CCC_INITIALIZER(nullptr, BLEManagerImpl::HandleTXCCCWrite, nullptr); @@ -110,6 +115,13 @@ bt_gatt_attr sChipoBleAttributes[] = { BT_GATT_PERM_READ, BLEManagerImpl::HandleC3Read, nullptr, nullptr), #endif + +#if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE + BT_GATT_CHARACTERISTIC(&UUID128_CHIPoBLEChar_ChipID.uuid, + BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, + BLEManagerImpl::HandleChipIDRead, nullptr, nullptr), +#endif }; bt_gatt_service sChipoBleService = BT_GATT_SERVICE(sChipoBleAttributes); @@ -946,8 +958,34 @@ CHIP_ERROR BLEManagerImpl::HandleBleConnectionClosed(const ChipDeviceEvent * eve return CHIP_NO_ERROR; } +#if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE +#include +ssize_t BLEManagerImpl::HandleChipIDRead(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, + uint16_t offset) +{ + ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE Chip ID (ConnId 0x%02x)", bt_conn_index(conId)); + // Example chip_id data storage (replace with actual chip_id value) + // uint8_t chip_id[] = { 0x42, 0xe3, 0x03, 0xb4, 0xcf, 0x3c, 0xe6, 0x32, 0x36, 0x37, 0x36, 0x42, 0x50, 0x55, 0x76, 0xce }; + uint8_t chip_id[16] = { 0 }; + // efuse_get_chip_id(chip_id); + uint8_t ieee_addr[8] = {0}; + + if (!efuse_get_ieee_addr(ieee_addr)) { + LOG_ERR("Failed to get chip ID."); + return false; + } + LOG_HEXDUMP_INF(ieee_addr, 8, "IEEE address"); + + memcpy(chip_id, ieee_addr, 8); + LOG_HEXDUMP_INF(chip_id, 16, "chip_id with IEEE address and zero padding"); + + return bt_gatt_attr_read(conId, attr, buf, len, offset, chip_id, sizeof(chip_id)); +} +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD -CHIP_ERROR BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) +CHIP_ERROR +BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) { ChipLogDetail(DeviceLayer, "HandleOperationalNetworkEnabled"); diff --git a/src/platform/telink/BLEManagerImpl.h b/src/platform/telink/BLEManagerImpl.h index dff0874fac14..52bfc0948a61 100644 --- a/src/platform/telink/BLEManagerImpl.h +++ b/src/platform/telink/BLEManagerImpl.h @@ -172,6 +172,11 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla bool NeedToResetFailSafeTimer(void); void ClearResetFailSafeTimerFlag(void); +#if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE + static ssize_t HandleChipIDRead(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, + uint16_t offset); +#endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD // Switch context from BLE to Thread void SwitchToIeee802154(void); diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 14adaf851f67..82710b3f586f 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -121,6 +121,18 @@ #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 #endif +#ifdef CONFIG_EXPOSE_CHIP_ID_VIA_BLE +#define CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE CONFIG_EXPOSE_CHIP_ID_VIA_BLE +#else +#define CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE 0 +#endif + +#ifdef CONFIG_SECURE_PROGRAMMING +#define CHIP_DEVICE_SECURE_PROGRAMMING CONFIG_SECURE_PROGRAMMING +#else +#define CHIP_DEVICE_SECURE_PROGRAMMING 0 +#endif + // ========== Platform-specific Configuration ========= // These are configuration options that are unique to Zephyr platforms. diff --git a/src/platform/telink/FactoryDataParser.c b/src/platform/telink/FactoryDataParser.c index a2d4c26ede99..224f99bffd93 100644 --- a/src/platform/telink/FactoryDataParser.c +++ b/src/platform/telink/FactoryDataParser.c @@ -26,7 +26,9 @@ #define MAX_FACTORY_DATA_NESTING_LEVEL 3 LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); - +#if CHIP_DEVICE_SECURE_PROGRAMMING +static uint8_t dac_key_decrypt[32] = { 0 }; +#endif static inline bool uint16_decode(zcbor_state_t * states, uint16_t * value) { uint32_t u32; @@ -100,17 +102,29 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData } else if (strncmp("date", (const char *) currentString.value, currentString.len) == 0) { - // Date format is YYYY-MM-DD, so format needs to be validated and string parse to integer parts. - struct zcbor_string date; - res = res && zcbor_bstr_decode(states, &date); - if (date.len == 10 && isdigit(date.value[0]) && isdigit(date.value[1]) && isdigit(date.value[2]) && - isdigit(date.value[3]) && date.value[4] == '-' && isdigit(date.value[5]) && isdigit(date.value[6]) && - date.value[7] == '-' && isdigit(date.value[8]) && isdigit(date.value[9])) + // Format needs to be validated and string parse to integer parts. + struct zcbor_string * date = (struct zcbor_string *) &factoryData->mfg_date_str; + res = res && zcbor_bstr_decode(states, date); + + // First check for YYYY-MM-DD format (10 digits with hyphens) + if (date->len == 10 && isdigit(date->value[0]) && isdigit(date->value[1]) && isdigit(date->value[2]) && + isdigit(date->value[3]) && date->value[4] == '-' && isdigit(date->value[5]) && isdigit(date->value[6]) && + date->value[7] == '-' && isdigit(date->value[8]) && isdigit(date->value[9])) + { + factoryData->date_year = 1000 * (date->value[0] - '0') + 100 * (date->value[1] - '0') + + 10 * (date->value[2] - '0') + date->value[3] - '0'; + factoryData->date_month = 10 * (date->value[5] - '0') + date->value[6] - '0'; + factoryData->date_day = 10 * (date->value[8] - '0') + date->value[9] - '0'; + } + // Then check for YYYYMMDD or extended formats (8-16 digits) + else if ((date->len >= 8 && date->len <= 16) && isdigit(date->value[0]) && isdigit(date->value[1]) && + isdigit(date->value[2]) && isdigit(date->value[3]) && isdigit(date->value[4]) && isdigit(date->value[5]) && + isdigit(date->value[6]) && isdigit(date->value[7])) { - factoryData->date_year = - 1000 * (date.value[0] - '0') + 100 * (date.value[1] - '0') + 10 * (date.value[2] - '0') + date.value[3] - '0'; - factoryData->date_month = 10 * (date.value[5] - '0') + date.value[6] - '0'; - factoryData->date_day = 10 * (date.value[8] - '0') + date.value[9] - '0'; + factoryData->date_year = 1000 * (date->value[0] - '0') + 100 * (date->value[1] - '0') + + 10 * (date->value[2] - '0') + date->value[3] - '0'; + factoryData->date_month = 10 * (date->value[4] - '0') + date->value[5] - '0'; + factoryData->date_day = 10 * (date->value[6] - '0') + date->value[7] - '0'; } else { @@ -125,14 +139,22 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->rd_uid); } +#if !CHIP_DEVICE_SECURE_PROGRAMMING else if (strncmp("dac_cert", (const char *) currentString.value, currentString.len) == 0) { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_cert); + // LOG_INF("DAC cert len=%u", currentString.len); + // LOG_HEXDUMP_INF(currentString.value, + // currentString.len, + // "DAC CERT"); } else if (strncmp("dac_key", (const char *) currentString.value, currentString.len) == 0) { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->dac_priv_key); + // LOG_INF("DAC priv key decrypted, len=%u", currentString.len); + // LOG_HEXDUMP_INF(currentString.value, currentString.len, "DAC PRIV KEY"); } +#endif else if (strncmp("pai_cert", (const char *) currentString.value, currentString.len) == 0) { res = res && zcbor_bstr_decode(states, (struct zcbor_string *) &factoryData->pai_cert); @@ -185,3 +207,76 @@ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData return res && zcbor_list_map_end_force_decode(states); } + +#if CHIP_DEVICE_SECURE_PROGRAMMING +#if CONFIG_SOC_RISCV_TELINK_TL323X +#include "efuse.h" +#include "ske_basic.h" +#include "ske_portable.h" +#include +#include +#else +#include "aes.h" +#endif + +bool LoadDACCertAndKey(uint8_t * base_buffer , struct FactoryData * factoryData) +{ + size_t dac_priv_key_len; + uint8_t ieee_addr[8] = {0}; + uint8_t chip_id[16] = { 0 }; + /* get the dac key pair info form the flash directly*/ + uint8_t buffer[34] = {0}; + const struct device * mFlashDevice = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)); + int ret = flash_read(mFlashDevice, FIXED_PARTITION_OFFSET(dac_keypair_partition), buffer, sizeof(buffer)); + + dac_priv_key_len = buffer[0]; + dac_priv_key_len |= (uint16_t) buffer[1] << 8; + factoryData->dac_priv_key.len = dac_priv_key_len; + if (!factoryData->dac_priv_key.len) + { + return false; + } + + if (efuse_get_ieee_addr(ieee_addr) == DRV_API_SUCCESS) + { + LOG_HEXDUMP_INF(ieee_addr, 8, "IEEE address"); + + memcpy(chip_id, ieee_addr, 8); + LOG_HEXDUMP_INF(chip_id, 16, "chip_id with IEEE address and zero padding"); + +#if CONFIG_SOC_RISCV_TELINK_TL323X + ske_dig_en(); + aes_decryption_be(chip_id, buffer + 2, dac_key_decrypt); + aes_decryption_be(chip_id, buffer + 18, dac_key_decrypt + 16); +#else + aes_decrypt(chip_id, buffer + 2, dac_key_decrypt); + aes_decrypt(chip_id, buffer + 18, dac_key_decrypt + 16); +#endif + + LOG_INF("[LoadDACCertAndKey]DAC priv key decrypted, len=%u", dac_priv_key_len); + LOG_HEXDUMP_INF(buffer + 2, dac_priv_key_len, "[LoadDACCertAndKey]Encrypted DAC PRIV KEY"); + LOG_HEXDUMP_INF(dac_key_decrypt, dac_priv_key_len, "[LoadDACCertAndKey]DAC PRIV KEY"); + factoryData->dac_priv_key.data = dac_key_decrypt; + } + else + { + LOG_ERR("Failed to get chip ID."); + return false; + } + + size_t dac_cert_len = 0; + flash_read(mFlashDevice, FIXED_PARTITION_OFFSET(dac_keypair_partition)+100, buffer, 2); + dac_cert_len = buffer[0]; + dac_cert_len |= (uint16_t) buffer[1] << 8; + factoryData->dac_cert.len = dac_cert_len; + if (!factoryData->dac_cert.len) + { + return false; + } + factoryData->dac_cert.data =(uint8_t *) (0x20000000 + FIXED_PARTITION_OFFSET(dac_keypair_partition) + 102); + // LOG_INF("[LoadDACCertAndKey]DAC cert len=%u", dac_cert_len); + // LOG_HEXDUMP_INF(factoryData->dac_cert.data, factoryData->dac_cert.len, "DAC CERT"); + + return true; +} +#endif diff --git a/src/platform/telink/FactoryDataParser.h b/src/platform/telink/FactoryDataParser.h index de8f7c72da83..2b780027bcbd 100644 --- a/src/platform/telink/FactoryDataParser.h +++ b/src/platform/telink/FactoryDataParser.h @@ -21,6 +21,8 @@ #include #include +#include "CHIPDevicePlatformConfig.h" + #ifdef __cplusplus extern "C" { #endif @@ -46,6 +48,7 @@ struct FactoryData struct FactoryDataString product_url; struct FactoryDataString product_label; uint16_t hw_ver; + struct FactoryDataString mfg_date_str; struct FactoryDataString hw_ver_str; struct FactoryDataString rd_uid; struct FactoryDataString dac_cert; @@ -77,6 +80,18 @@ struct FactoryData */ bool ParseFactoryData(uint8_t * buffer, uint16_t bufferSize, struct FactoryData * factoryData); +#if CHIP_DEVICE_SECURE_PROGRAMMING +/** + * @brief Inject dac cert and dac private key into the factory data structure. + * + * @param[in] . base_buffer malloc buffer for factory data + * @param[out] factoryData address of object to be filled with parsed factory data. + * + * @returns true on success, false otherwise. + */ +bool LoadDACCertAndKey(uint8_t * base_buffer, struct FactoryData * factoryData); +#endif + #ifdef __cplusplus } #endif diff --git a/src/platform/telink/FactoryDataProvider.cpp b/src/platform/telink/FactoryDataProvider.cpp index de375d98a48f..370e60a99785 100644 --- a/src/platform/telink/FactoryDataProvider.cpp +++ b/src/platform/telink/FactoryDataProvider.cpp @@ -27,6 +27,8 @@ #include #include +LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL); + namespace chip { namespace { @@ -62,12 +64,18 @@ CHIP_ERROR GetFactoryDataString(const FactoryDataString & str, char * buf, size_ } // namespace namespace DeviceLayer { - +#if CHIP_DEVICE_SECURE_PROGRAMMING +static constexpr uint32_t kFactoryDataOffset = 6; +#endif template CHIP_ERROR FactoryDataProvider::Init() { uint8_t * factoryData = nullptr; size_t factoryDataSize; +#if CHIP_DEVICE_SECURE_PROGRAMMING + uint8_t * dacData = nullptr; + size_t dacDataSize; +#endif CHIP_ERROR error = mFlashFactoryData.ProtectFactoryDataPartitionAgainstWrite(); @@ -98,15 +106,43 @@ CHIP_ERROR FactoryDataProvider::Init() if (error != CHIP_NO_ERROR) { ChipLogError(DeviceLayer, "Failed to read factory data partition"); + free(ptr); // Only free on failure return error; } + +#if CHIP_DEVICE_SECURE_PROGRAMMING + if (!ParseFactoryData(factoryData + kFactoryDataOffset, factoryDataSize - kFactoryDataOffset, &mFactoryData)) +#else if (!ParseFactoryData(factoryData, factoryDataSize, &mFactoryData)) +#endif { ChipLogError(DeviceLayer, "Failed to parse factory data"); + free(ptr); // Only free on failure return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; } + LOG_INF("[ParseFactoryData - ParseFactoryData] DAC priv key len=%u", mFactoryData.dac_priv_key.len); + LOG_HEXDUMP_INF(mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len, "DAC PRIV KEY"); + + LOG_INF("[ParseFactoryData - ParseFactoryData] DAC cert len=%u", mFactoryData.dac_cert.len); + LOG_HEXDUMP_INF(mFactoryData.dac_cert.data, mFactoryData.dac_cert.len, "DAC CERT"); + +#if CHIP_DEVICE_SECURE_PROGRAMMING + if (!LoadDACCertAndKey(mFactoryDataBuffer , &mFactoryData)) + { + ChipLogError(DeviceLayer, "Failed to inject dac data"); + free(ptr); // Only free on failure + return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + + LOG_INF("[ParseFactoryData-LoadDACCertAndKey] DAC priv key len=%u", mFactoryData.dac_priv_key.len); + LOG_HEXDUMP_INF(mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len, "DAC PRIV KEY"); + + LOG_INF("[ParseFactoryData-LoadDACCertAndKey] DAC cert len=%u", mFactoryData.dac_cert.len); + LOG_HEXDUMP_INF(mFactoryData.dac_cert.data, mFactoryData.dac_cert.len, "DAC CERT"); +#endif + // Release the memory of mFactoryDataBuffer after complete parse free(ptr); @@ -153,7 +189,11 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(Mutab VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); +#if CHIP_DEVICE_SECURE_PROGRAMMING + memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); +#else GetFactoryData(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); +#endif outBuffer.reduce_size(mFactoryData.dac_cert.len); @@ -195,13 +235,26 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(c return CHIP_ERROR_NO_MEMORY; } +#if CHIP_DEVICE_SECURE_PROGRAMMING + memcpy(P_DACCert, mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); +#else GetFactoryData(P_DACCert, mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); +#endif + + LOG_INF("[SignWithDeviceAttestationKey] DAC cert len=%u", mFactoryData.dac_cert.len); + LOG_HEXDUMP_INF(mFactoryData.dac_cert.data, mFactoryData.dac_cert.len, "mFactoryData.dac_cert.data"); + LOG_HEXDUMP_INF(P_DACCert, mFactoryData.dac_cert.len, "DAC CERT - P_DACCert"); // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(P_DACCert), mFactoryData.dac_cert.len }; + LOG_INF("[SignWithDeviceAttestationKey] DAC cert len=%u", dacCertSpan.size()); + LOG_HEXDUMP_INF(dacCertSpan.data(), dacCertSpan.size(), "DAC CERT"); chip::Crypto::P256PublicKey dacPublicKey; error = chip::Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey); + LOG_INF("[SignWithDeviceAttestationKey] DAC pub key len=%u", dacPublicKey.Length()); + LOG_HEXDUMP_INF(dacPublicKey.Bytes(), dacPublicKey.Length(), "DAC PUB KEY"); + free(P_DACCert); if (error != CHIP_NO_ERROR) { @@ -219,7 +272,15 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(c return CHIP_ERROR_NO_MEMORY; } +#if CHIP_DEVICE_SECURE_PROGRAMMING + memcpy(P_DACPrivKey, mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len); +#else GetFactoryData(P_DACPrivKey, mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len); +#endif + + LOG_INF("[SignWithDeviceAttestationKey] DAC priv key len=%u", mFactoryData.dac_priv_key.len); + LOG_HEXDUMP_INF(mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len, "mFactoryData.dac_priv_key.data"); + LOG_HEXDUMP_INF(P_DACPrivKey, mFactoryData.dac_priv_key.len, "DAC CERT - P_DACPrivKey"); // Load keypair from raw. error = LoadKeypairFromRaw(ByteSpan(reinterpret_cast(P_DACPrivKey), mFactoryData.dac_priv_key.len), @@ -362,6 +423,12 @@ CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t return CHIP_NO_ERROR; } +template +CHIP_ERROR FactoryDataProvider::GetManufacturingDateString(char * buf, size_t bufSize) +{ + return GetFactoryDataString(mFactoryData.mfg_date_str, buf, bufSize); +} + template CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { diff --git a/src/platform/telink/FactoryDataProvider.h b/src/platform/telink/FactoryDataProvider.h index bbfd9c92e049..4cd3d877d1e7 100644 --- a/src/platform/telink/FactoryDataProvider.h +++ b/src/platform/telink/FactoryDataProvider.h @@ -107,6 +107,7 @@ class FactoryDataProvider : public chip::Credentials::DeviceAttestationCredentia CHIP_ERROR GetProductLabel(char * buf, size_t bufSize) override; CHIP_ERROR GetSerialNumber(char * buf, size_t bufSize) override; CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; + CHIP_ERROR GetManufacturingDateString(char * buf, size_t bufSize) override; CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; CHIP_ERROR GetHardwareVersionString(char * buf, size_t bufSize) override; CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; From ce25e1af46fb37e1eb92dfa52d45420cfacee13c Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 29 Jan 2026 13:28:45 +0800 Subject: [PATCH 27/54] telink: tl3238x: clean code . - clean demo jump code zigbee switch demo code . - clean code kFailSafeTimerExpired. Signed-off-by: haiwen.xia --- examples/platform/telink/common/src/AppTaskCommon.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 6ae16f84e1a8..86798901ec39 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -739,9 +739,6 @@ void AppTaskCommon::StartBleAdvButtonEventHandler(void) void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent) { LOG_INF("StartBleAdvHandler"); - #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE - dual_mode_switch(OPCODE_SWITCH_ZIGBEE); - #endif // Disable manual Matter service BLE advertising after device provisioning. if (sIsNetworkProvisioned) { @@ -979,8 +976,8 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* printk("Commissioning complete; Matter commissioned flag set.\n"); break; -#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE case DeviceEventType::kFailSafeTimerExpired: +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE /* Reset to Zigbee mode if commissioning fails */ if (sBoot_zb) { @@ -988,11 +985,12 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* printk("FailSafeTimer expired; Matter commissioning failed. Rebooting to Zigbee mode...\n"); } else +#endif { printk("FailSafeTimer expired; Matter commissioning failed.\n"); } break; -#endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD case DeviceEventType::kDnssdInitialized: From ef56245b1c9c2246a6c52b12de5e668122acdaa9 Mon Sep 17 00:00:00 2001 From: Damien Ji Date: Thu, 29 Jan 2026 15:39:42 +0800 Subject: [PATCH 28/54] telink: tl3238x: fix expose chipId via ble. - fix compilation error when enabling CONFIG_EXPOSE_CHIP_ID_VIA_BLE Signed-off-by: Damien Ji --- src/platform/telink/BLEManagerImpl.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 50fe137844e4..1c9729ab5331 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -959,6 +959,9 @@ CHIP_ERROR BLEManagerImpl::HandleBleConnectionClosed(const ChipDeviceEvent * eve } #if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE +extern "C" { +#include "efuse.h" +} #include ssize_t BLEManagerImpl::HandleChipIDRead(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset) @@ -966,20 +969,19 @@ ssize_t BLEManagerImpl::HandleChipIDRead(struct bt_conn * conId, const struct bt ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE Chip ID (ConnId 0x%02x)", bt_conn_index(conId)); // Example chip_id data storage (replace with actual chip_id value) // uint8_t chip_id[] = { 0x42, 0xe3, 0x03, 0xb4, 0xcf, 0x3c, 0xe6, 0x32, 0x36, 0x37, 0x36, 0x42, 0x50, 0x55, 0x76, 0xce }; - uint8_t chip_id[16] = { 0 }; - // efuse_get_chip_id(chip_id); + uint8_t chip_id[16] = { 0 }; uint8_t ieee_addr[8] = {0}; - if (!efuse_get_ieee_addr(ieee_addr)) { - LOG_ERR("Failed to get chip ID."); + if (efuse_get_ieee_addr(ieee_addr) == DRV_API_SUCCESS) + { + memcpy(chip_id, ieee_addr, 8); + return bt_gatt_attr_read(conId, attr, buf, len, offset, chip_id, sizeof(chip_id)); + } + else + { + ChipLogDetail(DeviceLayer, "Failed to get chip ID."); return false; } - LOG_HEXDUMP_INF(ieee_addr, 8, "IEEE address"); - - memcpy(chip_id, ieee_addr, 8); - LOG_HEXDUMP_INF(chip_id, 16, "chip_id with IEEE address and zero padding"); - - return bt_gatt_attr_read(conId, attr, buf, len, offset, chip_id, sizeof(chip_id)); } #endif From 88a36b6c3e9edc1290996d525c3abf47a236fe92 Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Thu, 29 Jan 2026 16:20:12 +0800 Subject: [PATCH 29/54] riscv: telink: Adjust the format - Adjust HandleChipIDRead format . Signed-off-by: Fengtai Xie --- src/platform/telink/BLEManagerImpl.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 1c9729ab5331..3005e837956d 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -959,29 +959,32 @@ CHIP_ERROR BLEManagerImpl::HandleBleConnectionClosed(const ChipDeviceEvent * eve } #if CHIP_DEVICE_EXPOSE_CHIP_ID_VIA_BLE +#ifdef __cplusplus extern "C" { +#endif #include "efuse.h" +#ifdef __cplusplus } +#endif #include ssize_t BLEManagerImpl::HandleChipIDRead(struct bt_conn * conId, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset) { - ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE Chip ID (ConnId 0x%02x)", bt_conn_index(conId)); // Example chip_id data storage (replace with actual chip_id value) // uint8_t chip_id[] = { 0x42, 0xe3, 0x03, 0xb4, 0xcf, 0x3c, 0xe6, 0x32, 0x36, 0x37, 0x36, 0x42, 0x50, 0x55, 0x76, 0xce }; + ChipLogDetail(DeviceLayer, "Read request received for CHIPoBLE Chip ID (ConnId 0x%02x)", bt_conn_index(conId)); + uint8_t chip_id[16] = { 0 }; - uint8_t ieee_addr[8] = {0}; + uint8_t ieee_addr[8] = { 0 }; - if (efuse_get_ieee_addr(ieee_addr) == DRV_API_SUCCESS) - { - memcpy(chip_id, ieee_addr, 8); - return bt_gatt_attr_read(conId, attr, buf, len, offset, chip_id, sizeof(chip_id)); - } - else + if (efuse_get_ieee_addr(ieee_addr) != DRV_API_SUCCESS) { ChipLogDetail(DeviceLayer, "Failed to get chip ID."); - return false; + return 0; } + + memcpy(chip_id, ieee_addr, 8); + return bt_gatt_attr_read(conId, attr, buf, len, offset, chip_id, sizeof(chip_id)); } #endif From 182898f4383418e5d5bca2eed99cd052c7b75470 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 29 Jan 2026 13:28:45 +0800 Subject: [PATCH 30/54] telink: tl3238x: clean code . - close CONFIG_BOOT_BANNER . Signed-off-by: haiwen.xia --- config/telink/app/bootloader_compress_lzma.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/telink/app/bootloader_compress_lzma.conf b/config/telink/app/bootloader_compress_lzma.conf index 4ee33768e7d6..429d378279ff 100644 --- a/config/telink/app/bootloader_compress_lzma.conf +++ b/config/telink/app/bootloader_compress_lzma.conf @@ -45,3 +45,6 @@ CONFIG_SIZE_OPTIMIZATIONS=y CONFIG_COMPRESS_LZMA=y CONFIG_PICOLIBC=y + +# ### Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. +CONFIG_BOOT_BANNER=n \ No newline at end of file From 379bc2dd3fc325b6da524bcabb2e5d0ac7b0bb06 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 4 Feb 2026 15:27:51 +0800 Subject: [PATCH 31/54] telink: tl3238x: fix tl3238c 4m mode for lzma . - add overly for 4m lzma mode . Signed-off-by: haiwen.xia --- .../telink/tl3238x_4m_lzma_flash.overlay | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/platform/telink/tl3238x_4m_lzma_flash.overlay diff --git a/src/platform/telink/tl3238x_4m_lzma_flash.overlay b/src/platform/telink/tl3238x_4m_lzma_flash.overlay new file mode 100644 index 000000000000..02ead8922059 --- /dev/null +++ b/src/platform/telink/tl3238x_4m_lzma_flash.overlay @@ -0,0 +1,70 @@ +&flash { + reg = <0x20000000 0x400000>; + + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; +// reserve 20k for software bootloader , 64k for mcuboot,need to disable log for mcuboot; + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0x16000>; + }; + slot0_partition: partition@16000 { + label = "image-0"; + reg = <0x16000 0x1e5000>; // total slot0 is 1940k + }; +// add information , increase part for matter & zigbee +// currently , matter slot0 is 1640k, zigbee is 276k ,reserve 20k for matter ota trailor + slot0_matter_partition: partition@16000_1 { + label = "image-0-matter"; + reg = <0x16000 0x19a000>; // suppose matter is 1640k (0x19a000) + }; + slot0_zb_partition: partition@1b0000 { + label = "image-0-zb"; + reg = <0x1b0000 0x46000>; // suppose zigbee is 280k (0x46000) + }; + slot0_trailor_partition: partition@1f6000 { + label = "image-0-trailor"; + reg = <0x1f6000 0x5000>; // suppose trailor is 20k + }; +// the total fw area is 1940k */ + slot1_partition: partition@1fb000 { + label = "image-1"; + reg = <0x1fb000 0x1e5000>; + }; + user_rfu_partition: partition@3e0000 { + label = "user_rfu"; + reg = <0x3e0000 0x4000>; + }; + storage_partition: partition@3e4000 { + label = "matter-nvs"; + reg = <0x3e4000 0x8000>; // matter nvs part , total is 32k. + }; + zigbee_nvs_partition: partition@3ec000 { + label = "zigbee-nvs"; + reg = <0x3ec000 0xc000>; // zigbee nvs part , total is 48k. + }; + secure_partition: partition@3f8000 { + label = "secure"; + reg = <0x3f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + dual_mode_partition: partition@3fa000 { + label = "dual-mode"; + reg = <0x3fa000 0x2000>; // user:store the mode info and the key info part.same as public area for dual mode + }; + dac_keypair_partition: partition@3fc000 { + label = "dac-keypair"; + reg = <0x3fc000 0x1000>; // store dac and key pair. + }; + factory_partition: partition@3fd000 { + label = "factory-data"; + reg = <0x3fd000 0x1000>; // factory data info + }; + vendor_partition: partition@3fe000 { + label = "vendor-data"; + reg = <0x3fe000 0x2000>; // mac and rf info. + }; + }; +}; From 8309471cf9cf9ebdc7e6e8cb2dcd4345d1e98e4b Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 4 Feb 2026 18:12:28 +0800 Subject: [PATCH 32/54] telink: tl3238x: submit contact sensor mode . - add config for contact sensor mode ,but dfu over smp will compile fail ,wait to slove . Signed-off-by: haiwen.xia --- examples/contact-sensor-app/telink/prj.conf | 25 ++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index 5b7ce94f3253..ceca3279d14c 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -30,6 +30,9 @@ CONFIG_BT_DEVICE_NAME="TelinkSensor" # Disable Matter OTA DFU CONFIG_CHIP_OTA_REQUESTOR=y +CONFIG_CHIP_DFU_OVER_BT_SMP=n +CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n + CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 # Disable CHIP shell support @@ -39,10 +42,30 @@ CONFIG_CHIP_LIB_SHELL=n CONFIG_CHIP_FACTORY_DATA=n CONFIG_CHIP_FACTORY_DATA_BUILD=n CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n - +CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n +# CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=y #compress ota CONFIG_COMPRESS_LZMA=y CONFIG_LZMA=y + +#ICD SETTING INFO +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 +CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 +CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 + +#matter switch mode +# config NORMAL_MODE 0 independent matter mode +# ACTION_DUAL_MODE 1 matter action switch mode ,such as by button +# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. +CONFIG_DUAL_MODE=1 + +# open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE +# init should be n +CONFIG_SECURE_PROGRAMMING=n + +# Enable CHIP-ID via ble +CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n \ No newline at end of file From 7bf78cc718522f2e0f68a72db97c41cf7b866587 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 4 Feb 2026 20:53:04 +0800 Subject: [PATCH 33/54] telink: tl3238x: fix dfu mode for contact sensor mode . - open dfu mode ,and add dfu module into cmake.list in contact sensor mode. Signed-off-by: haiwen.xia --- examples/contact-sensor-app/telink/CMakeLists.txt | 5 +++++ examples/contact-sensor-app/telink/prj.conf | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/examples/contact-sensor-app/telink/CMakeLists.txt b/examples/contact-sensor-app/telink/CMakeLists.txt index 47ec87579425..745f0f4dc3be 100755 --- a/examples/contact-sensor-app/telink/CMakeLists.txt +++ b/examples/contact-sensor-app/telink/CMakeLists.txt @@ -57,3 +57,8 @@ chip_configure_data_model(app if(CONFIG_BOOTLOADER_MCUBOOT) target_sources(app PRIVATE ${TELINK_COMMON}/util/src/OTAUtil.cpp) endif() + +if(CONFIG_MCUMGR_TRANSPORT_BT) + zephyr_library_link_libraries(MCUBOOT_BOOTUTIL) + target_sources(app PRIVATE ${TELINK_COMMON}/util/src/DFUOverSMP.cpp) +endif() diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index ceca3279d14c..e132e1087b9e 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -30,8 +30,8 @@ CONFIG_BT_DEVICE_NAME="TelinkSensor" # Disable Matter OTA DFU CONFIG_CHIP_OTA_REQUESTOR=y -CONFIG_CHIP_DFU_OVER_BT_SMP=n -CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=n +CONFIG_CHIP_DFU_OVER_BT_SMP=y +CONFIG_CHIP_DFU_OVER_BT_SMP_BUILD=y CONFIG_CHIP_DEVICE_SOFTWARE_VERSION=1 From dbe8d97f150720a895fc5f0b47df033c482d1501 Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Thu, 5 Feb 2026 15:16:46 +0800 Subject: [PATCH 34/54] riscv: telink: fix dnss exception trigger when dfu-ota - Stopping sDnssTimer when duf-ota start . Signed-off-by: Fengtai Xie --- .../telink/common/src/AppTaskCommon.cpp | 4 +++- .../platform/telink/util/include/DFUOverSMP.h | 10 ++++++++++ .../platform/telink/util/src/DFUOverSMP.cpp | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 86798901ec39..db203d3e61b7 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -173,7 +173,9 @@ user_para_t user_para; const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; const struct device * zb_para_dev = ZB_NVS_PARTITION_DEVICE; constexpr int kDnssTimeout = 60000; -static k_timer sDnssTimer; +#if !CONFIG_MCUMGR_TRANSPORT_BT +static k_timer sDnssTimer; // create when dfu disable +#endif /* !CONFIG_MCUMGR_TRANSPORT_BT */ void FactoryResetExtHandler(void) { diff --git a/examples/platform/telink/util/include/DFUOverSMP.h b/examples/platform/telink/util/include/DFUOverSMP.h index cc99422f935e..8293e2ac7db3 100644 --- a/examples/platform/telink/util/include/DFUOverSMP.h +++ b/examples/platform/telink/util/include/DFUOverSMP.h @@ -27,6 +27,16 @@ #include #include +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE +#ifdef __cplusplus +extern "C" { +#endif +extern struct k_timer sDnssTimer; +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CONFIG_AUTO_SWITCH_DUAL_MODE */ + enum VerificationFailReason : unsigned char { NO_FAIL = 0, diff --git a/examples/platform/telink/util/src/DFUOverSMP.cpp b/examples/platform/telink/util/src/DFUOverSMP.cpp index bdbe10aae26c..e408ed123317 100644 --- a/examples/platform/telink/util/src/DFUOverSMP.cpp +++ b/examples/platform/telink/util/src/DFUOverSMP.cpp @@ -36,6 +36,17 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE +#ifdef __cplusplus +extern "C" { +#endif +struct k_timer sDnssTimer; +static volatile bool canlTimerFlag = false; +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* CONFIG_AUTO_SWITCH_DUAL_MODE */ + static void reboot_work_handler(struct k_work * work) { LOG_INF("[DFU] Start reboot!"); @@ -55,6 +66,13 @@ int UploadProgressHandler(uint32_t event, int32_t rc, bool * abort_more, void * #endif { +#if CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + if (!canlTimerFlag) { + k_timer_stop(&sDnssTimer); + canlTimerFlag = true; + LOG_INF("[Telink] DnssTimer stopped; DFU-OTA Handler.\n"); + } +#endif /* CONFIG_AUTO_SWITCH_DUAL_MODE */ const img_mgmt_upload_check & imgData = *static_cast(data); LOG_INF("[DFU] DFU over SMP progress: %u/%u B of image %u", static_cast(imgData.req->off), From 9c63585c1a438c773a4d04bc010421d48c6f4991 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Fri, 6 Feb 2026 18:09:20 +0800 Subject: [PATCH 35/54] telink: tl3238x: fix the logic jump from zigbee for auto-switch mode . - fix jump logic and before switch to zb ,should make it matter nvs clean. Signed-off-by: haiwen.xia --- examples/platform/telink/common/src/AppTaskCommon.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index db203d3e61b7..2f5d62f72d55 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -169,9 +169,16 @@ user_para_t user_para; #define ZB_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZB_NVS_PARTITION) #define ZB_NVS_START_ADR FIXED_PARTITION_OFFSET(ZB_NVS_PARTITION) +/*MATTER NVS*/ +#define MATTER_NVS_PARTITION storage_partition +#define MATTER_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(MATTER_NVS_PARTITION) +#define MATTER_NVS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(MATTER_NVS_PARTITION) +#define MATTER_NVS_PARTITION_SIZE FIXED_PARTITION_SIZE(MATTER_NVS_PARTITION) const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; const struct device * zb_para_dev = ZB_NVS_PARTITION_DEVICE; +const struct device * matter_nvs_dev = MATTER_NVS_PARTITION_DEVICE; + constexpr int kDnssTimeout = 60000; #if !CONFIG_MCUMGR_TRANSPORT_BT static k_timer sDnssTimer; // create when dfu disable @@ -190,6 +197,8 @@ uint8_t dual_mode_switch_from_zb() flash_read(flash_para_dev, DUAL_MODE_PARTITION_OFFSET, &user_para, sizeof(user_para)); if (user_para.val == USER_ZB_SW_VAL){ return 1; + }else{ + return 0; } } @@ -220,6 +229,8 @@ void dual_mode_auto_switch(int32_t op) // need to reboot ,switch to bootloader if (op == OPCODE_SWITCH_ZIGBEE) { + // clear matter nvs for unclean info in matter nvs + flash_erase(matter_nvs_dev, MATTER_NVS_PARTITION_OFFSET, MATTER_NVS_PARTITION_SIZE); sys_reboot(SYS_REBOOT_WARM); } } From d7ff28dea41dd8b53b8b01b27bcfcf7bdd64372c Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Sat, 7 Feb 2026 14:24:30 +0800 Subject: [PATCH 36/54] telink: tl3238x: update the auto switch logic in OTBR share mode . - seperate the commission mode and enhance mode. Signed-off-by: haiwen.xia --- examples/platform/telink/common/src/AppTaskCommon.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 2f5d62f72d55..c45ae9cf628e 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -984,6 +984,8 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_MATTER_PAIRED); #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + /* clear boot from zigbee after commission*/ + sBoot_zb = 0; dual_mode_auto_switch(OPCODE_MATTER_PAIRED); #endif printk("Commissioning complete; Matter commissioned flag set.\n"); From b926f786f4ee52d9e92c86b468b655e5b790e92c Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Wed, 25 Feb 2026 15:55:07 +0200 Subject: [PATCH 37/54] [Telink] add BLE extended advertising (#43277) * [Telink] Add BLE extended advertising * [Telink] Fix DISCOVERY_TIMEOUT * [Telink] Don't enable extended advertising by default * [Telibk] Fix typo --- src/platform/telink/BLEManagerImpl.cpp | 81 +++++++++++++++---- src/platform/telink/BLEManagerImpl.h | 6 +- .../telink/CHIPDevicePlatformConfig.h | 8 +- 3 files changed, 78 insertions(+), 17 deletions(-) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 3005e837956d..4f8e7d94d1e2 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -293,18 +294,40 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest(void) Encoding::LittleEndian::Put16(serviceData.uuid, UUID16_CHIPoBLEService.val); ReturnErrorOnFailure(ConfigurationMgr().GetBLEDeviceIdentificationInfo(serviceData.deviceIdInfo)); +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + if (mFlags.Has(Flags::kExtendedAdvertisingEnabled)) + { + serviceData.deviceIdInfo.SetVendorId(DEVICE_HANDLE_NULL); + serviceData.deviceIdInfo.SetProductId(DEVICE_HANDLE_NULL); + serviceData.deviceIdInfo.SetExtendedAnnouncementFlag(true); + } +#endif + advertisingData[0] = BT_DATA(BT_DATA_FLAGS, &kAdvertisingFlags, sizeof(kAdvertisingFlags)); advertisingData[1] = BT_DATA(BT_DATA_SVC_DATA16, &serviceData, sizeof(serviceData)); scanResponseData[0] = BT_DATA(BT_DATA_NAME_COMPLETE, name, nameSize); - mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY; - mAdvertisingRequest.options = kAdvertisingOptions; - mAdvertisingRequest.minInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) - ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN - : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; - mAdvertisingRequest.maxInterval = mFlags.Has(Flags::kFastAdvertisingEnabled) - ? CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX - : CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + mAdvertisingRequest.priority = CHIP_DEVICE_BLE_ADVERTISING_PRIORITY; + mAdvertisingRequest.options = kAdvertisingOptions; + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN; + mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX; + } +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + else if (mFlags.Has(Flags::kExtendedAdvertisingEnabled)) + { + mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MIN; + mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_MAX; + } +#endif + else + { + mAdvertisingRequest.minInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN; + mAdvertisingRequest.maxInterval = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX; + } + mAdvertisingRequest.advertisingData = Span(advertisingData); mAdvertisingRequest.scanResponseData = nameSize ? Span(scanResponseData) : Span{}; @@ -408,10 +431,17 @@ CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void) if (mFlags.Has(Flags::kFastAdvertisingEnabled)) { - // Start timer to change advertising interval. + // Start timer to change advertising interval from fast to slow. TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().StartTimer( System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME), - HandleBLEAdvertisementIntervalChange, this); + HandleSlowBLEAdvertisementInterval, this); + +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + // Start timer to schedule start of the extended advertising + TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().StartTimer( + System::Clock::Milliseconds32(CHIP_DEVICE_CONFIG_BLE_EXT_ADVERTISING_INTERVAL_CHANGE_TIME_MS), + HandleExtendedBLEAdvertisementInterval, this); +#endif } } @@ -437,6 +467,10 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) mFlags.Clear(Flags::kAdvertising); mFlags.Set(Flags::kFastAdvertisingEnabled, true); +#if CHIP_DEVICE_CONFIG_EXT_ADVERTISING + mFlags.Clear(Flags::kExtendedAdvertisingEnabled); +#endif + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising stopped"); // Post a CHIPoBLEAdvertisingChange(Stopped) event. @@ -448,7 +482,8 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) } // Cancel timer event changing CHIPoBLE advertisement interval - DeviceLayer::SystemLayer().CancelTimer(HandleBLEAdvertisementIntervalChange, this); + DeviceLayer::SystemLayer().CancelTimer(HandleSlowBLEAdvertisementInterval, this); + DeviceLayer::SystemLayer().CancelTimer(HandleExtendedBLEAdvertisementInterval, this); } return CHIP_NO_ERROR; @@ -461,6 +496,9 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) ChipLogDetail(DeviceLayer, "CHIPoBLE advertising set to %s", val ? "on" : "off"); mFlags.Set(Flags::kAdvertisingEnabled, val); + // Ensure that each enabling/disabling of the general advertising clears + // the extended mode, to make sure we always start fresh in the regular mode + mFlags.Set(Flags::kExtendedAdvertisingEnabled, false); TEMPORARY_RETURN_IGNORED PlatformMgr().ScheduleWork(DriveBLEState, 0); } @@ -473,8 +511,14 @@ CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) { case BLEAdvertisingMode::kFastAdvertising: mFlags.Set(Flags::kFastAdvertisingEnabled, true); + mFlags.Set(Flags::kExtendedAdvertisingEnabled, false); break; case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + mFlags.Set(Flags::kExtendedAdvertisingEnabled, false); + break; + case BLEAdvertisingMode::kExtendedAdvertising: + mFlags.Set(Flags::kExtendedAdvertisingEnabled, true); mFlags.Set(Flags::kFastAdvertisingEnabled, false); break; default: @@ -669,12 +713,18 @@ CHIP_ERROR BLEManagerImpl::PrepareC3CharData(void) } #endif -void BLEManagerImpl::HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param) +void BLEManagerImpl::HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param) { TEMPORARY_RETURN_IGNORED BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to slow"); } +void BLEManagerImpl::HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param) +{ + TEMPORARY_RETURN_IGNORED BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kExtendedAdvertising); + ChipLogProgress(DeviceLayer, "CHIPoBLE advertising mode changed to extended"); +} + void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -774,7 +824,8 @@ CHIP_ERROR BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const Chi params->attr = &sChipoBleAttributes[kCHIPoBLE_CCC_AttributeIndex]; params->func = HandleTXIndicated; params->data = pBuf->Start(); - params->len = pBuf->DataLength(); + VerifyOrExit(CanCastTo(pBuf->DataLength()), err = CHIP_ERROR_MESSAGE_TOO_LONG); + params->len = static_cast(pBuf->DataLength()); status = bt_gatt_indicate(conId, params); VerifyOrExit(status == 0, err = MapErrorZephyr(status)); @@ -933,8 +984,10 @@ ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gat return 0; } + // For BLE, the max payload size is limited to UINT16_MAX since the length + // field is 2 bytes long. So, the cast to uint16_t should be fine. return bt_gatt_attr_read(conId, attr, buf, len, offset, sInstance.c3CharDataBufferHandle->Start(), - sInstance.c3CharDataBufferHandle->DataLength()); + static_cast(sInstance.c3CharDataBufferHandle->DataLength())); } #endif diff --git a/src/platform/telink/BLEManagerImpl.h b/src/platform/telink/BLEManagerImpl.h index 52bfc0948a61..3596e2eb633c 100644 --- a/src/platform/telink/BLEManagerImpl.h +++ b/src/platform/telink/BLEManagerImpl.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022-2024 Project CHIP Authors + * Copyright (c) 2022-2026 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. @@ -92,6 +92,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla kAdvertisingRefreshNeeded = 0x0010, /**< The advertising state/configuration has changed, but the SoftDevice has yet to be updated. */ kChipoBleGattServiceRegister = 0x0020, /**< The system has currently CHIPoBLE GATT service registered. */ + kExtendedAdvertisingEnabled = 0x0040, /**< The application has enabled extended advertising. */ }; struct ServiceData; @@ -150,7 +151,8 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla static void HandleTXIndicated(bt_conn * conn, bt_gatt_indicate_params * attr, uint8_t err); static void HandleConnect(bt_conn * conn, uint8_t err); static void HandleDisconnect(bt_conn * conn, uint8_t reason); - static void HandleBLEAdvertisementIntervalChange(System::Layer * layer, void * param); + static void HandleSlowBLEAdvertisementInterval(System::Layer * layer, void * param); + static void HandleExtendedBLEAdvertisementInterval(System::Layer * layer, void * param); // ===== Members for internal use by the following friends. diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 82710b3f586f..928984814594 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022-2024 Project CHIP Authors + * Copyright (c) 2022-2026 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. @@ -262,6 +262,12 @@ #define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 #endif // CONFIG_CHIP_EXTENDED_DISCOVERY +#ifdef CONFIG_CHIP_BLE_EXT_ADVERTISING +#define CHIP_DEVICE_CONFIG_EXT_ADVERTISING 1 +#endif // CONFIG_CHIP_BLE_EXT_ADVERTISING + +#define CHIP_DEVICE_CONFIG_DISCOVERY_TIMEOUT_SECS (CONFIG_CHIP_BLE_ADVERTISING_DURATION * 60) + #ifndef CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL #ifdef CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL #define CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL chip::System::Clock::Milliseconds32(CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL) From b10de1ea55cd0c1cb7edb1f62ee66a13a5f884b8 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 18 Mar 2026 17:57:36 +0800 Subject: [PATCH 38/54] telink: tl3238x: release descriptor space for users. - lowdown the secure partition and add user config partition for user. Signed-off-by: haiwen.xia --- src/platform/telink/tl3238x_2m_flash.overlay | 6 +++++- src/platform/telink/tl3238x_2m_flash_backup.overlay | 6 +++++- src/platform/telink/tl3238x_2m_lzma_flash.overlay | 6 +++++- src/platform/telink/tl3238x_4m_flash.overlay | 6 +++++- src/platform/telink/tl3238x_4m_lzma_flash.overlay | 6 +++++- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/platform/telink/tl3238x_2m_flash.overlay b/src/platform/telink/tl3238x_2m_flash.overlay index 9e9886e30976..249608848d98 100644 --- a/src/platform/telink/tl3238x_2m_flash.overlay +++ b/src/platform/telink/tl3238x_2m_flash.overlay @@ -53,7 +53,11 @@ }; secure_partition: partition@1f8000 { label = "secure"; - reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + reg = <0x1f8000 0x1000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + user_config_partition: partition@1f9000 { + label = "user_config"; + reg = <0x1f9000 0x1000>; // user_config ,for the secure-boot sign logic changes ,it can release for user . }; dual_mode_partition: partition@1fa000 { label = "dual-mode"; diff --git a/src/platform/telink/tl3238x_2m_flash_backup.overlay b/src/platform/telink/tl3238x_2m_flash_backup.overlay index 2352450cc755..2fe5cafe183c 100644 --- a/src/platform/telink/tl3238x_2m_flash_backup.overlay +++ b/src/platform/telink/tl3238x_2m_flash_backup.overlay @@ -33,7 +33,11 @@ }; secure_partition: partition@1f8000 { label = "secure"; - reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + reg = <0x1f8000 0x1000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + user_config_partition: partition@1f9000 { + label = "user_config"; + reg = <0x1f9000 0x1000>; // user_config ,for the secure-boot sign logic changes ,it can release for user . }; dual_mode_partition: partition@1fa000 { label = "dual-mode"; diff --git a/src/platform/telink/tl3238x_2m_lzma_flash.overlay b/src/platform/telink/tl3238x_2m_lzma_flash.overlay index 9e9886e30976..249608848d98 100644 --- a/src/platform/telink/tl3238x_2m_lzma_flash.overlay +++ b/src/platform/telink/tl3238x_2m_lzma_flash.overlay @@ -53,7 +53,11 @@ }; secure_partition: partition@1f8000 { label = "secure"; - reg = <0x1f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + reg = <0x1f8000 0x1000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + user_config_partition: partition@1f9000 { + label = "user_config"; + reg = <0x1f9000 0x1000>; // user_config ,for the secure-boot sign logic changes ,it can release for user . }; dual_mode_partition: partition@1fa000 { label = "dual-mode"; diff --git a/src/platform/telink/tl3238x_4m_flash.overlay b/src/platform/telink/tl3238x_4m_flash.overlay index 02ead8922059..fa0284405499 100644 --- a/src/platform/telink/tl3238x_4m_flash.overlay +++ b/src/platform/telink/tl3238x_4m_flash.overlay @@ -48,7 +48,11 @@ }; secure_partition: partition@3f8000 { label = "secure"; - reg = <0x3f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + reg = <0x3f8000 0x1000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + user_config_partition: partition@3f9000 { + label = "user_config"; + reg = <0x3f9000 0x1000>; // user_config ,for the secure-boot sign logic changes ,it can release for user . }; dual_mode_partition: partition@3fa000 { label = "dual-mode"; diff --git a/src/platform/telink/tl3238x_4m_lzma_flash.overlay b/src/platform/telink/tl3238x_4m_lzma_flash.overlay index 02ead8922059..fa0284405499 100644 --- a/src/platform/telink/tl3238x_4m_lzma_flash.overlay +++ b/src/platform/telink/tl3238x_4m_lzma_flash.overlay @@ -48,7 +48,11 @@ }; secure_partition: partition@3f8000 { label = "secure"; - reg = <0x3f8000 0x2000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + reg = <0x3f8000 0x1000>; // secure info ,reserved for secure boot .if not use , can beused by other way . + }; + user_config_partition: partition@3f9000 { + label = "user_config"; + reg = <0x3f9000 0x1000>; // user_config ,for the secure-boot sign logic changes ,it can release for user . }; dual_mode_partition: partition@3fa000 { label = "dual-mode"; From 33976a6c51a135df9c2818eb88cb15e33537384f Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Wed, 11 Mar 2026 15:30:25 +0800 Subject: [PATCH 39/54] telink: tl3238x: add and fix some config - Open CONFIG_ADC in lighting-app/light-switch-app/contact-sensor-app . - Fix the compilation will fail when CONFIG_LOG=n . Signed-off-by: Fengtai Xie --- examples/contact-sensor-app/telink/prj.conf | 10 ++++++---- examples/light-switch-app/telink/prj.conf | 8 +++++--- examples/lighting-app/telink/prj.conf | 6 ++++-- src/platform/telink/OTAImageProcessorImpl.cpp | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index e132e1087b9e..146538c14625 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -46,26 +46,28 @@ CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n # CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=y +# Enable ADC +CONFIG_ADC=y #compress ota CONFIG_COMPRESS_LZMA=y CONFIG_LZMA=y #ICD SETTING INFO -CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 -#matter switch mode +#matter switch mode # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. CONFIG_DUAL_MODE=1 # open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE -# init should be n +# init should be n CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble -CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n \ No newline at end of file +CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 798d760ba99c..8bb7d139bd65 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -45,25 +45,27 @@ CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n # CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=y +# Enable ADC +CONFIG_ADC=y #compress ota CONFIG_COMPRESS_LZMA=y CONFIG_LZMA=y #ICD SETTING INFO -CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 -#matter switch mode +#matter switch mode # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. CONFIG_DUAL_MODE=1 # open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE -# init should be n +# init should be n CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 7452a8d7e01b..62da82f05891 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -48,7 +48,7 @@ CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE=n # open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE -# init should be n +# init should be n CONFIG_SECURE_PROGRAMMING=n # Enable PWM @@ -56,12 +56,14 @@ CONFIG_PWM=y CONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF00 # Enable Power Management CONFIG_PM=n +# Enable ADC +CONFIG_ADC=y #compress ota CONFIG_COMPRESS_LZMA=n CONFIG_LZMA=n -# matter switch mode +# matter switch mode # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code.should use 4m flash diff --git a/src/platform/telink/OTAImageProcessorImpl.cpp b/src/platform/telink/OTAImageProcessorImpl.cpp index 9f6d02707204..9832e6a0208c 100644 --- a/src/platform/telink/OTAImageProcessorImpl.cpp +++ b/src/platform/telink/OTAImageProcessorImpl.cpp @@ -215,7 +215,7 @@ CHIP_ERROR OTAImageProcessorImpl::RestoreBytes(ByteSpan & aBlock) // Align to the nearest lower multiple of sector size (4 KB) for Flash erase/write downloadedBytesRestored = ROUND_DOWN(downloadedBytesRestored, 0x1000); ChipLogDetail(SoftwareUpdate, "Restored %u/%u bytes", static_cast(downloadedBytesRestored), - static_cast(mParams.totalFileBytes)) + static_cast(mParams.totalFileBytes)); // Reinit Flash Stream with offset ReturnErrorOnFailure(System::MapErrorZephyr(stream_flash_buffered_write(&stream, NULL, 0, true))); From aeb29668a31ae90a4754fbfae4e1f2ae1801e039 Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Thu, 26 Mar 2026 16:55:06 +0800 Subject: [PATCH 40/54] telink: tl3238x: reduce fc time - Accelerate factory_reset run time . Signed-off-by: Fengtai Xie --- src/platform/telink/ThreadStackManagerImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp index 455a9af6e571..c8fd77e449c0 100644 --- a/src/platform/telink/ThreadStackManagerImpl.cpp +++ b/src/platform/telink/ThreadStackManagerImpl.cpp @@ -73,7 +73,7 @@ void ThreadStackManagerImpl::_UnlockThreadStack() #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT void ThreadStackManagerImpl::_WaitOnSrpClearAllComplete() { - k_sem_take(&mSrpClearAllSemaphore, K_SECONDS(2)); + k_sem_take(&mSrpClearAllSemaphore, K_MSEC(500)); } void ThreadStackManagerImpl::_NotifySrpClearAllComplete() From 05341507543af9a793769975e028e98b874f4cf0 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Thu, 26 Mar 2026 13:11:06 +0800 Subject: [PATCH 41/54] telink: tl3238x: enlarge ble stack. - after change the ble lib , the ble stack need to enlarge 256. Signed-off-by: haiwen.xia --- config/telink/chip-module/Kconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index 9a4e7ed821b0..e99532557298 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -181,7 +181,7 @@ if SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX config TL_BLE_CTRL_THREAD_STACK_SIZE default 648 if ZEPHYR_VERSION_3_3 default 768 if SOC_RISCV_TELINK_TL721X - default 840 if SOC_RISCV_TELINK_TL323X + default 1096 if SOC_RISCV_TELINK_TL323X default 712 config TL_BLE_CTRL_MASTER_MAX_NUM From 5aeed00d2c445305d55e21c7c64d858b4253321a Mon Sep 17 00:00:00 2001 From: 0x0023 Date: Fri, 27 Mar 2026 18:58:39 +0800 Subject: [PATCH 42/54] tl323x: Merge SBoot or ZB FW (#428) * Merge SBoot or ZB FW - Add commands to merge Secure Boot or Zigbee FW if exits - Enable BOOT_VALIDATE_SLOT0 but disable BOOT_BANNER to output chip_id Signed-off-by: Damien Ji * Enable BOOT_VALIDATE_SLOT0_ONCE to validate slot0 for only once. Signed-off-by: Damien Ji * update boot signature key file - CONFIG_BOOT_SIGNATURE_KEY_FILE - CONFIG_MCUBOOT_SIGNATURE_KEY_FILE Signed-off-by: Damien Ji * Extend Boot Signature Key File in More Apps - add CONFIG_MCUBOOT_SIGNATURE_KEY_FILE in contact-sensor-app, light-switch-app, lighting-app, and lock-app - Disable CONFIG_BOOT_SIGNATURE_KEY_FILE and CONFIG_MCUBOOT_SIGNATURE_KEY_FILE in configuration files Signed-off-by: Damien Ji --------- Signed-off-by: Damien Ji --- config/telink/app/bootloader.conf | 8 ++ .../telink/app/bootloader_compress_lzma.conf | 9 +- config/telink/chip-module/CMakeLists.txt | 84 ++++++++++++++++++- examples/contact-sensor-app/telink/prj.conf | 2 + examples/light-switch-app/telink/prj.conf | 2 + examples/lighting-app/telink/prj.conf | 2 + examples/lock-app/telink/prj.conf | 25 ++++++ 7 files changed, 128 insertions(+), 4 deletions(-) diff --git a/config/telink/app/bootloader.conf b/config/telink/app/bootloader.conf index a8c3c0c7d8b7..522ddd663bec 100644 --- a/config/telink/app/bootloader.conf +++ b/config/telink/app/bootloader.conf @@ -28,6 +28,7 @@ CONFIG_BOOT_SWAP_USING_SCRATCH=n # Enable this option in case if the whole slot0 image need to be validated # With disabled option the only image magic is validated CONFIG_BOOT_VALIDATE_SLOT0=n +CONFIG_BOOT_VALIDATE_SLOT0_ONCE=y # Required for Zephyr 3.3 and replased with CONFIG_BOOT_MAX_IMG_SECTORS_AUTO in new versions # Maximum number of image sectors supported by the bootloader. @@ -43,3 +44,10 @@ CONFIG_BOOT_MAX_IMG_SECTORS=512 CONFIG_MCUBOOT_LOG_LEVEL_INF=y CONFIG_PICOLIBC=y + +# Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. +CONFIG_BOOT_BANNER=n + +# CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y +# CONFIG_BOOT_SIGNATURE_KEY_FILE="ecdsa_private_key.pem" +# CONFIG_BOOT_SIGNATURE_KEY_FILE="" diff --git a/config/telink/app/bootloader_compress_lzma.conf b/config/telink/app/bootloader_compress_lzma.conf index 429d378279ff..e370e753eb87 100644 --- a/config/telink/app/bootloader_compress_lzma.conf +++ b/config/telink/app/bootloader_compress_lzma.conf @@ -21,6 +21,7 @@ CONFIG_BOOT_UPGRADE_ONLY=y # Enable this option in case if the whole slot0 image need to be validated # With disabled option the only image magic is validated CONFIG_BOOT_VALIDATE_SLOT0=n +CONFIG_BOOT_VALIDATE_SLOT0_ONCE=y # Required for Zephyr 3.3 and replased with CONFIG_BOOT_MAX_IMG_SECTORS_AUTO in new versions # Maximum number of image sectors supported by the bootloader. @@ -46,5 +47,9 @@ CONFIG_COMPRESS_LZMA=y CONFIG_PICOLIBC=y -# ### Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. -CONFIG_BOOT_BANNER=n \ No newline at end of file +# Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. +CONFIG_BOOT_BANNER=n + +# CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y +# CONFIG_BOOT_SIGNATURE_KEY_FILE="ecdsa_private_key.pem" +# CONFIG_BOOT_SIGNATURE_KEY_FILE="" diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 05a9679d3a53..6f74b97df967 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -170,12 +170,45 @@ endif() # Define 'process_binaries' target for collecting final binary to flash # ============================================================================== +set(BLOCK_SIZE "1024") + +if(CONFIG_SOC_RISCV_TELINK_TL323X) +set(SOC "TL323X") + +# Calculate the offset of zigbee partition relative to slot0 start +dt_nodelabel(slot0_partition_path NODELABEL "slot0_partition") +dt_reg_addr(slot0_start PATH ${slot0_partition_path}) +dt_reg_size(slot0_size PATH ${slot0_partition_path}) +message(STATUS "slot0_start: ${slot0_start}") +message(STATUS "slot0_size: ${slot0_size}") + +dt_nodelabel(zb_partition_path NODELABEL "slot0_zb_partition") +dt_reg_addr(zb_start PATH ${zb_partition_path}) +message(STATUS "zb_start: ${zb_start}") + +math(EXPR zb_offset_bytes "${zb_start} - ${slot0_start}" OUTPUT_FORMAT DECIMAL) + +math(EXPR ZB_FW_OFFSET_DECIMAL "${zb_offset_bytes} / ${BLOCK_SIZE}" OUTPUT_FORMAT DECIMAL) +message(STATUS "ZB_FW_OFFSET_DECIMAL: ${ZB_FW_OFFSET_DECIMAL}") + +set(ZB_FILE_PATH "${ZEPHYR_BASE}/${SOC}_FW/ZB/Zigbee-SampleDemo.bin") + +set(SBOOT_FILE_PATH "${ZEPHYR_BASE}/${SOC}_FW/SBOOT/Secure_Bootloader.bin") +math(EXPR SKIP_BYTES_DECIMAL "${CONFIG_MCUBOOT_START_OFFSET} / ${BLOCK_SIZE}" OUTPUT_FORMAT DECIMAL) +message(STATUS "SKIP_BYTES_DECIMAL: ${SKIP_BYTES_DECIMAL}") + +endif() + add_custom_target( process_binaries ALL COMMAND ${Python3_EXECUTABLE} ${CHIP_ROOT}/scripts/tools/telink/process_binaries.py WORKING_DIRECTORY ${PROJECT_BINARY_DIR} ) -add_dependencies(process_binaries ${ZEPHYR_FINAL_EXECUTABLE}) +if(EXISTS ${ZB_FILE_PATH} AND CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_RISCV_TELINK_B9X OR CONFIG_SOC_RISCV_TELINK_TLX)) + add_dependencies(process_binaries west_sign) +else() + add_dependencies(process_binaries ${ZEPHYR_FINAL_EXECUTABLE}) +endif() # ============================================================================== # Define 'build_mcuboot' target for building the MCUBoot bootloader @@ -187,8 +220,55 @@ if (CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_RISCV_TELINK_B9X OR CONFIG_SOC_RIS west build -b ${BASE_BOARD} -d build_mcuboot ${ZEPHYR_BASE}/../bootloader/mcuboot/boot/zephyr -- -DCONFIG_DUAL_MODE=${CONFIG_DUAL_MODE} -DOVERLAY_CONFIG=${GLOBAL_BOOT_CONF_OVERLAY_FILE} -DDTC_OVERLAY_FILE="${GLOBAL_BOOT_DTC_OVERLAY_FILE};${FLASH_DTC_OVERLAY_FILE};${USB_BOOT_DTC_OVERLAY_FILE};${MARS_BOOT_DTC_OVERLAY_FILE}" COMMAND - cp ${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin ${PROJECT_BINARY_DIR}/mcuboot.bin + dd if=${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin of=${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/mcuboot_for_sign.bin bs=${BLOCK_SIZE} skip=${SKIP_BYTES_DECIMAL} conv=notrunc + COMMAND + cp ${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/mcuboot_for_sign.bin ${PROJECT_BINARY_DIR}/zephyr.mcuboot.bin + COMMAND + cp ${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/mcuboot_for_sign.bin ${PROJECT_BINARY_DIR}/mcuboot_for_sign.bin ) + message(STATUS "mcuboot_for_sign.bin is for external signing.") + + if (EXISTS ${SBOOT_FILE_PATH}) + add_custom_target(merge_sboot ALL + COMMAND + dd if=/dev/zero bs=${BLOCK_SIZE} count=${SKIP_BYTES_DECIMAL} | tr '\\000' '\\377' > ${PROJECT_BINARY_DIR}/bootloader_merged.bin + COMMAND + dd if=${SBOOT_FILE_PATH} of=${PROJECT_BINARY_DIR}/bootloader_merged.bin conv=notrunc + COMMAND + dd if=${PROJECT_BINARY_DIR}/zephyr.mcuboot.bin of=${PROJECT_BINARY_DIR}/bootloader_merged.bin bs=${BLOCK_SIZE} seek=${SKIP_BYTES_DECIMAL} conv=notrunc + COMMAND + cp ${PROJECT_BINARY_DIR}/bootloader_merged.bin ${PROJECT_BINARY_DIR}/mcuboot.bin + ) + add_dependencies(merge_sboot build_mcuboot) + message(WARNING "merged secure boot to mcuboot..") + else() + message(WARNING "File ${SBOOT_FILE_PATH} does not exist. merge_sboot target will not be created.") + endif() + + if (EXISTS ${ZB_FILE_PATH}) + add_custom_target(merge_zigbee ALL + COMMAND + cp ${PROJECT_BINARY_DIR}/zephyr.bin ${PROJECT_BINARY_DIR}/zephyr.matter.bin # store matter firmware + COMMAND + dd if=/dev/zero bs=${BLOCK_SIZE} count=${ZB_FW_OFFSETZB_FW_OFFSET} | tr '\\000' '\\377' > ${PROJECT_BINARY_DIR}/dm_merged.bin + COMMAND + dd if=${PROJECT_BINARY_DIR}/zephyr.matter.bin of=${PROJECT_BINARY_DIR}/dm_merged.bin conv=notrunc + COMMAND + dd if=${ZB_FILE_PATH} of=${PROJECT_BINARY_DIR}/dm_merged.bin bs=${BLOCK_SIZE} seek=${ZB_FW_OFFSET_DECIMAL} conv=notrunc + COMMAND + cp ${PROJECT_BINARY_DIR}/dm_merged.bin ${PROJECT_BINARY_DIR}/zephyr.bin + COMMAND + cp ${PROJECT_BINARY_DIR}/dm_merged.bin ${PROJECT_BINARY_DIR}/unsign_merged.bin # store unsign merged firmware + ) + add_custom_target(west_sign ALL + COMMAND + west sign -t imgtool -p ${ZEPHYR_BASE}/../bootloader/mcuboot/scripts/imgtool.py -d ${PROJECT_BINARY_DIR}/.. -- --key ${ZEPHYR_BASE}/../${CONFIG_MCUBOOT_SIGNATURE_KEY_FILE} --slot-size ${slot0_size} + ) + add_dependencies(merge_zigbee ${ZEPHYR_FINAL_EXECUTABLE}) + add_dependencies(west_sign merge_zigbee) + else() + message(WARNING "File ${ZB_FILE_PATH} does not exist. merge_zigbee target will not be created.") + endif() endif() # ============================================================================== diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index 146538c14625..178dd1d40e4e 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -71,3 +71,5 @@ CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n + +# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 8bb7d139bd65..0def5f29710b 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -70,3 +70,5 @@ CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n + +# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index 62da82f05891..ab4202470cab 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -74,3 +74,5 @@ CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n + +# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/lock-app/telink/prj.conf b/examples/lock-app/telink/prj.conf index 7e9df11e659a..6231058a107e 100755 --- a/examples/lock-app/telink/prj.conf +++ b/examples/lock-app/telink/prj.conf @@ -42,3 +42,28 @@ CONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=n # Enable Power Management CONFIG_PM=y + +#compress ota +CONFIG_COMPRESS_LZMA=y +CONFIG_LZMA=y + +#ICD SETTING INFO +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 +CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 +CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 + +#matter switch mode +# config NORMAL_MODE 0 independent matter mode +# ACTION_DUAL_MODE 1 matter action switch mode ,such as by button +# AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. +CONFIG_DUAL_MODE=1 + +# open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE +# init should be n +CONFIG_SECURE_PROGRAMMING=n + +# Enable CHIP-ID via ble +CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n + +# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" From 07397fe23aecff88f7d6438fe5b7da6cc83071ec Mon Sep 17 00:00:00 2001 From: fenton1609 Date: Wed, 15 Apr 2026 08:52:18 +0800 Subject: [PATCH 43/54] telink: tl3238x: update multiple operation lists for mass production (#438) - Add ota event callback . - Add deferred storage attributes for provider . - Increase maximum group number per fabric . - Apply HW Hash and set BOOT_IMG_HASH_DIRECTLY_ON_STORAGE . - Increase the ISR_STACK_SIZE to 1024 . - Increase the SYSTEM_WORKQUEUE_STACK_SIZE to 2048 . - Increase the HEAP_MEM_POOL_SIZE to 1280 . - Increase the COMMON_LIBC_MALLOC_ARENA_SIZE to 20716 . - Increase the NET_IF_MCAST_IPV6_ADDR_COUNT to 47 . - Increase the TL_BLE_CTRL_THREAD_STACK_SIZE to 1536 . - Increase the OPENTHREAD_THREAD_STACK_SIZE to 4096 . - Increase the OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE to 2048 . - Increase the OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS to 40 . - Increase the NET_RX_STACK_SIZE to 2048 . Signed-off-by: Fengtai Xie Co-authored-by: Damien Ji --- .github/workflows/examples-telink.yaml | 2 +- config/telink/app/bootloader.conf | 2 + .../telink/app/bootloader_compress_lzma.conf | 2 + config/telink/chip-module/Kconfig | 4 ++ config/telink/chip-module/Kconfig.defaults | 20 +++--- .../contact-sensor-app/telink/CMakeLists.txt | 1 + examples/contact-sensor-app/telink/prj.conf | 3 + .../light-switch-app/telink/CMakeLists.txt | 1 + examples/light-switch-app/telink/prj.conf | 3 + examples/lighting-app/telink/CMakeLists.txt | 1 + examples/lighting-app/telink/prj.conf | 3 + examples/lock-app/telink/CMakeLists.txt | 1 + examples/lock-app/telink/prj.conf | 9 ++- .../telink/common/include/AppTaskCommon.h | 2 + .../telink/common/src/AppTaskCommon.cpp | 72 +++++++++++++++++++ src/platform/telink/CHIPPlatformConfig.h | 8 +++ 16 files changed, 121 insertions(+), 13 deletions(-) diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index bc6d25a1a577..ee79637f70ee 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -58,7 +58,7 @@ jobs: gh-context: ${{ toJson(github) }} - name: Update Zephyr version 4.1.0 (develop) to specific revision (for developers purpose) - run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 42f57a7692969193ece78fde32354c6208043c25" + run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py d31d26afcd55cea3b43df82dbd51ecefeedf8993" - name: Build tools required for Factory Data # Run test for master and all PRs diff --git a/config/telink/app/bootloader.conf b/config/telink/app/bootloader.conf index 522ddd663bec..00f04d04ab78 100644 --- a/config/telink/app/bootloader.conf +++ b/config/telink/app/bootloader.conf @@ -48,6 +48,8 @@ CONFIG_PICOLIBC=y # Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. CONFIG_BOOT_BANNER=n +CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE=y + # CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y # CONFIG_BOOT_SIGNATURE_KEY_FILE="ecdsa_private_key.pem" # CONFIG_BOOT_SIGNATURE_KEY_FILE="" diff --git a/config/telink/app/bootloader_compress_lzma.conf b/config/telink/app/bootloader_compress_lzma.conf index e370e753eb87..e2fb166e9ef2 100644 --- a/config/telink/app/bootloader_compress_lzma.conf +++ b/config/telink/app/bootloader_compress_lzma.conf @@ -50,6 +50,8 @@ CONFIG_PICOLIBC=y # Disabling the banner is to allow cmd tool to better parse the chip ID, avoid interface. CONFIG_BOOT_BANNER=n +CONFIG_BOOT_IMG_HASH_DIRECTLY_ON_STORAGE=y + # CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y # CONFIG_BOOT_SIGNATURE_KEY_FILE="ecdsa_private_key.pem" # CONFIG_BOOT_SIGNATURE_KEY_FILE="" diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index f351d90e6c14..ff96ec5c0325 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -333,3 +333,7 @@ config SECURE_PROGRAMMING config EXPOSE_CHIP_ID_VIA_BLE bool "Enable CHIP-ID via ble" default n + +config DEFERRED_ATTR_STORAGE + bool "Defer the storage time of attributes" + default n diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index e99532557298..d894a0af9f58 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -79,18 +79,20 @@ config IDLE_STACK_SIZE default 560 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 config ISR_STACK_SIZE - default 800 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 + default 1024 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_W91 config SYSTEM_WORKQUEUE_STACK_SIZE - default 664 if PM && !SOC_RISCV_TELINK_W91 + default 2048 if PM && !SOC_RISCV_TELINK_W91 config HEAP_MEM_POOL_SIZE default 256 if ZEPHYR_VERSION_3_3 + default 1796 if SOC_RISCV_TELINK_TL323X default 1280 config COMMON_LIBC_MALLOC_ARENA_SIZE default 19000 if SOC_RISCV_TELINK_TL321X && !ZEPHYR_VERSION_3_3 default 29448 if SOC_RISCV_TELINK_W91 + default 26584 if SOC_RISCV_TELINK_TL323X default 20716 config NET_IPV6_MLD @@ -98,7 +100,7 @@ config NET_IPV6_MLD default y config NET_IF_MCAST_IPV6_ADDR_COUNT - default 8 if PM + default 47 if PM || SOC_RISCV_TELINK_TL323X default 15 # Network buffers @@ -181,7 +183,7 @@ if SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX config TL_BLE_CTRL_THREAD_STACK_SIZE default 648 if ZEPHYR_VERSION_3_3 default 768 if SOC_RISCV_TELINK_TL721X - default 1096 if SOC_RISCV_TELINK_TL323X + default 1536 if SOC_RISCV_TELINK_TL323X default 712 config TL_BLE_CTRL_MASTER_MAX_NUM @@ -269,7 +271,7 @@ config NVS_LOOKUP_CACHE default y config NVS_LOOKUP_CACHE_SIZE - default 400 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X + default 400 if SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X default 2048 if !PM || SOC_RISCV_TELINK_W91 # Set multiplicator of Name Value Storage (NVS) as 1 to reach NVS sector size 4KB @@ -323,10 +325,10 @@ config IEEE802154_TLX_OPTIMIZATION Improve RF performance in IEEE 802.15.4 communication on TLX SoCs. config OPENTHREAD_THREAD_STACK_SIZE - default 2400 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X + default 4096 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X config OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE - default 608 if PM + default 2048 if PM || SOC_RISCV_TELINK_TL323X default 608 config OPENTHREAD_SLAAC @@ -341,7 +343,7 @@ config OPENTHREAD_DEFAULT_TX_POWER default 11 config OPENTHREAD_IP6_MAX_EXT_MCAST_ADDRS - default 2 if PM + default 40 if PM || SOC_RISCV_TELINK_TL323X default 8 endif # NET_L2_OPENTHREAD @@ -352,7 +354,7 @@ config NET_TX_STACK_SIZE config NET_RX_STACK_SIZE default 2048 if SOC_RISCV_TELINK_W91 - default 664 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X + default 2048 if PM || SOC_RISCV_TELINK_TL321X || SOC_RISCV_TELINK_TL323X # Disable certain parts of Zephyr IPv6 stack config NET_IPV6_NBR_CACHE diff --git a/examples/contact-sensor-app/telink/CMakeLists.txt b/examples/contact-sensor-app/telink/CMakeLists.txt index 745f0f4dc3be..72959d768a95 100755 --- a/examples/contact-sensor-app/telink/CMakeLists.txt +++ b/examples/contact-sensor-app/telink/CMakeLists.txt @@ -38,6 +38,7 @@ target_sources(app PRIVATE src/AppTask.cpp src/ContactSensorManager.cpp src/ZclCallbacks.cpp + ${CHIP_ROOT}/src/app/persistence/DeferredAttributePersistenceProvider.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp diff --git a/examples/contact-sensor-app/telink/prj.conf b/examples/contact-sensor-app/telink/prj.conf index 178dd1d40e4e..294b8666a2cd 100755 --- a/examples/contact-sensor-app/telink/prj.conf +++ b/examples/contact-sensor-app/telink/prj.conf @@ -72,4 +72,7 @@ CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n +# Enable Deferred Store Attribute +CONFIG_DEFERRED_ATTR_STORAGE=n + # CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/light-switch-app/telink/CMakeLists.txt b/examples/light-switch-app/telink/CMakeLists.txt index dde7205b38b0..6ae1d14fc9fb 100755 --- a/examples/light-switch-app/telink/CMakeLists.txt +++ b/examples/light-switch-app/telink/CMakeLists.txt @@ -39,6 +39,7 @@ target_sources(app PRIVATE src/AppTask.cpp src/ZclCallbacks.cpp src/binding-handler.cpp + ${CHIP_ROOT}/src/app/persistence/DeferredAttributePersistenceProvider.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp diff --git a/examples/light-switch-app/telink/prj.conf b/examples/light-switch-app/telink/prj.conf index 0def5f29710b..0e30c8d8fc8d 100755 --- a/examples/light-switch-app/telink/prj.conf +++ b/examples/light-switch-app/telink/prj.conf @@ -71,4 +71,7 @@ CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n +# Enable Deferred Store Attribute +CONFIG_DEFERRED_ATTR_STORAGE=n + # CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/lighting-app/telink/CMakeLists.txt b/examples/lighting-app/telink/CMakeLists.txt index dbdef1d38393..d182edb230a9 100644 --- a/examples/lighting-app/telink/CMakeLists.txt +++ b/examples/lighting-app/telink/CMakeLists.txt @@ -51,6 +51,7 @@ endif() target_sources(app PRIVATE src/AppTask.cpp src/ZclCallbacks.cpp + ${CHIP_ROOT}/src/app/persistence/DeferredAttributePersistenceProvider.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp diff --git a/examples/lighting-app/telink/prj.conf b/examples/lighting-app/telink/prj.conf index ab4202470cab..db26116359f9 100644 --- a/examples/lighting-app/telink/prj.conf +++ b/examples/lighting-app/telink/prj.conf @@ -75,4 +75,7 @@ CONFIG_CHIP_BUTTON_MANAGER_IRQ_MODE=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n +# Enable Deferred Store Attribute +CONFIG_DEFERRED_ATTR_STORAGE=n + # CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/lock-app/telink/CMakeLists.txt b/examples/lock-app/telink/CMakeLists.txt index 384dbdfc288f..059a279b310d 100755 --- a/examples/lock-app/telink/CMakeLists.txt +++ b/examples/lock-app/telink/CMakeLists.txt @@ -40,6 +40,7 @@ target_sources(app PRIVATE src/ZclCallbacks.cpp src/LockManager.cpp src/LockSettingsStorage.cpp + ${CHIP_ROOT}/src/app/persistence/DeferredAttributePersistenceProvider.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp diff --git a/examples/lock-app/telink/prj.conf b/examples/lock-app/telink/prj.conf index 6231058a107e..2b72c8f89c23 100755 --- a/examples/lock-app/telink/prj.conf +++ b/examples/lock-app/telink/prj.conf @@ -48,22 +48,25 @@ CONFIG_COMPRESS_LZMA=y CONFIG_LZMA=y #ICD SETTING INFO -CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 +CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=7500 CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=200 CONFIG_CHIP_ICD_ACTIVE_MODE_THRESHOLD=300 CONFIG_CHIP_ICD_IDLE_MODE_DURATION=900 -#matter switch mode +#matter switch mode # config NORMAL_MODE 0 independent matter mode # ACTION_DUAL_MODE 1 matter action switch mode ,such as by button # AUTO_SWITCH_DUAL_MODE 2 matter auto-switch mode ,such as by scan QR code. CONFIG_DUAL_MODE=1 # open seucre programming , need to open CONFIG_CHIP_FACTORY_DATA and CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE -# init should be n +# init should be n CONFIG_SECURE_PROGRAMMING=n # Enable CHIP-ID via ble CONFIG_EXPOSE_CHIP_ID_VIA_BLE=n +# Enable Deferred Store Attribute +CONFIG_DEFERRED_ATTR_STORAGE=n + # CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/ecdsa_private_key.pem" diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index fadd9d0b2349..f81e497a0173 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -167,6 +167,8 @@ class AppTaskCommon static void UpdateStatusLED(void); + static void OtaEventsHandler(const ChipDeviceEvent * event); + #if CONFIG_CHIP_FACTORY_DATA chip::DeviceLayer::FactoryDataProvider mFactoryDataProvider; #endif diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index c45ae9cf628e..f2a84fb7efa9 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -34,6 +34,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -88,6 +92,37 @@ bool sIsNetworkEnabled = false; bool sIsNetworkAttached = false; bool sHaveBLEConnections = false; +/** + * @brief Set deferred attributes storage + * + * @see Define a custom attribute persister which makes actual write of the CurrentHue, CurrentSaturation, CurrentLevel attributes + * value to the non-volatile storage only when it has remained constant for 5 seconds. This is to reduce the flash wearout when the + * attribute changes frequently as a result of MoveToLevel command. DeferredAttribute object describes a deferred attribute, but + * also holds a buffer with a value to be written, so it must live so long as the DeferredAttributePersistenceProvider object. + * + * @param ATTRIBUTES_ARRAY_SIZE The lenght of the DeferredAttribute array + * @param DEFERRED_STORAGE_TIME The deferred time(ms) to store attributes + */ +#define ATTRIBUTES_ARRAY_SIZE (3U) +#define DEFERRED_STORAGE_TIME (500U) + +DeferredAttribute gPersisters[] = { +#if CONFIG_DEFERRED_ATTR_STORAGE + DeferredAttribute( + ConcreteAttributePath(kExampleEndpointId, Clusters::ColorControl::Id, Clusters::ColorControl::Attributes::CurrentHue::Id)), + DeferredAttribute(ConcreteAttributePath(kExampleEndpointId, Clusters::ColorControl::Id, + Clusters::ColorControl::Attributes::CurrentSaturation::Id)), + DeferredAttribute( + ConcreteAttributePath(kExampleEndpointId, Clusters::LevelControl::Id, Clusters::LevelControl::Attributes::CurrentLevel::Id)) +#endif // CONFIG_DEFERRED_ATTR_STORAGE +}; + +// Deferred persistence will be auto-initialized as soon as the default persistence is initialized +DefaultAttributePersistenceProvider gSimpleAttributePersistence; +DeferredAttributePersistenceProvider gDeferredAttributePersister(gSimpleAttributePersistence, + Span(gPersisters, ATTRIBUTES_ARRAY_SIZE), + System::Clock::Milliseconds32(DEFERRED_STORAGE_TIME)); + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE || CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE #include #include @@ -506,6 +541,7 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void) VerifyOrDie(sTestEventTriggerDelegate.AddHandler(&sOtaTestEventTriggerHandler) == CHIP_NO_ERROR); #endif (void) initParams.InitializeStaticResourcesBeforeServerInit(); + VerifyOrDie(gSimpleAttributePersistence.Init(initParams.persistentStorageDelegate) == CHIP_NO_ERROR); #if APP_SET_DEVICE_INFO_PROVIDER gExampleDeviceInfoProvider.SetStorageDelegate(initParams.persistentStorageDelegate); chip::DeviceLayer::SetDeviceInfoProvider(&gExampleDeviceInfoProvider); @@ -515,6 +551,9 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void) initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams)); + /* Add deferred storage attribute for provider */ + app::SetAttributePersistenceProvider(&gDeferredAttributePersister); + ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); @@ -947,6 +986,36 @@ void AppTaskCommon::TriggerMicroSpeechEventHandler(AppEvent * aEvent) } #endif +void AppTaskCommon::OtaEventsHandler(const ChipDeviceEvent * event) +{ + switch (event->OtaStateChanged.newState) + { + case DeviceLayer::kOtaDownloadInProgress: + ChipLogProgress(DeviceLayer, "OTA image download in progress\n"); + break; + case DeviceLayer::kOtaDownloadComplete: + ChipLogProgress(DeviceLayer, "OTA image download complete\n"); + break; + case DeviceLayer::kOtaDownloadFailed: + ChipLogProgress(DeviceLayer, "OTA image download failed\n"); + break; + case DeviceLayer::kOtaDownloadAborted: + ChipLogProgress(DeviceLayer, "OTA image download aborted\n"); + break; + case DeviceLayer::kOtaApplyInProgress: + ChipLogProgress(DeviceLayer, "OTA image apply in progress\n"); + break; + case DeviceLayer::kOtaApplyComplete: + ChipLogProgress(DeviceLayer, "OTA image apply complete\n"); + break; + case DeviceLayer::kOtaApplyFailed: + ChipLogProgress(DeviceLayer, "OTA image apply failed\n"); + break; + default: + break; + } +} + void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg */) { switch (event->Type) @@ -1064,6 +1133,9 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* UpdateStatusLED(); #endif break; + case DeviceEventType::kOtaStateChanged: + AppTaskCommon::OtaEventsHandler(event); + break; default: break; } diff --git a/src/platform/telink/CHIPPlatformConfig.h b/src/platform/telink/CHIPPlatformConfig.h index 421578b65917..0deaad9e4906 100644 --- a/src/platform/telink/CHIPPlatformConfig.h +++ b/src/platform/telink/CHIPPlatformConfig.h @@ -118,6 +118,14 @@ #endif // CONFIG_CHIP_MAX_FABRICS #endif // CHIP_CONFIG_MAX_FABRICS +#ifndef CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC +#define CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC 2 +#endif // CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC + +#ifndef CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTRY +#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTRY (4 * CHIP_CONFIG_MAX_GROUP_ENDPOINTS_PER_FABRIC) +#endif // CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTR + #ifdef CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS #define CHIP_CONFIG_DEVICE_MAX_ACTIVE_CASE_CLIENTS CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS #endif // CONFIG_CHIP_MAX_ACTIVE_CASE_CLIENTS From 56b73281e1441868960c636ce1db2cb2fc5aeaf4 Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Fri, 10 Apr 2026 11:47:26 +0800 Subject: [PATCH 44/54] telink: tl3238x: ota resume optimization for non-supporting ecosystems - Add OTA resume watchdog to avoid the question . Signed-off-by: Fengtai Xie --- src/platform/telink/OTAImageProcessorImpl.cpp | 14 +++++++++++++- src/platform/telink/OTAImageProcessorImpl.h | 9 ++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/platform/telink/OTAImageProcessorImpl.cpp b/src/platform/telink/OTAImageProcessorImpl.cpp index 9832e6a0208c..15d651ff0136 100644 --- a/src/platform/telink/OTAImageProcessorImpl.cpp +++ b/src/platform/telink/OTAImageProcessorImpl.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -141,6 +140,16 @@ CHIP_ERROR OTAImageProcessorImpl::Apply() #endif } +void OTAImageProcessorImpl::ResumeWatchdogHandler(System::Layer * systemLayer, void * context) +{ + auto * self = static_cast(context); + ChipLogError(SoftwareUpdate, "Resume not supported by OTA provider"); + + LogErrorOnFailure(KeyValueStoreMgr().Delete(kDownloadedBytes)); + LogErrorOnFailure(KeyValueStoreMgr().Delete(kImageDigest)); + self->mDownloader->EndDownload(CHIP_ERROR_NOT_IMPLEMENTED); +} + CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock) { VerifyOrReturnError(mDownloader != nullptr, CHIP_ERROR_INCORRECT_STATE); @@ -171,9 +180,12 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock) { TEMPORARY_RETURN_IGNORED mDownloader->SkipData(downloadedBytesRestored - aBlock.size()); downloadedBytesRestored = 0; + TEMPORARY_RETURN_IGNORED SystemLayer().StartTimer( + System::Clock::Milliseconds32(kResumeWatchdogTimeoutMs), ResumeWatchdogHandler, this); } else { + TEMPORARY_RETURN_IGNORED DeviceLayer::SystemLayer().CancelTimer(ResumeWatchdogHandler, this); TEMPORARY_RETURN_IGNORED mDownloader->FetchNextData(); } } diff --git a/src/platform/telink/OTAImageProcessorImpl.h b/src/platform/telink/OTAImageProcessorImpl.h index 19ebb291fa98..cb1eb3e41f61 100644 --- a/src/platform/telink/OTAImageProcessorImpl.h +++ b/src/platform/telink/OTAImageProcessorImpl.h @@ -18,6 +18,7 @@ #include #include +#include #include namespace chip { @@ -46,15 +47,17 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface CHIP_ERROR ProcessHeader(ByteSpan & aBlock); CHIP_ERROR InitFlashStream(size_t offset); CHIP_ERROR RestoreBytes(ByteSpan & aBlock); + static void ResumeWatchdogHandler(System::Layer * systemLayer, void * context); OTADownloader * mDownloader = nullptr; OTAImageHeaderParser mHeaderParser; uint8_t mBuffer[kBufferSize]; // Define non-volatile storage keys for DownloadedBytes and ImageDigest. - static constexpr char kDownloadedBytes[] = "DownloadedBytes"; - static constexpr char kImageDigest[] = "ImageDigest"; - uint64_t downloadedBytesRestored = 0; + static constexpr char kDownloadedBytes[] = "DownloadedBytes"; + static constexpr char kImageDigest[] = "ImageDigest"; + static constexpr uint16_t kResumeWatchdogTimeoutMs = 6000; + uint64_t downloadedBytesRestored = 0; }; } // namespace DeviceLayer From f7456986e6b1d5550867f2df8c1002d774cb2d85 Mon Sep 17 00:00:00 2001 From: "haiwen.xia" Date: Wed, 15 Apr 2026 10:41:27 +0800 Subject: [PATCH 45/54] telink: 3238x: improve the speed of factory_reset. - change the logic from the ScheduleFactoryReset() to earse NVS. Signed-off-by: haiwen.xia --- .../telink/common/src/AppTaskCommon.cpp | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index f2a84fb7efa9..c16a07e16386 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -122,12 +122,19 @@ DefaultAttributePersistenceProvider gSimpleAttributePersistence; DeferredAttributePersistenceProvider gDeferredAttributePersister(gSimpleAttributePersistence, Span(gPersisters, ATTRIBUTES_ARRAY_SIZE), System::Clock::Milliseconds32(DEFERRED_STORAGE_TIME)); - -#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE || CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE #include #include #include #include +/*MATTER NVS*/ +#define MATTER_NVS_PARTITION storage_partition +#define MATTER_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(MATTER_NVS_PARTITION) +#define MATTER_NVS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(MATTER_NVS_PARTITION) +#define MATTER_NVS_PARTITION_SIZE FIXED_PARTITION_SIZE(MATTER_NVS_PARTITION) +const struct device * matter_nvs_dev = MATTER_NVS_PARTITION_DEVICE; + +#if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE || CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + #define OPCODE_FACTORY_RESET 0 #define OPCODE_SWITCH_ZIGBEE 1 // include init state and matter paired state. @@ -204,15 +211,10 @@ user_para_t user_para; #define ZB_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(ZB_NVS_PARTITION) #define ZB_NVS_START_ADR FIXED_PARTITION_OFFSET(ZB_NVS_PARTITION) -/*MATTER NVS*/ -#define MATTER_NVS_PARTITION storage_partition -#define MATTER_NVS_PARTITION_DEVICE FIXED_PARTITION_DEVICE(MATTER_NVS_PARTITION) -#define MATTER_NVS_PARTITION_OFFSET FIXED_PARTITION_OFFSET(MATTER_NVS_PARTITION) -#define MATTER_NVS_PARTITION_SIZE FIXED_PARTITION_SIZE(MATTER_NVS_PARTITION) const struct device * flash_para_dev = DUAL_MODE_PARTITION_DEVICE; const struct device * zb_para_dev = ZB_NVS_PARTITION_DEVICE; -const struct device * matter_nvs_dev = MATTER_NVS_PARTITION_DEVICE; + constexpr int kDnssTimeout = 60000; #if !CONFIG_MCUMGR_TRANSPORT_BT @@ -835,10 +837,15 @@ void AppTaskCommon::FactoryResetHandler(AppEvent * aEvent) k_timer_stop(&sFactoryResetTimer); sFactoryResetCntr = 0; - chip::Server::GetInstance().ScheduleFactoryReset(); #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE dual_mode_switch(OPCODE_FACTORY_RESET); + #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + dual_mode_auto_switch(OPCODE_FACTORY_RESET); #endif + /* clear matter nvs for unclean info in matter nvs */ + LOG_INF("Factory Reset TC: Erase matter nvs directly and reboot"); + flash_erase(matter_nvs_dev, MATTER_NVS_PARTITION_OFFSET, MATTER_NVS_PARTITION_SIZE); + sys_reboot(SYS_REBOOT_WARM); } } From 56aac5e53ade59f431121afeab8252bd50c4e80b Mon Sep 17 00:00:00 2001 From: interfer Date: Mon, 20 Apr 2026 21:47:32 +0300 Subject: [PATCH 46/54] [Telink] Fix CNET 4.12 thread switching --- src/platform/telink/BLEManagerImpl.cpp | 10 +++++++++- src/platform/telink/ThreadStackManagerImpl.cpp | 16 +++++++++++++++- src/platform/telink/ThreadStackManagerImpl.h | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 4f8e7d94d1e2..4907abddf8e6 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -1048,6 +1048,14 @@ BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) ChipLogDetail(DeviceLayer, "HandleOperationalNetworkEnabled"); CHIP_ERROR error = CHIP_NO_ERROR; + if (!ThreadStackMgrImpl().IsReadyToAttach()) + { + // Ignore operational-network notifications once the one-time BLE->Thread + // handoff is complete. Pure Thread-to-Thread switches should be handled + // by the Thread stack directly. + return CHIP_NO_ERROR; + } + /* On first commissioning BLE disconnects before switching to Thread operational network. All subsequent Thread operational network changes are handled in a bit different way */ if (!mReadyToAttachThread) @@ -1071,7 +1079,6 @@ BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) error = PlatformMgr().PostEvent(&attachEvent); VerifyOrExit(error == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "PostEvent err: %" CHIP_ERROR_FORMAT, error.Format())); - TEMPORARY_RETURN_IGNORED ThreadStackMgrImpl().CommitConfiguration(); } exit: @@ -1105,6 +1112,7 @@ void BLEManagerImpl::SwitchToIeee802154(void) // Init Thread ThreadStackMgrImpl().SetRadioBlocked(false); TEMPORARY_RETURN_IGNORED ThreadStackMgrImpl().SetThreadEnabled(true); + ThreadStackMgrImpl().SetReadyToAttach(false); } #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp index c8fd77e449c0..7114720b2067 100644 --- a/src/platform/telink/ThreadStackManagerImpl.cpp +++ b/src/platform/telink/ThreadStackManagerImpl.cpp @@ -103,6 +103,17 @@ ThreadStackManagerImpl::_AttachToThreadNetwork(const Thread::OperationalDataset if (dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && callback == nullptr) return CHIP_NO_ERROR; + if (dataset.IsCommissioned() && current_dataset.IsCommissioned() && !dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && + IsThreadEnabled()) + { + result = SetThreadProvision(dataset.AsByteSpan()); + if (result == CHIP_NO_ERROR && callback != nullptr) + { + callback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0); + } + return result; + } + if (mRadioBlocked || mReadyToAttach) { /* On Telink platform it's not possible to rise Thread network when its used by BLE, @@ -111,7 +122,10 @@ ThreadStackManagerImpl::_AttachToThreadNetwork(const Thread::OperationalDataset if (result == CHIP_NO_ERROR) { mReadyToAttach = true; - callback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0); + if (callback != nullptr) + { + callback->OnResult(NetworkCommissioning::Status::kSuccess, CharSpan(), 0); + } } } else diff --git a/src/platform/telink/ThreadStackManagerImpl.h b/src/platform/telink/ThreadStackManagerImpl.h index 84f7a0755739..983a2df24524 100644 --- a/src/platform/telink/ThreadStackManagerImpl.h +++ b/src/platform/telink/ThreadStackManagerImpl.h @@ -60,6 +60,7 @@ class ThreadStackManagerImpl final : public ThreadStackManager, // ===== Methods that implement the ThreadStackManager abstract interface. CHIP_ERROR _InitThreadStack(); void SetRadioBlocked(bool state) { mRadioBlocked = state; } + void SetReadyToAttach(bool state) { mReadyToAttach = state; } bool IsReadyToAttach(void) const { return mReadyToAttach; } void Finalize(void); CHIP_ERROR CommitConfiguration(void); From 99fa85e61381cd4f6d91e62246547fb0bfaee36b Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Mon, 20 Apr 2026 18:55:44 +0000 Subject: [PATCH 47/54] Restyled by clang-format --- src/platform/telink/BLEManagerImpl.cpp | 1 - src/platform/telink/ThreadStackManagerImpl.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 4907abddf8e6..8e84961322d3 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -1078,7 +1078,6 @@ BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) error = PlatformMgr().PostEvent(&attachEvent); VerifyOrExit(error == CHIP_NO_ERROR, ChipLogError(DeviceLayer, "PostEvent err: %" CHIP_ERROR_FORMAT, error.Format())); - } exit: diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp index 7114720b2067..509bc044a11f 100644 --- a/src/platform/telink/ThreadStackManagerImpl.cpp +++ b/src/platform/telink/ThreadStackManagerImpl.cpp @@ -103,8 +103,8 @@ ThreadStackManagerImpl::_AttachToThreadNetwork(const Thread::OperationalDataset if (dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && callback == nullptr) return CHIP_NO_ERROR; - if (dataset.IsCommissioned() && current_dataset.IsCommissioned() && !dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && - IsThreadEnabled()) + if (dataset.IsCommissioned() && current_dataset.IsCommissioned() && + !dataset.AsByteSpan().data_equal(current_dataset.AsByteSpan()) && IsThreadEnabled()) { result = SetThreadProvision(dataset.AsByteSpan()); if (result == CHIP_NO_ERROR && callback != nullptr) From 0ddd85ca6c51e934a36ad3656fbd6e91e9d1c96b Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Wed, 11 Feb 2026 15:38:52 +0200 Subject: [PATCH 48/54] [Telink] Fix TC-OPCREDS-3.6 test (#43028) * [Telink] Fix TC-OPCREDS-3.6 test * Restyled by clang-format * [Telink] Decrease CHIP_MAX_FABRICS for BOARD_TL3218X_RETENTION. * [Telink] Fix default value for BOARD_TL3218X_RETENTION --------- Co-authored-by: Restyled.io --- config/telink/chip-module/Kconfig | 5 +- config/telink/chip-module/Kconfig.defaults | 4 + .../telink/common/src/AppTaskCommon.cpp | 73 +++++++++---------- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index ff96ec5c0325..7904131eaf21 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -284,14 +284,15 @@ config CHIP_PERSISTENT_SUBSCRIPTIONS # selecting experimental for this feature since there is an issue with multiple controllers. select EXPERIMENTAL -if CHIP_PERSISTENT_SUBSCRIPTIONS - config CHIP_MAX_FABRICS int "Maximum number of Matter fabrics" + default 3 if BOARD_TL3218X_RETENTION default 5 help The maximum number of Matter fabrics that device can be joined to. +if CHIP_PERSISTENT_SUBSCRIPTIONS + config CHIP_MAX_ACTIVE_CASE_CLIENTS int "Maximum number of outgoing CASE sessions" default CHIP_MAX_FABRICS diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index d894a0af9f58..343740c30cdf 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -279,6 +279,10 @@ config NVS_LOOKUP_CACHE_SIZE config SETTINGS_NVS_SECTOR_SIZE_MULT default 1 +# Enable extended discovery +config CHIP_EXTENDED_DISCOVERY + default y + # Enable OpenThread config NET_L2_OPENTHREAD default y if !WIFI diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index c16a07e16386..92a837e0bd27 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -318,51 +318,48 @@ class AppCallbacks : public AppDelegate AppCallbacks sCallbacks; } // namespace -class AppFabricTableDelegate : public FabricTable::Delegate +static void DoDelayedFactoryReset(struct k_work * work) { - void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) - { - if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) - { - ChipLogProgress(DeviceLayer, "Erasing settings partition"); + ChipLogProgress(DeviceLayer, "Erasing settings partition"); - // TC-OPCREDS-3.6 (device doesn't need to reboot automatically after the last fabric is removed) can't use FactoryReset - void * storage = nullptr; - int status = settings_storage_get(&storage); + // TC-OPCREDS-3.6 (device doesn't need to reboot automatically after the last fabric is removed) can't use FactoryReset + void * storage = nullptr; + int status = settings_storage_get(&storage); - if (!status) - { - status = nvs_clear(static_cast(storage)); - } + if (!status) + { + status = nvs_clear(static_cast(storage)); + } - if (!status) - { - status = nvs_mount(static_cast(storage)); - } + if (!status) + { + status = nvs_mount(static_cast(storage)); + } - if (status) - { - ChipLogError(DeviceLayer, "Storage clear failed: %d", status); - } + if (status) + { + ChipLogError(DeviceLayer, "Storage clear failed: %d", status); + } #ifdef CONFIG_TFLM_FEATURE - AppTask::MicroSpeechProcessStop(); + AppTask::MicroSpeechProcessStop(); #endif - // Reboot in case of failed commissioning to allow new pairing via BLE - if (sIsCommissioningFailed) - { - ChipLogProgress(DeviceLayer, "Rebooting board"); - sys_reboot(SYS_REBOOT_WARM); - } - else - { - #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE - dual_mode_switch(OPCODE_FACTORY_RESET); - #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE - dual_mode_auto_switch(OPCODE_FACTORY_RESET); - #endif - ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); - chip::Server::GetInstance().ScheduleFactoryReset(); - } + // Reboot in case of failed commissioning to allow new pairing via BLE + if (sIsCommissioningFailed) + { + ChipLogProgress(DeviceLayer, "Rebooting board"); + sys_reboot(SYS_REBOOT_WARM); + } +} + +static k_work_delayable sDelayedFactoryResetWork = Z_WORK_DELAYABLE_INITIALIZER(DoDelayedFactoryReset); + +class AppFabricTableDelegate : public FabricTable::Delegate +{ + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) + { + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + k_work_schedule(&sDelayedFactoryResetWork, K_SECONDS(2)); } } }; From 6ff99bb9a6b0e1967535804dfd25a78be4f796c9 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Mon, 27 Apr 2026 13:49:40 +0800 Subject: [PATCH 49/54] telink: 3238x: fix incorrect factory reset logic for commissioned device. - fix incorrect factory reset logic for commissioned device when fabric is 0. Signed-off-by: Hao Wu --- examples/platform/telink/common/src/AppTaskCommon.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 92a837e0bd27..ecafdf8ce785 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -349,6 +349,16 @@ static void DoDelayedFactoryReset(struct k_work * work) ChipLogProgress(DeviceLayer, "Rebooting board"); sys_reboot(SYS_REBOOT_WARM); } + else + { + #if CONFIG_DUAL_MODE == CONFIG_ACTION_DUAL_MODE + dual_mode_switch(OPCODE_FACTORY_RESET); + #elif CONFIG_DUAL_MODE == CONFIG_AUTO_SWITCH_DUAL_MODE + dual_mode_auto_switch(OPCODE_FACTORY_RESET); + #endif + ChipLogProgress(DeviceLayer, "Do factory_reset and reboot"); + chip::Server::GetInstance().ScheduleFactoryReset(); + } } static k_work_delayable sDelayedFactoryResetWork = Z_WORK_DELAYABLE_INITIALIZER(DoDelayedFactoryReset); From 121ca49d18bdc90dd5d312533994d67238642149 Mon Sep 17 00:00:00 2001 From: "zhenghuan.zhang" <102295942+pulin1103@users.noreply.github.com> Date: Thu, 21 May 2026 20:03:16 +0800 Subject: [PATCH 50/54] [common][platform][openthread] Fix race condition during Thread stack initialization (observed on NXP Zephyr platform) (#71368) (#463) * [common][platform][openthread] Add OT mutex lock when calling OT api to avoid race condition during initialization * The mutex lock is necessary for Zephyr because the openthread thread is initialized by the kernel init, and therefore it runs before the Matter initialization * so when we InitThreadStack, we must ensure that the OT api calls are protected with a mutex lock to avoid concurrent access to OT shared resources * Restyled by whitespace * [common][platform][openthread] Add comment to explain why the LockThreadStack() is required --------- Signed-off-by: Dina Benamar Co-authored-by: dinabenamar <108664279+dinabenamar@users.noreply.github.com> Co-authored-by: Restyled.io --- .../OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index d7c5887f5ee7..69b77e3499ae 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -689,6 +689,10 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::ConfigureThreadS mOTInst = otInst; + // Lock the OpenThread stack to prevent race conditions with OpenThread's internal operations. + // On some platforms (e.g., Zephyr), OpenThread may already be running before Matter initialization completes. + Impl()->LockThreadStack(); + // Arrange for OpenThread to call the OnOpenThreadStateChange method whenever a // state change occurs. Note that we reference the OnOpenThreadStateChange method // on the concrete implementation class so that that class can override the default @@ -724,6 +728,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::ConfigureThreadS exit: + Impl()->UnlockThreadStack(); ChipLogProgress(DeviceLayer, "OpenThread started: %s", otThreadErrorToString(otErr)); return err; } From 5fcb8ed404e914eb12ee9c27eda4dffd869807a1 Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Wed, 13 May 2026 17:18:39 +0300 Subject: [PATCH 51/54] [Telink] Fix OTA_EXTRA_ARGS config apply (#72034) --- config/zephyr/ota-image.cmake | 4 ++-- config/zephyr/ota-image_sysbuild.cmake | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/zephyr/ota-image.cmake b/config/zephyr/ota-image.cmake index 0d0108aa7579..bfb1f9dfc0f8 100644 --- a/config/zephyr/ota-image.cmake +++ b/config/zephyr/ota-image.cmake @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2021-2026 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. @@ -59,7 +59,7 @@ function(chip_ota_image TARGET_NAME) ) endif() - separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CHIP_OTA_IMAGE_EXTRA_ARGS}") + separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CONFIG_CHIP_OTA_IMAGE_EXTRA_ARGS}") list(APPEND OTA_ARGS ${OTA_EXTRA_ARGS}) list(APPEND OTA_ARGS ${ARG_INPUT_FILES}) diff --git a/config/zephyr/ota-image_sysbuild.cmake b/config/zephyr/ota-image_sysbuild.cmake index 88968ba15ecb..6a3703107e3d 100644 --- a/config/zephyr/ota-image_sysbuild.cmake +++ b/config/zephyr/ota-image_sysbuild.cmake @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Project CHIP Authors +# Copyright (c) 2021-2026 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. @@ -82,7 +82,7 @@ function(chip_ota_image TARGET_NAME) ) endif() - separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CHIP_OTA_IMAGE_EXTRA_ARGS}") + separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CONFIG_CHIP_OTA_IMAGE_EXTRA_ARGS}") list(APPEND OTA_ARGS ${OTA_EXTRA_ARGS}) list(APPEND OTA_ARGS ${ARG_INPUT_FILES}) From 17651752f60190bac7ee82f999a1de92d2bcf716 Mon Sep 17 00:00:00 2001 From: 0x0023 Date: Mon, 1 Jun 2026 16:47:28 +0800 Subject: [PATCH 52/54] Fix OpenThread path selection based on CONFIG_OPENTHREAD_TELINK_LIBRARY (#3) * Update Telink OpenThread Path Selection fixes the incorrect OpenThread repository selection logic in Telink platform builds: - Explicitly set ZEPHYR_OPENTHREAD_MODULE_DIR to use standard openthread path when CONFIG_OPENTHREAD_TELINK_LIBRARY is not enabled - Replace the directory-existence check with CONFIG_OPENTHREAD_TELINK_LIBRARY based path selection - Ensures build logs always print the correct git revision information matching the actually used OpenThread repository Now builds correctly distinguish between: - CONFIG_OPENTHREAD_TELINK_LIBRARY=y: uses modules/lib/openthread_telink_lib - CONFIG_OPENTHREAD_TELINK_LIBRARY=n: uses modules/lib/openthread Signed-off-by: Damien Ji * Restyled by clang-format - update zephyr revision to 3a3683860df05a6e9d441a66f50097c9c03258bb Signed-off-by: Damien Ji --------- Signed-off-by: Damien Ji Co-authored-by: Restyled.io --- .github/workflows/examples-telink.yaml | 2 +- config/telink/chip-module/CMakeLists.txt | 5 +- examples/platform/telink/build_info.cmake | 70 +++++++++++++++++++ .../telink/common/src/AppTaskCommon.cpp | 9 +++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index ee79637f70ee..7b7cc2203bb4 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -58,7 +58,7 @@ jobs: gh-context: ${{ toJson(github) }} - name: Update Zephyr version 4.1.0 (develop) to specific revision (for developers purpose) - run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py d31d26afcd55cea3b43df82dbd51ecefeedf8993" + run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 3a3683860df05a6e9d441a66f50097c9c03258bb" - name: Build tools required for Factory Data # Run test for master and all PRs diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 6f74b97df967..5d744915570b 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -71,7 +71,10 @@ matter_add_flags(-DMBEDTLS_USER_CONFIG_FILE=<${CONFIG_MBEDTLS_CFG_FILE}>) if (CONFIG_OPENTHREAD_TELINK_LIBRARY) set(ZEPHYR_OPENTHREAD_MODULE_DIR ${ZEPHYR_BASE}/../modules/lib/openthread_telink_lib CACHE STRING INTERNAL) - message(STATUS "OpenThread used as precompiled Telink library, path: ${ZEPHYR_OPENTHREAD_MODULE_DIR}") + message(STATUS "OpenThread used as precompiled Telink library, path: ${ZEPHYR_OPENTHREAD_MODULE_DIR}") +else() + set(ZEPHYR_OPENTHREAD_MODULE_DIR ${ZEPHYR_BASE}/../modules/lib/openthread CACHE STRING INTERNAL) + message(STATUS "OpenThread used from source, path: ${ZEPHYR_OPENTHREAD_MODULE_DIR}") endif() if (CONFIG_CHIP_OPENTHREAD_CONFIG) diff --git a/examples/platform/telink/build_info.cmake b/examples/platform/telink/build_info.cmake index f6a7ccfaee34..32c695db51f4 100644 --- a/examples/platform/telink/build_info.cmake +++ b/examples/platform/telink/build_info.cmake @@ -109,12 +109,66 @@ else() set(TELINK_HAL_LOCAL_STATUS "") endif() +# OpenThread info +if(CONFIG_OPENTHREAD_TELINK_LIBRARY) + set(OPENTHREAD_PATH "${ZEPHYR_BASE}/../modules/lib/openthread_telink_lib") +else() + set(OPENTHREAD_PATH "${ZEPHYR_BASE}/../modules/lib/openthread") +endif() + +execute_process( + COMMAND git -C ${OPENTHREAD_PATH} rev-parse HEAD + OUTPUT_VARIABLE OT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET +) + +execute_process( + COMMAND git -C ${OPENTHREAD_PATH} rev-parse --abbrev-ref HEAD + OUTPUT_VARIABLE OT_BRANCH_NAME + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET +) + +execute_process( + COMMAND git -C ${OPENTHREAD_PATH} show -s --format=%cd --date=format:%Y-%m-%d HEAD + OUTPUT_VARIABLE OT_COMMIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET +) + +execute_process( + COMMAND bash -c "git -C ${OPENTHREAD_PATH} remote get-url \$(git -C ${OPENTHREAD_PATH} remote | head -n 1)" + OUTPUT_VARIABLE OT_REMOTE_URL + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET +) + +execute_process( + COMMAND git -C ${OPENTHREAD_PATH} diff --quiet + RESULT_VARIABLE OT_LOCAL_STATUS + ERROR_QUIET +) + +if(OT_LOCAL_STATUS) + set(OT_LOCAL_STATUS "-dirty") +else() + set(OT_LOCAL_STATUS "") +endif() + execute_process( COMMAND git -C ${ZEPHYR_BASE}/../modules/hal/telink show -s --format=%cd --date=format:%Y-%m-%d OUTPUT_VARIABLE TELINK_HAL_COMMIT_DATE OUTPUT_STRIP_TRAILING_WHITESPACE ) +execute_process( + COMMAND git -C ${OPENTHREAD_PATH} describe --tags --exact-match + OUTPUT_VARIABLE OT_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET +) + target_compile_definitions(app PRIVATE MATTER_COMMIT_HASH="${MATTER_COMMIT_HASH}" MATTER_BRANCH="${MATTER_BRANCH_NAME}" @@ -132,6 +186,14 @@ target_compile_definitions(app PRIVATE TELINK_HAL_COMMIT_HASH="${TELINK_HAL_COMMIT_HASH}" TELINK_HAL_LOCAL_STATUS="${TELINK_HAL_LOCAL_STATUS}" TELINK_HAL_COMMIT_DATE="${TELINK_HAL_COMMIT_DATE}" + + OPENTHREAD_PATH="${OPENTHREAD_PATH}" + OT_COMMIT_HASH="${OT_COMMIT_HASH}" + OT_BRANCH="${OT_BRANCH_NAME}" + OT_COMMIT_DATE="${OT_COMMIT_DATE}" + OT_REMOTE_URL="${OT_REMOTE_URL}" + OT_LOCAL_STATUS="${OT_LOCAL_STATUS}" + OT_TAG="${OT_TAG}" ) message(STATUS "Matter revision:") @@ -146,3 +208,11 @@ message(STATUS " remote: ${ZEPHYR_REMOTE_URL}") message(STATUS "HAL revision:") message(STATUS " commit: ${TELINK_HAL_COMMIT_HASH} ${TELINK_HAL_COMMIT_DATE}") + +message(STATUS "OpenThread revision:") +message(STATUS " path: ${OPENTHREAD_PATH}") +message(STATUS " branch: ${OT_BRANCH_NAME} ${OT_COMMIT_HASH} ${OT_COMMIT_DATE}") +if(OT_TAG) + message(STATUS " tag: ${OT_TAG}") +endif() +message(STATUS " remote: ${OT_REMOTE_URL}") diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index ecafdf8ce785..cc128cdca838 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -500,6 +500,15 @@ void AppTaskCommon::PrintFirmwareInfo(void) LOG_DBG("\t branch: %s %.8s%s %s", ZEPHYR_BRANCH, ZEPHYR_COMMIT_HASH, ZEPHYR_LOCAL_STATUS, ZEPHYR_COMMIT_DATE); LOG_DBG("\t remote: %s", ZEPHYR_REMOTE_URL); LOG_DBG("\t HAL commit: %.8s%s %s", TELINK_HAL_COMMIT_HASH, TELINK_HAL_LOCAL_STATUS, TELINK_HAL_COMMIT_DATE); + + LOG_DBG("OpenThread revision: "); + LOG_DBG("\t path: %s", OPENTHREAD_PATH); + LOG_DBG("\t remote: %s", OT_REMOTE_URL); + if (strlen(OT_TAG) > 0) + { + LOG_DBG("\t tag: %s", OT_TAG); + } + LOG_DBG("\t branch: %s %.8s%s %s", OT_BRANCH, OT_COMMIT_HASH, OT_LOCAL_STATUS, OT_COMMIT_DATE); #endif } CHIP_ERROR AppTaskCommon::InitCommonParts(void) From 3142988fbcb3b94b3762b1301c3323b683bad66a Mon Sep 17 00:00:00 2001 From: fenton1609 Date: Wed, 17 Jun 2026 16:57:55 +0800 Subject: [PATCH 53/54] [Telink] Check matter network state when power-on (#469) * [Telink] Check if the thread dataset and fabirc were successfully written. Signed-off-by: Fengtai Xie --- .../telink/common/src/AppTaskCommon.cpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index cc128cdca838..037f29743e7b 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -26,6 +26,7 @@ #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include "ThreadUtil.h" +#include #elif CHIP_DEVICE_CONFIG_ENABLE_WIFI #include #include @@ -435,6 +436,28 @@ void AppTaskCommon::DnssTimerTimeoutCallback(k_timer * timer) } #endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +static void PowerOnNetworkCheck(void) +{ + Thread::OperationalDataset curDataset; + CHIP_ERROR err = DeviceLayer::ThreadStackMgrImpl().GetThreadProvision(curDataset); + bool hasDataset = (err == CHIP_NO_ERROR); // Check if stored OpenThread dataset + + uint8_t fabricNum = chip::Server::GetInstance().GetFabricTable().FabricCount(); + + if (!hasDataset && fabricNum == 0) { // New device + return; + } else if (hasDataset && fabricNum > 0) { // Device successfully commissioned + return; + } else if (hasDataset && fabricNum == 0) { + ChipLogProgress(DeviceLayer, "Thread dataset exists, but matter uncommissioned\n"); + } else { + return; + } + k_work_schedule(&sDelayedFactoryResetWork, K_SECONDS(2)); +} +#endif + CHIP_ERROR AppTaskCommon::StartApp(void) { CHIP_ERROR err = GetAppTask().Init(); @@ -607,6 +630,11 @@ CHIP_ERROR AppTaskCommon::InitCommonParts(void) return err; } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + // TODO: Defer this validation until chip::Server is fully initialized to avoid crashes + PowerOnNetworkCheck(); +#endif + return CHIP_NO_ERROR; } From 71a86011eaa48c33bfd1b71a046f5225eb3cc937 Mon Sep 17 00:00:00 2001 From: fenton1609 Date: Fri, 3 Jul 2026 14:07:28 +0800 Subject: [PATCH 54/54] telink: tl3238x: add commissioning flag and fix compilations (#471) - Improve the commissioning flag process and maintain boundary security . - Copy a mcuboot.bin from build_mcuboot/.../zephyr.bin in CMakeLists . Signed-off-by: Fengtai Xie --- config/telink/chip-module/CMakeLists.txt | 9 +++++++-- examples/platform/telink/common/src/AppTaskCommon.cpp | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 5d744915570b..a1d97f44512a 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -242,11 +242,16 @@ if (CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_RISCV_TELINK_B9X OR CONFIG_SOC_RIS COMMAND cp ${PROJECT_BINARY_DIR}/bootloader_merged.bin ${PROJECT_BINARY_DIR}/mcuboot.bin ) - add_dependencies(merge_sboot build_mcuboot) message(WARNING "merged secure boot to mcuboot..") else() - message(WARNING "File ${SBOOT_FILE_PATH} does not exist. merge_sboot target will not be created.") + # Since there is no secure boot, no offset is needed. + # Simultaneously check if CONFIG_MCUBOOT_START_OFFSET is 0x0. + add_custom_target(merge_sboot ALL + cp ${PROJECT_BINARY_DIR}/../modules/chip-module/build_mcuboot/zephyr/zephyr.bin ${PROJECT_BINARY_DIR}/mcuboot.bin + ) + message(WARNING "File ${SBOOT_FILE_PATH} does not exist.") endif() + add_dependencies(merge_sboot build_mcuboot) if (EXISTS ${ZB_FILE_PATH}) add_custom_target(merge_zigbee ALL diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 037f29743e7b..dda0db0598a8 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -306,7 +306,7 @@ class AppCallbacks : public AppDelegate void OnCommissioningSessionEstablishmentStarted() override { sIsCommissioningFailed = false; } void OnCommissioningSessionStarted() override { isComissioningStarted = true; } void OnCommissioningSessionStopped() override { isComissioningStarted = false; } - void OnCommissioningSessionEstablishmentError(CHIP_ERROR err) override { sIsCommissioningFailed = true; } + void OnCommissioningSessionEstablishmentError(CHIP_ERROR err) override { sIsCommissioningFailed = true; isComissioningStarted = false; } #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE void OnCommissioningWindowClosed() override {