From 33962769e5c37678857152e368a3fb44e6e9d393 Mon Sep 17 00:00:00 2001 From: Fengtai Xie Date: Tue, 31 Dec 2024 13:49:51 +0800 Subject: [PATCH] riscv: telink: add functional features for tlsr9528 and tl3218 - add user token storage partition based on JSON automatic build . - optimize waiting time to 500ms for avoid excessive blockage after factory reset . - optimize startup time to be less than 600ms . Signed-off-by: Fengtai Xie --- config/telink/chip-module/CMakeLists.txt | 12 + config/telink/chip-module/Kconfig.defaults | 8 + examples/lighting-app/telink/process_token.py | 233 ++++++++++++++++++ .../lighting-app/telink/src/ZclCallbacks.cpp | 78 ++++++ examples/lighting-app/telink/token.json | 52 ++++ .../telink/common/include/AppTaskCommon.h | 22 ++ .../telink/common/src/AppTaskCommon.cpp | 140 +++++++++++ .../platform/telink/common/src/mainCommon.cpp | 122 +++++++++ .../telink/ThreadStackManagerImpl.cpp | 2 +- src/platform/telink/tl3218x.overlay | 12 +- src/platform/telink/tlsr9528a.overlay | 4 +- 11 files changed, 676 insertions(+), 9 deletions(-) create mode 100644 examples/lighting-app/telink/process_token.py create mode 100644 examples/lighting-app/telink/token.json diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 0f925cdeffc904..33ea8e98fa0e54 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -213,4 +213,16 @@ if (CONFIG_CHIP_FACTORY_DATA_BUILD) telink_generate_factory_data() endif() +# ============================================================================== +# Define 'build_user_token' target for building the user token image +# ============================================================================== + +if(DEFINED CONFIG_USER_TOKEN AND CONFIG_USER_TOKEN STREQUAL "y") + add_custom_target(build_user_token ALL + COMMAND ${Python3_EXECUTABLE} ${CHIP_ROOT}/examples/lighting-app/telink/process_token.py + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + ) + add_dependencies(build_user_token ${ZEPHYR_FINAL_EXECUTABLE}) +endif() + endif() # CONFIG_CHIP diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index 4d1c86f8e3de41..7c51b7618a7af7 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -280,6 +280,14 @@ config I2C_LED default n select I2C +config USER_TOKEN + bool "Generate the user token image" + default n + +config STARTUP_OPTIMIZATION + bool "Optimize startup speed" + default n + # Set multiplicator of Name Value Storage (NVS) as 1 to reach NVS sector size 4KB # nvs_sector_size = flash_page_size * mult = 4KB * 1 = 4KB config SETTINGS_NVS_SECTOR_SIZE_MULT diff --git a/examples/lighting-app/telink/process_token.py b/examples/lighting-app/telink/process_token.py new file mode 100644 index 00000000000000..44a1da8e08ef67 --- /dev/null +++ b/examples/lighting-app/telink/process_token.py @@ -0,0 +1,233 @@ +import json +import os + + +def find_json(json_path): + """ + Find token.json in given path. + + Args: + json_path (string): The file path of token.json. + + Returns: + json_data (structure): The json data structure. + """ + try: + with open(json_path, 'r') as f: + json_data = json.load(f) + + except FileNotFoundError: + print(json_path + " is not find, abort.") + exit(1) + + except json.JSONDecodeError: + print(json_path + " parse error, abort.") + exit(1) + + return json_data + + +def get_json_data(json_data): + """ + Get the json data from token.json. + + Args: + json_data (structure): The data structure of json. + + Returns: + [ start_addr, sizeByte, write_data ]: The array of json data. + """ + startAddr = json_data.get("offset") + sizeByte = json_data.get("sizeB") + writeData = json_data.get("data") + + return [startAddr, sizeByte, writeData] + + +def intervals_intersect(interval1, interval2): + if interval1[1] <= interval2[0] or interval1[0] >= interval2[1]: + return False # no intersection return False + else: + return True + + +def find_intersection(interval1, interval2): + if not intervals_intersect(interval1, interval2): + return [] + + start = max(interval1[0], interval2[0]) + end = min(interval1[1], interval2[1]) + + return [hex(start), hex(end)] + + +def two_find_intersection(intervalArry, interval): + for inter in intervalArry: + intersection = find_intersection(inter, interval) + if len(intersection) != 0: # has intersection + print("Intersection: ", end="\n") + print(intersection, end="\n") + return -1 + return 0 + + +def curOffsetAddrCheck(curOffset, curSizeB, intervalArry, token_bin_size): + curOffset_INT = int(curOffset, 16) + + result = two_find_intersection( + intervalArry, + [curOffset_INT + 0, curOffset_INT + curSizeB] + ) + if result == (-1): + print("\ncurOffset: " + str(curOffset) + ",curSizeB: " + str(curSizeB), end="\n") + + print("\nThe current write offset address is invalid,", end="\n") + print("there is a risk of overwriting the previous write interval,", end="\n") + print("abort!", end="\n") + + exit(1) + + if (curOffset_INT + curSizeB) >= token_bin_size: + print("curOffset: " + curOffset + ",curSizeB: " + curSizeB, end="\n") + + print("The current write offset address is invalid,", end="\n") + print("exceed the write range of the token.bin,", end="\n") + print("abort!", end="\n") + + exit(1) + + +def offsetNewSet(preOffset, preSizeB, curOffset): + _TMP_ = curOffset.split("0x") + + if len(_TMP_) == 1: # use pre offset + pre sizeB to calculate cur offset + curOffset = hex( + int(preOffset, 16) + preSizeB + ) + + return curOffset + + +def covertData(data): + _TMP_ = data.split("0x") + + if len(_TMP_) == 1: + return [format(ord(char), '02x') for char in _TMP_[0]] + else: + return [Str.strip().replace(',', '') for Str in _TMP_[1:]] + + +def adjustWrittenData(sizeB, data, offset, baseVAL="ff"): + dataLen = len(data) + + if sizeB == dataLen: + return data + elif sizeB > dataLen: + return (data + ([baseVAL] * (sizeB - dataLen))) + elif sizeB < dataLen: + print("offset: " + str(offset) + ", sizeB: " + str(sizeB) + ", dataLen: " + str(dataLen), end="\n") + print("sizeB < len(data), illegal operation, abort!", end="\n") + exit(1) + + +def generate_token(token_bin_path, offset, data): + """ + Generate token.bin according to the data of token.json. + + Args: + token_bin_path (string): The path of token.bin for new generate. + addr (int): Location of written data. + data (string): The data to be written. + """ + try: + with open(token_bin_path, 'r+b') as f: + f.seek(int(offset, 16)) + + for val in data: + f.write(bytes.fromhex(val)) + + except IOError: + print("An error occurred while open or write to the bin, abort.") + exit(1) + + +def main(): + current_abs_path = os.path.dirname(os.path.abspath(__file__)) + # print(current_abs_path) + + token_json_path = current_abs_path + "/token.json" + token_bin_path = "./token.bin" + + token_bin_size = 4096 # 4KB + + # Create a bin with all values of '0xff' + with open(token_bin_path, 'wb+') as f: + f.write(bytes([0xff] * token_bin_size)) + + # Find the token.json. + _JSON_DATA_ = find_json( + token_json_path + ) + + preOffset = "null" + preSizeB = -1 + + intervalArry = [] + + for json_data in _JSON_DATA_: + # Get the json data. + offset, sizeB, data = get_json_data(json_data) + + if (sizeB == 0): + continue + + # Init preOffset and preSizeB. + if (preOffset == "null") or (preSizeB == -1): + preOffset = offset + preSizeB = sizeB + + # Get a new offset addr. + newOffset = offsetNewSet( + preOffset, + preSizeB, + offset + ) + # print(newOffset, end = "\t") + # print(sizeB, end = "\n") + + # Check if the current write offset address is valid. + curOffsetAddrCheck( + newOffset, + sizeB, + intervalArry, + token_bin_size + ) + + # Covert input data and get the new write data. + covertArray = covertData(data) + newData = adjustWrittenData(sizeB, covertArray, newOffset, "ff") + # print(covertArray, end = "\n") + # print(newData, end = "\n\n") + + # Generate token bin. + generate_token( + token_bin_path, + newOffset, + newData + ) + + # Update preOffset and preSizeB. + preOffset = newOffset + preSizeB = sizeB + # Use to two way find intersection. + intervalArry.append([ + int(preOffset, 16) + 0, + int(preOffset, 16) + preSizeB + ]) + # print(intervalArry, end="\n\n") + + print("Generate successfully for the token.bin.") + + +if __name__ == '__main__': + main() diff --git a/examples/lighting-app/telink/src/ZclCallbacks.cpp b/examples/lighting-app/telink/src/ZclCallbacks.cpp index 8b49fe6d3642ef..da46144f4db414 100644 --- a/examples/lighting-app/telink/src/ZclCallbacks.cpp +++ b/examples/lighting-app/telink/src/ZclCallbacks.cpp @@ -30,6 +30,47 @@ LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); using namespace chip; using namespace chip::app::Clusters; +#if CONFIG_STARTUP_OPTIMIZATION +#include "AppTaskCommon.h" + +static uint8_t latest_level = 0; +#define CLUTER_SOTRE_TIMEOUT 500 +#define TRANSTION_TIMER_INIT_FLAG 0x55 +#define TRANSTION_TIMER_DEINIT_FLAG 0x00 + +struct k_timer LevelChangeTimer; +static int timer_period = CLUTER_SOTRE_TIMEOUT; +static uint8_t init_timer = TRANSTION_TIMER_INIT_FLAG; + +static void LevelTimeoutCallback(struct k_timer * timer) +{ + if (!timer) + { + return; + } + + cluster_startup_para cluster_para; + if (read_cluster_para(&cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail read cluster parameter when execute LevelTimeoutCallback\n"); + } + } + if (cluster_para.level != latest_level) + { + cluster_para.level = latest_level; + if (store_cluster_para(&cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail store cluster parameter when execute LevelTimeoutCallback\n"); + } + } + } +} +#endif // CONFIG_STARTUP_OPTIMIZATION + void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) { @@ -125,4 +166,41 @@ void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & } } #endif + +#if CONFIG_STARTUP_OPTIMIZATION + if (init_timer == TRANSTION_TIMER_INIT_FLAG) + { + k_timer_init(&LevelChangeTimer, &LevelTimeoutCallback, nullptr); + init_timer = TRANSTION_TIMER_DEINIT_FLAG; + } + + if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id) + { + cluster_startup_para cluster_para; + if (read_cluster_para(&cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail read cluster parameter when clusterId is OnOff\n"); + } + } + if (cluster_para.onoff != *value) + { + cluster_para.onoff = *value; + if (store_cluster_para(&cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail store cluster parameter when clusterId is OnOff\n"); + } + } + } + } + else if (clusterId == LevelControl::Id && attributeId == LevelControl::Attributes::CurrentLevel::Id) + { + latest_level = *value; + k_timer_stop(&LevelChangeTimer); + k_timer_start(&LevelChangeTimer, K_MSEC(timer_period), K_NO_WAIT); + } +#endif // CONFIG_STARTUP_OPTIMIZATION } diff --git a/examples/lighting-app/telink/token.json b/examples/lighting-app/telink/token.json new file mode 100644 index 00000000000000..d63bab322c5fa5 --- /dev/null +++ b/examples/lighting-app/telink/token.json @@ -0,0 +1,52 @@ +[ + { + "name": "NOTE", + "sizeB": 0, + "description_1": "The following is only test data.", + "description_2": "This json item will no execute when sizeB = 0.", + "description_3": "Please make your changes and re-compile matter using (-p).", + "description_4": "The new token.bin will be generated under the ${project}/build/zephyr." + }, + { + "offset": "0x00", + "sizeB": 32, + "data": "bulb CWS", + "description": "Basic Cluster Model Identifier, 32 Char" + }, + { + "offset": "0x40", + "sizeB": 1, + "data": "0x01", + "description": "Basic Cluster Hardware Version, uint 8" + }, + { + "offset": "", + "sizeB": 3, + "data": "0xaa, 0x12", + "description": "Basic Cluster Generic Device type, uint 8" + }, + { + "offset": "", + "sizeB": 2, + "data": "0xaa, 0x56", + "description": "Basic Cluster Generic Device type, uint 8" + }, + { + "offset": "0x50", + "sizeB": 16, + "data": "LED2024", + "description": "Basic Cluster Product Code, 16 Octet" + }, + { + "offset": "0x60", + "sizeB": 1, + "data": "0x02", + "description": "Configuration of Product Type, uint 8" + }, + { + "offset": "", + "sizeB": 2, + "data": "0x05", + "description": "Basic Cluster Generic Device type, uint 8" + } +] diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index 4440673b1e1db8..97e4991b042b9d 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -91,6 +91,28 @@ extern uint8_t para_lightness; extern uint8_t sBoot_zb; #endif +#if CONFIG_STARTUP_OPTIMIZATION +#define USER_CLUSTER_PARTITION user_cluster_partition +#define USER_CLUSTER_PARTITION_DEVICE FIXED_PARTITION_DEVICE(USER_CLUSTER_PARTITION) +#define USER_CLUSTER_PARTITION_OFFSET FIXED_PARTITION_OFFSET(USER_CLUSTER_PARTITION) +#define USER_CLUSTER_PARTITION_SIZE FIXED_PARTITION_SIZE(USER_CLUSTER_PARTITION) + +typedef struct +{ + uint8_t onoff; + uint8_t level; + uint8_t rfu[30]; +} cluster_startup_para; + +extern volatile bool uart_init_flag; + +void set_debug_flag(bool flag); +volatile bool read_debug_flag(void); +void init_cluster_partition(void); +int store_cluster_para(cluster_startup_para * data); +int read_cluster_para(cluster_startup_para * data); +#endif // CONFIG_STARTUP_OPTIMIZATION + #include using namespace ::chip; diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index c7faaf7deafb76..0bac810417c30f 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -141,6 +141,130 @@ class AppCallbacks : public AppDelegate AppCallbacks sCallbacks; } // namespace +#if CONFIG_STARTUP_OPTIMIZATION +volatile bool uart_init_flag = false; +const struct device * cluster_para_dev = USER_CLUSTER_PARTITION_DEVICE; + +uint32_t cluster_para_addr = USER_CLUSTER_PARTITION_OFFSET; +#define CLUSTER_PARA_LEN (sizeof(cluster_startup_para)) +#define USER_CLUSTER_PARTITION_END (USER_CLUSTER_PARTITION_OFFSET + USER_CLUSTER_PARTITION_SIZE) + +void set_debug_flag(bool flag) +{ + uart_init_flag = flag; +} + +volatile bool read_debug_flag(void) +{ + return uart_init_flag; +} + +void clear_cluster_para(void) +{ + flash_erase(cluster_para_dev, USER_CLUSTER_PARTITION_OFFSET, USER_CLUSTER_PARTITION_SIZE); + cluster_para_addr = USER_CLUSTER_PARTITION_OFFSET; +} + +void init_cluster_partition(void) +{ + uint32_t i, cur_addr; + cluster_startup_para t_cmp; + cluster_startup_para t_cmp_back; + memset((void *) (&t_cmp_back), 0xff, CLUSTER_PARA_LEN); + + for (i = 0;; i++) + { + cur_addr = USER_CLUSTER_PARTITION_OFFSET + i * CLUSTER_PARA_LEN; + if (cur_addr >= USER_CLUSTER_PARTITION_END) + { + clear_cluster_para(); + if (uart_init_flag) + { + printk("The partition is full, clear and redirect to:0x%x\n", cluster_para_addr); + } + break; + } + + flash_read(cluster_para_dev, cur_addr, &t_cmp, CLUSTER_PARA_LEN); + if (memcmp(&t_cmp, &t_cmp_back, CLUSTER_PARA_LEN) == 0) // read t_cmp is 0xff + { + cluster_para_addr = cur_addr; + if (uart_init_flag) + { + printk("Init partition to:0x%x\n", cluster_para_addr); + } + return; + } + } +} + +int store_cluster_para(cluster_startup_para * data) +{ + if (data == NULL) + { + if (uart_init_flag) + { + printk("The data that needs to be stored is NULL\n"); + } + return -1; + } + if (cluster_para_addr >= (USER_CLUSTER_PARTITION_END - CLUSTER_PARA_LEN)) + { + clear_cluster_para(); + } + + flash_write(cluster_para_dev, cluster_para_addr, data, CLUSTER_PARA_LEN); + cluster_para_addr += CLUSTER_PARA_LEN; + return 0; +} + +int read_cluster_para(cluster_startup_para * data) +{ + if (data == NULL) + { + if (uart_init_flag) + { + printk("The data to be read is NULL\n"); + } + return -1; + } + if (cluster_para_addr >= USER_CLUSTER_PARTITION_END) + { + clear_cluster_para(); + if (uart_init_flag) + { + printk("The read address exceeds partition, clear and redirect to:0x%x\n", cluster_para_addr); + } + return -1; + } + if ((cluster_para_addr - CLUSTER_PARA_LEN) < USER_CLUSTER_PARTITION_OFFSET) + { + if (uart_init_flag) + { + printk("The partition is all NULL\n"); + } + return -1; + } + + cluster_startup_para t_cmp; + cluster_startup_para t_cmp_back; + memset((void *) (&t_cmp_back), 0xff, CLUSTER_PARA_LEN); + + flash_read(cluster_para_dev, (cluster_para_addr - CLUSTER_PARA_LEN), &t_cmp, CLUSTER_PARA_LEN); + if (memcmp(&t_cmp, &t_cmp_back, CLUSTER_PARA_LEN) == 0) // read t_cmp is 0xff, error + { + clear_cluster_para(); + if (uart_init_flag) + { + printk("The previous data was not successfully written\n"); + } + return -1; + } + memcpy(data, &t_cmp, CLUSTER_PARA_LEN); + return 0; +} +#endif // CONFIG_STARTUP_OPTIMIZATION + #if CONFIG_DUAL_MODE_SWTICH void FactoryResetExtHandler(void) { @@ -148,6 +272,10 @@ void FactoryResetExtHandler(void) flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE); // Erase ZigBee NVS data during factory reset flash_erase(zb_para_dev, ZB_NVS_START_ADR, ZB_NVS_SEC_SIZE); +#if CONFIG_STARTUP_OPTIMIZATION + // Need to erase cluster para parition + flash_erase(cluster_para_dev, USER_CLUSTER_PARTITION_OFFSET, USER_CLUSTER_PARTITION_SIZE); +#endif // CONFIG_STARTUP_OPTIMIZATION } #endif @@ -867,6 +995,18 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* sBoot_zb = 0; flash_erase(flash_para_dev, USER_PARTITION_OFFSET, USER_PARTITION_SIZE); flash_write(flash_para_dev, USER_PARTITION_OFFSET, &val, 1); +#if CONFIG_STARTUP_OPTIMIZATION + cluster_startup_para cluster_para; + cluster_para.onoff = light_para.onoff; + cluster_para.level = light_para.level; + if (store_cluster_para(&cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail store cluster parameter after commissioning complete\n"); + } + } +#endif // CONFIG_STARTUP_OPTIMIZATION printk("Commissioning complete; Matter commissioned flag set.\n"); } break; diff --git a/examples/platform/telink/common/src/mainCommon.cpp b/examples/platform/telink/common/src/mainCommon.cpp index 3f68acab099528..d62f291595fee2 100644 --- a/examples/platform/telink/common/src/mainCommon.cpp +++ b/examples/platform/telink/common/src/mainCommon.cpp @@ -142,8 +142,130 @@ void matter_nvs_raw_demo(void) #endif +#if CONFIG_STARTUP_OPTIMIZATION +#include "AppTaskCommon.h" +#include +#include +#include +#include +#include +#include + +struct k_timer PwmChangeTimer; +static PWM_POOL_DEFINE(pwm_pool); +struct pwm_pool_data * pwm_data = &pwm_pool; +static const struct device * flash_para_dev = USER_PARTITION_DEVICE; + +/** + * @brief Parameters which is used to PWM gradual change + * + * @see The follow are just a basic configuration, + * and it is only open the blue light. Users can make + * modifications according to actual situation. + * + * @param PWM_CHANGE_TOTAL_TIME_MS Total duration time of gradual change + * @param PWM_CHANGE_PRE_STEP_MS The interval for PWM gradual change + * + */ +#define ENUM_BLUE (PwmManager::EAppPwm_Blue) +/* EAppPwm_Blue enum is 4, corresponds to channel 2 in overlay */ +#define PWM_CHANNEL_BLUE ((uint32_t) ENUM_BLUE - 2) +#define PWM_CHANNEL_TO_BIT(CHANNEL) ((CHANNEL == 0) ? FLD_PWM0_EN : BIT(CHANNEL)) +#define BIT_PWM_CHANNEL_BLUE PWM_CHANNEL_TO_BIT(PWM_CHANNEL_BLUE) + +#define PWM_CHANGE_TOTAL_TIME_MS (400U) +#define PWM_CHANGE_PRE_STEP_MS (8U) +/* The maximum count of PWM gradual change */ +#define PWM_STEP_CNT_MAX (PWM_CHANGE_TOTAL_TIME_MS / PWM_CHANGE_PRE_STEP_MS) +/* The calculation of the pulse cycle during PWM gradual change */ +#define PWM_PULSE_CYCLE(period, level, cnt) ((period / (255 * PWM_STEP_CNT_MAX)) * (level) * (cnt)) + +static uint32_t cnt = 1; +static uint8_t cur_level = 0; +static uint32_t timer_period = PWM_CHANGE_PRE_STEP_MS; + +static void init_startup_para(void) +{ + cluster_startup_para light_cluster_para; + if (read_cluster_para(&light_cluster_para) != 0) + { + if (uart_init_flag) + { + printk("Fail read cluster parameter when execute init_startup_para\n"); + } + } + + if (light_cluster_para.onoff == 1) + { + cur_level = light_cluster_para.level; + } + else + { // OFF || ERROR + cur_level = 0; + timer_period = 0; + } +} + +static void PwmSetTimeoutCallback(struct k_timer * timer) +{ + if (!timer) + { + return; + } + + pwm_set_dt(&pwm_data->out[ENUM_BLUE], pwm_data->out[ENUM_BLUE].period, + PWM_PULSE_CYCLE(pwm_data->out[ENUM_BLUE].period, cur_level, cnt)); + pwm_set_start((pwm_en_e) (BIT_PWM_CHANNEL_BLUE)); + + if (cnt >= PWM_STEP_CNT_MAX) + { + k_timer_stop(timer); + if (uart_init_flag) + { + printk("The current pulse cycle after gradual change: %d\n", + PWM_PULSE_CYCLE(pwm_data->out[ENUM_BLUE].period, cur_level, cnt)); + } + } + + cnt++; +} +#endif // CONFIG_STARTUP_OPTIMIZATION + +void early_proc_cluster(void) +{ +#if CONFIG_STARTUP_OPTIMIZATION + unsigned char val; + flash_read(flash_para_dev, USER_PARTITION_OFFSET, &val, 1); + if (val == USER_MATTER_PAIR_VAL) + { + init_cluster_partition(); + init_startup_para(); + if (timer_period != 0) + { + k_timer_init(&PwmChangeTimer, &PwmSetTimeoutCallback, nullptr); + k_timer_start(&PwmChangeTimer, K_MSEC(timer_period), K_MSEC(timer_period)); + } + } +#endif // CONFIG_STARTUP_OPTIMIZATION +} + +typedef void (*p_early_proc)(void); +p_early_proc early_proc_cluster_f = early_proc_cluster; + int main(void) { +#if CONFIG_STARTUP_OPTIMIZATION + /** + * @brief Control log output for startup optimizate module. + * + * @see It only takes effect when the startup optimizate + * module is opened. Note than the flag can only be set + * to true after the execution of the main function. + */ + set_debug_flag(true); + printk("cur_level:%d, timer_period:%d\n", cur_level, timer_period); +#endif // CONFIG_STARTUP_OPTIMIZATION + #if defined(CONFIG_USB_DEVICE_STACK) && !defined(CONFIG_CHIP_PW_RPC) usb_enable(NULL); #endif /* CONFIG_USB_DEVICE_STACK */ diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp index 41d9189ab5f215..869443e2cbd033 100644 --- a/src/platform/telink/ThreadStackManagerImpl.cpp +++ b/src/platform/telink/ThreadStackManagerImpl.cpp @@ -71,7 +71,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() diff --git a/src/platform/telink/tl3218x.overlay b/src/platform/telink/tl3218x.overlay index a87a89d59dab06..27e3bbb4f8f5be 100644 --- a/src/platform/telink/tl3218x.overlay +++ b/src/platform/telink/tl3218x.overlay @@ -45,18 +45,18 @@ &pwm0 { /* On board RGB LEDs */ pinctrl-ch0 = <&pwm_ch0_pb1_default>; - pinctrl-ch2 = <&pwm_ch1_pb2_default>; - pinctrl-ch1 = <&pwm_ch2_pb0_default>; + pinctrl-ch1 = <&pwm_ch1_pb0_default>; + pinctrl-ch2 = <&pwm_ch2_pb2_default>; }; &pinctrl { pwm_ch0_pb1_default: pwm_ch0_pb1_default { pinmux = ; }; - pwm_ch1_pb2_default: pwm_ch1_pb2_default { - pinmux = ; + pwm_ch1_pb0_default: pwm_ch1_pb0_default { + pinmux = ; }; - pwm_ch2_pb0_default: pwm_ch2_pb0_default { - pinmux = ; + pwm_ch2_pb2_default: pwm_ch2_pb2_default { + pinmux = ; }; }; diff --git a/src/platform/telink/tlsr9528a.overlay b/src/platform/telink/tlsr9528a.overlay index d80b61f12434cf..cd6a6c0063d867 100644 --- a/src/platform/telink/tlsr9528a.overlay +++ b/src/platform/telink/tlsr9528a.overlay @@ -45,8 +45,8 @@ &pwm0 { /* On board RGB LEDs */ pinctrl-ch0 = <&pwm_ch0_pe7_default>; - pinctrl-ch2 = <&pwm_ch1_pd1_default>; - pinctrl-ch1 = <&pwm_ch2_pd0_default>; + pinctrl-ch1 = <&pwm_ch1_pd1_default>; + pinctrl-ch2 = <&pwm_ch2_pd0_default>; }; &pinctrl {