diff --git a/CMakeLists.txt b/CMakeLists.txt index 0be9ad00..1348a41d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,10 +9,12 @@ if(CONFIG_HAS_TELINK_DRIVERS) # SOC configuration for Telink RISC-V series string(REGEX REPLACE "^telink_" "" SOC_FAMILY ${CONFIG_SOC_SERIES}) + + if(CONFIG_SOC_RISCV_TELINK_B91 OR CONFIG_SOC_RISCV_TELINK_B92 OR CONFIG_SOC_RISCV_TELINK_TL321X OR CONFIG_SOC_RISCV_TELINK_TL721X) add_subdirectory(hal_v1) -elseif(CONFIG_SOC_RISCV_TELINK_TL322X OR CONFIG_SOC_RISCV_TELINK_TL323X) +elseif(CONFIG_SOC_RISCV_TELINK_TL322X OR CONFIG_SOC_RISCV_TELINK_TL323X OR CONFIG_SOC_RISCV_TELINK_TL523X) add_subdirectory(hal_v2) else() message(FATAL_ERROR "Not supported SOC") diff --git a/Kconfig b/Kconfig index 95952dcc..220504be 100644 --- a/Kconfig +++ b/Kconfig @@ -8,7 +8,7 @@ config HAL_TELINK_V1 config HAL_TELINK_V2 bool "Telink HAL V2" - depends on SOC_RISCV_TELINK_TL322X || SOC_RISCV_TELINK_TL323X + depends on SOC_RISCV_TELINK_TL322X || SOC_RISCV_TELINK_TL323X || SOC_RISCV_TELINK_TL523X default y if HAL_TELINK_V1 diff --git a/hal_v1/tlsr9/crypto/Kconfig b/hal_v1/tlsr9/crypto/Kconfig index 795380d9..a1ace27c 100644 --- a/hal_v1/tlsr9/crypto/Kconfig +++ b/hal_v1/tlsr9/crypto/Kconfig @@ -7,8 +7,6 @@ if TELINK_B9X_MBEDTLS_HW_ACCELERATION || TELINK_B9X_TINYCRYPT_HW_ACCELERATION || choice prompt "Telink crypto back-ends log level" default TELINK_CRYPTO_BACKEND_LOG_LEVEL_INFO - help - This option selects log level for Telink crypto back-ends. config TELINK_CRYPTO_BACKEND_LOG_LEVEL_CRIT bool "Critical" config TELINK_CRYPTO_BACKEND_LOG_LEVEL_WARN diff --git a/hal_v2/CMakeLists.txt b/hal_v2/CMakeLists.txt index 9178cc7a..f85b0f06 100644 --- a/hal_v2/CMakeLists.txt +++ b/hal_v2/CMakeLists.txt @@ -7,7 +7,7 @@ # SOC configuration for Telink RISC-V series string(REGEX REPLACE "^telink_" "" SOC_FAMILY ${CONFIG_SOC_SERIES}) -elseif(CONFIG_SOC_RISCV_TELINK_TL321X) +if(CONFIG_SOC_RISCV_TELINK_TL321X) set(SOC "TL321X") set(LIB_SOC_NAME "tl321x") message(STATUS "Configuring for SOC: TELINK_TL321X") @@ -23,6 +23,10 @@ elseif(CONFIG_SOC_RISCV_TELINK_TL323X) set(SOC "TL323X") set(LIB_SOC_NAME "tl323x") message(STATUS "Configuring for SOC: TELINK_TL323X") +elseif(CONFIG_SOC_RISCV_TELINK_TL523X) + set(SOC "TL523X") + set(LIB_SOC_NAME "tl523x") + message(STATUS "Configuring for SOC: TELINK_TL523X") else() message(FATAL_ERROR "Not supported SOC") endif() diff --git a/hal_v2/fetch_sdk.sh b/hal_v2/fetch_sdk.sh index 5c4891ac..00a3a65e 100755 --- a/hal_v2/fetch_sdk.sh +++ b/hal_v2/fetch_sdk.sh @@ -2,33 +2,157 @@ # # Downloading Telink BLE SDK. # -# Usage: ./fetch_sdk.sh +# Usage: ./fetch_sdk.sh [repo_url] [target] # Copyright (c) 2026 Telink Semiconductor # SPDX-License-Identifier: Apache-2.0 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) -REPO_URL="https://github.com/telink-semi/tl_ble_sdk.git" -TARGET_COMMIT="bf886feb6cb78dac40b4fc34c8cc1cec1316bf14" +# default values +DEFAULT_REPO_URL="https://github.com/telink-semi/tl_ble_sdk_zephyr.git" +DEFAULT_TARGET="b1ba6612464d56c8fac1382b1ada36d1e83532da" + +# parse parameters +REPO_URL="${1:-$DEFAULT_REPO_URL}" +TARGET="${2:-$DEFAULT_TARGET}" DEST_DIR="$SCRIPT_DIR/tl_ble_sdk" -echo "dest dir: $DEST_DIR" +# show help message +show_help() { + echo "Usage: $0 [repo_url] [target]" + echo "" + echo "Parameters:" + echo " repo_url - Git repository URL (default: $DEFAULT_REPO_URL)" + echo " target - Commit hash, branch name, or tag (default: $DEFAULT_TARGET)" + echo "" + echo "Examples:" + echo " $0 # Use default values" + echo " $0 https://github.com/xxx/sdk.git main # Clone main branch" + echo " $0 https://github.com/xxx/sdk.git v1.2.3 # Clone tag v1.2.3" + echo " $0 https://github.com/xxx/sdk.git abc123 # Clone specific commit" + echo "" +} -if [ ! -d "$DEST_DIR/.git" ]; then - echo "cloning repo..." - git clone $REPO_URL "$DEST_DIR" -else - echo "repo already exists, updating..." +# check parameters +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + show_help + exit 0 fi -cd "$DEST_DIR" || exit +echo "==========================================" +echo "Fetching Telink BLE SDK" +echo "==========================================" +echo "Repository: $REPO_URL" +echo "Target: $TARGET" +echo "Destination: $DEST_DIR" +echo "==========================================" -echo "fetching latest data and checking out Commit: $TARGET_COMMIT" -git fetch origin -git checkout $TARGET_COMMIT +# check if target repo exists +if [ -d "$DEST_DIR/.git" ]; then + echo "Repository already exists, updating..." + cd "$DEST_DIR" || exit 1 + + # acquire latest data + git fetch --all --tags --prune + + # check if target commit exists in current remote + TARGET_EXISTS=false + + if git rev-parse --quiet --verify "$TARGET^{commit}" >/dev/null 2>&1; then + TARGET_EXISTS=true + else + # Try to fetch from other remotes + echo "Target not found in current remote, trying to add alternative remote..." + + # Check if we need to switch to different repository + CURRENT_REMOTE=$(git remote get-url origin 2>/dev/null) + if [ "$CURRENT_REMOTE" != "$REPO_URL" ]; then + echo "Current remote: $CURRENT_REMOTE" + echo "Target remote: $REPO_URL" + echo "Switching remote to target repository..." + + # Add new remote + git remote add target_repo "$REPO_URL" 2>/dev/null || git remote set-url target_repo "$REPO_URL" + + # Fetch from target remote + git fetch target_repo --tags --prune + + # Check if target exists in target remote + if git rev-parse --quiet --verify "target_repo/$TARGET^{commit}" >/dev/null 2>&1; then + TARGET_EXISTS=true + # Create a local branch tracking the target remote + git checkout -b "target_$TARGET" "target_repo/$TARGET" 2>/dev/null || git checkout "$TARGET" + fi + fi + fi + + CURRENT_COMMIT=$(git rev-parse HEAD) + + # try to checkout target as commit, branch, or tag + if [ "$TARGET_EXISTS" = true ] || git rev-parse --quiet --verify "$TARGET^{commit}" >/dev/null 2>&1; then + # TARGET is valid commit hash + if [ "$CURRENT_COMMIT" = "$TARGET" ]; then + echo "Already at target commit: $TARGET" + exit 0 + fi + git checkout "$TARGET" + elif git show-ref --quiet --verify "refs/heads/$TARGET"; then + # TARGET is local branch + echo "Switching to branch: $TARGET" + git checkout "$TARGET" + git pull origin "$TARGET" + elif git ls-remote --exit-code --heads origin "$TARGET" >/dev/null 2>&1; then + # TARGET is remote branch + echo "Switching to remote branch: $TARGET" + git checkout -B "$TARGET" "origin/$TARGET" + elif git ls-remote --exit-code --tags origin "$TARGET" >/dev/null 2>&1; then + # TARGET is tag + echo "Switching to tag: $TARGET" + git checkout "tags/$TARGET" -b "tag-$TARGET" + elif git ls-remote --exit-code --heads target_repo "$TARGET" >/dev/null 2>&1; then + # TARGET is branch in target remote + echo "Switching to branch from target remote: $TARGET" + git checkout -B "$TARGET" "target_repo/$TARGET" + elif git ls-remote --exit-code --tags target_repo "$TARGET" >/dev/null 2>&1; then + # TARGET is tag in target remote + echo "Switching to tag from target remote: $TARGET" + git checkout "tags/$TARGET" -b "tag-$TARGET" + else + echo "Error: Cannot find target '$TARGET'" + echo "Available commits in current repository:" + git log --oneline -10 + exit 1 + fi +else + echo "Cloning repository..." + git clone "$REPO_URL" "$DEST_DIR" + cd "$DEST_DIR" || exit 1 + + # switch to specific target + if git rev-parse --quiet --verify "$TARGET^{commit}" >/dev/null 2>&1; then + git checkout "$TARGET" + elif git ls-remote --exit-code origin "$TARGET" >/dev/null 2>&1; then + git checkout -B "$TARGET" "origin/$TARGET" + elif git ls-remote --exit-code --tags origin "$TARGET" >/dev/null 2>&1; then + git checkout "tags/$TARGET" -b "tag-$TARGET" + else + echo "Warning: Target '$TARGET' not found, using default branch" + fi +fi -CURRENT_COMMIT=$(git rev-parse HEAD) -echo "------------------------------------------" +# show final status +FINAL_COMMIT=$(git rev-parse HEAD) +FINAL_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "detached HEAD") + +echo "==========================================" echo "Sync complete!" echo "Current directory: $(pwd)" -echo "Current Commit: $CURRENT_COMMIT" +echo "Current branch: $FINAL_BRANCH" +echo "Current commit: $FINAL_COMMIT" +echo "==========================================" + +# show recent commits +echo "Recent commits:" +git log --oneline -3 +echo "==========================================" + diff --git a/hal_v2/fetch_src.sh b/hal_v2/fetch_src.sh index f6f5c482..21fb9d9d 100755 --- a/hal_v2/fetch_src.sh +++ b/hal_v2/fetch_src.sh @@ -11,7 +11,7 @@ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) REPO_URL="http://192.168.48.36/src/ble/telink_b91m_ble_multi_connection_src.git" -TARGET_COMMIT="d8b779b1ed138c0579b548d3164cb255955e6f09" +TARGET_COMMIT="7ccf4bfd53099c67ac1dad4047e9144fb6ead41e" DEST_DIR="$SCRIPT_DIR/tl_ble_src" echo "dest dir: $DEST_DIR" diff --git a/hal_v2/wrapper/CMakeLists.txt b/hal_v2/wrapper/CMakeLists.txt index 195b5ccd..ea603f59 100644 --- a/hal_v2/wrapper/CMakeLists.txt +++ b/hal_v2/wrapper/CMakeLists.txt @@ -23,8 +23,8 @@ zephyr_library_sources(${ZIGBEE_SOURCES}) zephyr_compile_options( -DCHIP_TYPE=CHIP_TYPE_TL322X - -DTLK_MESSAGE_D25F=1 - -DTLK_MESSAGE_N22=0 + # -DTLK_MESSAGE_D25F=1 + # -DTLK_MESSAGE_N22=0 -DMAILBOX_D25F=1 -DMAILBOX_FALSH_WR_NOTIFY=1 -DSHM_MBOX_TYPE_TPSLL_EN=1 @@ -69,6 +69,9 @@ if(CONFIG_BT OR CONFIG_IEEE802154) endif() zephyr_library_sources(common/tl_flash.c) +if(CONFIG_SOC_RISCV_TELINK_TL323X) +zephyr_library_sources(common/tl_sd_adc.c) +endif() if(CONFIG_PM) zephyr_sources(common/tl_sleep.c) diff --git a/hal_v2/wrapper/common/tl_flash.c b/hal_v2/wrapper/common/tl_flash.c index d5872111..359b8b39 100644 --- a/hal_v2/wrapper/common/tl_flash.c +++ b/hal_v2/wrapper/common/tl_flash.c @@ -21,6 +21,7 @@ #include "flash.h" #include "flash_prot.h" +#ifndef CONFIG_SOC_RISCV_TELINK_TL523X /******************************************************************************************************************* * This function serves to 1m area flash protection ******************************************************************************************************************/ @@ -33,9 +34,11 @@ uint16_t flash_protection_lock_select(uint32_t addr) { - unsigned int flash_lockBlock_cmd; + /* FLASH_LOCK_NONE_MID156085 or FLASH_LOCK_NONE_MID1560C8 is 0x0*/ + unsigned int flash_lockBlock_cmd = 0x0; unsigned int app_lockBlock = FLASH_LOCK_FW_LOW_1M; unsigned int blc_flash_mid; + if(addr == FLASH_1M_ADR_OFFSET) { app_lockBlock = FLASH_LOCK_FW_LOW_1M; flash_lockBlock_cmd = flash_change_app_lock_block_to_flash_lock_block(app_lockBlock); @@ -76,4 +79,5 @@ void flash_protection_unlock_operation(unsigned int offset) if(offset < FLASH_ADR_OFFSET_SELECT){ flash_unlock(); } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/hal_v2/wrapper/common/tl_sd_adc.c b/hal_v2/wrapper/common/tl_sd_adc.c new file mode 100644 index 00000000..04969f39 --- /dev/null +++ b/hal_v2/wrapper/common/tl_sd_adc.c @@ -0,0 +1,124 @@ + +/******************************************************************************************************** + * @file tl_sd_adc.c + * + * @brief This is the source file for tl323x + * + * @author Driver Group + * @date 2026 + * + * @par Copyright (c) 2026, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *******************************************************************************************************/ + +#include +#include "sd_adc.h" +#include "tl_sd_adc.h" +#include "lib/include/stimer.h" +#include "lpc.h" + +#define SD_ADC_SAMPLE_CNT 16 // Number of samples used to calculate the average. +static signed int sd_adc_sample_buffer[SD_ADC_SAMPLE_CNT] __attribute__((aligned(4))) = {0}; + +_attribute_ram_code_sec_ +int adc_sort_and_get_average_code(void) +{ + signed int code_average = 0; + + // Enable ADC and start sampling + sd_adc_power_on(SD_ADC_SAMPLE_MODE); + + /* Wait for ADC to stabilize */ + delay_us(200); + + /* Start sampling */ + sd_adc_sample_start(); + + // Discard the first 4 invalid samples + for (int i = 0; i < 4; i++) { + sd_adc_get_raw_code(); + } + + // Collect multiple samples + int cnt = 0; + while (cnt < SD_ADC_SAMPLE_CNT) { + int sample_cnt = sd_adc_get_rxfifo_cnt(); + if (sample_cnt > 0) { + sd_adc_sample_buffer[cnt] = sd_adc_get_raw_code(); + cnt++; + } + } + + // Sort samples using insertion sort + for(int i = 1; i < SD_ADC_SAMPLE_CNT; i++) { + if(sd_adc_sample_buffer[i] < sd_adc_sample_buffer[i-1]) { + signed int temp = sd_adc_sample_buffer[i]; + sd_adc_sample_buffer[i] = sd_adc_sample_buffer[i-1]; + int j; + for(j = i-1; j >= 0 && sd_adc_sample_buffer[j] > temp; j--) { + sd_adc_sample_buffer[j+1] = sd_adc_sample_buffer[j]; + } + sd_adc_sample_buffer[j+1] = temp; + } + } + + // Calculate average (remove the highest and lowest 1/4 data) + for (int i = SD_ADC_SAMPLE_CNT >> 2; i < (SD_ADC_SAMPLE_CNT - (SD_ADC_SAMPLE_CNT >> 2)); i++) { + code_average += sd_adc_sample_buffer[i] / (SD_ADC_SAMPLE_CNT >> 1); + } + + signed int sd_adc_vol_10x = sd_adc_calculate_voltage(code_average, SD_ADC_VOLTAGE_10X_MV); + return sd_adc_vol_10x / 10; +} + +void AdcDriverInit(void) +{ + /* Initialize the SD ADC module to single-channel mode */ + sd_adc_init(SD_ADC_SINGLE_DC_MODE); +#if(SD_ADC_MODE == SD_ADC_GPIO_MODE) + sd_adc_gpio_cfg_t adc_gpio_cfg = + { + .clk_freq = SD_ADC_CLK_FREQ, + .downsample_rate = SD_ADC_DOWNSAMPLE_RATE, + .gpio_div = SD_ADC_DIV, + .input_p = SD_ADC_GPIO_PIN, + .input_n = SD_ADC_GNDN, + }; + sd_adc_gpio_sample_init(&adc_gpio_cfg); +#elif(SD_ADC_MODE == SD_ADC_VBAT_MODE) + sd_adc_vbat_sample_init(SD_ADC_CLK_FREQ, + SD_ADC_DIV, SD_ADC_DOWNSAMPLE_RATE); +#endif +} + +int AdcDriverRead(void) +{ + int adc_mv_val = adc_sort_and_get_average_code(); + sd_adc_power_off(SD_ADC_SAMPLE_MODE); +#if(SD_ADC_MODE == SD_ADC_GPIO_MODE) + +#elif(SD_ADC_MODE == SD_ADC_VBAT_MODE) + /* + * Close LPC before sleep, otherwise + * it will increase the standby current. + */ + lpc_vbat_detect_disable(); + lpc_power_down(); +#endif + return adc_mv_val; +} + +adc_init_f _TLAdcDriverInit = AdcDriverInit; +adc_read_f _TLAdcDriverRead = AdcDriverRead; diff --git a/hal_v2/wrapper/common/tl_sd_adc.h b/hal_v2/wrapper/common/tl_sd_adc.h new file mode 100644 index 00000000..f0551f78 --- /dev/null +++ b/hal_v2/wrapper/common/tl_sd_adc.h @@ -0,0 +1,55 @@ +/******************************************************************************************************** + * @file tl_sd_adc.h + * + * @brief This is the header file for tl323x + * + * @author Driver Group + * @date 2026 + * + * @par Copyright (c) 2026, Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK") + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *******************************************************************************************************/ +#pragma once + +#include "dma.h" +#include "compiler.h" +#include "gpio.h" +#include "reg_include/register.h" + +#define SD_ADC_GPIO_MODE 1 +#define SD_ADC_VBAT_MODE 2 +#define SD_ADC_MODE SD_ADC_VBAT_MODE + +#if(SD_ADC_MODE == SD_ADC_GPIO_MODE) +#define SD_ADC_GPIO_PIN SD_ADC_GPIO_PB5P +#define SD_ADC_DIV SD_ADC_GPIO_CHN_DIV_1F4 +#elif(SD_ADC_MODE == SD_ADC_VBAT_MODE) +#define SD_ADC_DIV SD_ADC_VBAT_DIV_1F4 +#endif +#define SD_ADC_CLK_FREQ SD_ADC_SAPMPLE_CLK_1M +#define SD_ADC_DOWNSAMPLE_RATE SD_ADC_DOWNSAMPLE_RATE_128 + +_attribute_ram_code_sec_ +int adc_sort_and_get_average_code(void); + +void AdcDriverInit(void); + +int AdcDriverRead(void); + +typedef void (*adc_init_f)(void); +typedef int (*adc_read_f)(void); + +extern adc_init_f _TLAdcDriverInit; +extern adc_read_f _TLAdcDriverRead; diff --git a/hal_v2/wrapper/common/tl_sleep.c b/hal_v2/wrapper/common/tl_sleep.c index ce91db51..6a795866 100644 --- a/hal_v2/wrapper/common/tl_sleep.c +++ b/hal_v2/wrapper/common/tl_sleep.c @@ -105,6 +105,8 @@ CONFIG_SOC_SERIES_RISCV_TELINK_TLX_RETENTION) #define DEEPSLEEP_MODE_RET_SRAM DEEPSLEEP_MODE_RET_SRAM_LOW96K #elif CONFIG_SOC_RISCV_TELINK_TL321X #define DEEPSLEEP_MODE_RET_SRAM DEEPSLEEP_MODE_RET_SRAM_LOW96K +#elif CONFIG_SOC_RISCV_TELINK_TL322X +#define DEEPSLEEP_MODE_RET_SRAM DEEPSLEEP_MODE_RET_SRAM_LOW128K #elif CONFIG_SOC_RISCV_TELINK_TL323X #define DEEPSLEEP_MODE_RET_SRAM DEEPSLEEP_MODE_RET_SRAM_LOW160K #elif CONFIG_SOC_RISCV_TELINK_TL721X diff --git a/hal_v2/wrapper/common/tl_sleep.h b/hal_v2/wrapper/common/tl_sleep.h index 25ead433..cf2ce5cd 100644 --- a/hal_v2/wrapper/common/tl_sleep.h +++ b/hal_v2/wrapper/common/tl_sleep.h @@ -29,4 +29,8 @@ bool tl_deep_sleep(uint32_t wake_stimer_tick); #endif /* (CONFIG_SOC_SERIES_RISCV_TELINK_B9X_RETENTION || */ /* CONFIG_SOC_SERIES_RISCV_TELINK_TLX_RETENTION) */ +#if CONFIG_SOC_RISCV_TELINK_TL322X || CONFIG_SOC_RISCV_TELINK_TL323X +#define cpu_sleep_wakeup_32k_rc cpu_sleep_wakeup +#endif + #endif /* __TL_SLEEP_H */ diff --git a/hal_v2/wrapper/controller/tlx/tlx_bt_init.c b/hal_v2/wrapper/controller/tlx/tlx_bt_init.c index fd06c76f..32a6adb5 100644 --- a/hal_v2/wrapper/controller/tlx/tlx_bt_init.c +++ b/hal_v2/wrapper/controller/tlx/tlx_bt_init.c @@ -66,11 +66,23 @@ _attribute_ble_data_retention_ u8 #define SUSPEND_EXIT_LATENCY_US (320U) #define DEEPRETN_EXIT_LATENCY_US (1000U) /*!< Not used for now */ #elif CONFIG_SOC_RISCV_TELINK_TL323X - #define SUSPEND_EXIT_LATENCY_US (500U) /*!< No Fast Settle Used For Now, Update Later */ - #define DEEPRETN_EXIT_LATENCY_US (1000U) /*!< Not used for now */ + /* for tl323x, if in pm mode the cclk is 48M, the early wakeup should be 500us. + * In non-pm mode ,the cclk is 96M, the early wakeup should be 400us, will be + * more stable + */ + #if CONFIG_PM + /*!< No Fast Settle Used For Now, Update Later */ + #define SUSPEND_EXIT_LATENCY_US (500U) + #else + /*!< No Fast Settle Used For Now, Update Later */ + #define SUSPEND_EXIT_LATENCY_US (400U) + #endif + /*!< Not used for now */ + #define DEEPRETN_EXIT_LATENCY_US (1000U) #elif CONFIG_SOC_RISCV_TELINK_TL721X #define SUSPEND_EXIT_LATENCY_US (250U) - #define DEEPRETN_EXIT_LATENCY_US (0U) /*!< Not used for now */ + /*!< Not used for now */ + #define DEEPRETN_EXIT_LATENCY_US (0U) #endif /** @@ -102,6 +114,7 @@ int tlx_bt_blc_init(void *prx, void *ptx) blc_ll_initAclConnection_module(); #ifdef CONFIG_BT_CENTRAL + blc_ll_initLegacyScanning_module(); // scan module: mandatory for BLE slave blc_ll_initAclMasterRole_module(); #endif /* CONFIG_BT_CENTRAL */ #ifdef CONFIG_BT_PERIPHERAL diff --git a/hal_v2/wrapper/crypto/mbedtls/CMakeLists.txt b/hal_v2/wrapper/crypto/mbedtls/CMakeLists.txt index ce18ad44..27fff563 100644 --- a/hal_v2/wrapper/crypto/mbedtls/CMakeLists.txt +++ b/hal_v2/wrapper/crypto/mbedtls/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2022-2024, Telink +# Copyright (c) 2022-2026, Telink # # SPDX-License-Identifier: Apache-2.0 # @@ -34,6 +34,30 @@ zephyr_library_sources_ifdef(CONFIG_TELINK_TLX_MBEDTLS_HW_ACCELERATION ./ecp_tlx_backend.c ) +# Include TLX drivers for accelerated SHA256, linker wraps +if(CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION) + message(STATUS "HW SHA configured") + + zephyr_include_directories( + ${ZEPHYR_HAL_TELINK_MODULE_DIR}/tl_ble_sdk/tl_ble_sdk/drivers/${SOC}/lib/include + ${ZEPHYR_HAL_TELINK_MODULE_DIR}/tl_ble_sdk/tl_ble_sdk/drivers/${SOC}/lib/include/hash + ) + + zephyr_library_sources( + ./sha256_tlx_backend.c + ) + + zephyr_link_libraries( + -Wl,--wrap,mbedtls_sha256_init + -Wl,--wrap,mbedtls_sha256_starts + -Wl,--wrap,mbedtls_sha256_update + -Wl,--wrap,mbedtls_sha256_finish + -Wl,--wrap,mbedtls_sha256_free + -Wl,--wrap=mbedtls_sha256 + -Wl,--wrap=mbedtls_sha256_clone + ) +endif() # CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION + zephyr_link_libraries( -Wl,--wrap,mbedtls_ecp_check_pubkey -Wl,--wrap,mbedtls_ecp_mul diff --git a/hal_v2/wrapper/crypto/mbedtls/ecp_tlx_backend.c b/hal_v2/wrapper/crypto/mbedtls/ecp_tlx_backend.c index 7ee0022b..9ac8c490 100644 --- a/hal_v2/wrapper/crypto/mbedtls/ecp_tlx_backend.c +++ b/hal_v2/wrapper/crypto/mbedtls/ecp_tlx_backend.c @@ -457,7 +457,12 @@ int telink_tlx_ecp_mul_restartable(mbedtls_ecp_group *grp, break; } telink_soc_ecp_lock(); +#if CONFIG_SOC_RISCV_TELINK_TL322X +/* pke_x25519_point_mul is not supported on TL322X pke module, directly use x25519_pointMul */ + int r = x25519_pointMul(mont_curve, ms, Qx, Qx); +#else int r = pke_x25519_point_mul(mont_curve, ms, Qx, Qx); +#endif /* CONFIG_SOC_RISCV_TELINK_TL322X */ telink_soc_ecp_unlock(); if (r != PKE_SUCCESS) { LOG_ERR("EC multiplication error"); diff --git a/hal_v2/wrapper/crypto/mbedtls/mbedtls_wrapper.c b/hal_v2/wrapper/crypto/mbedtls/mbedtls_wrapper.c index 06c086cb..356844a8 100644 --- a/hal_v2/wrapper/crypto/mbedtls/mbedtls_wrapper.c +++ b/hal_v2/wrapper/crypto/mbedtls/mbedtls_wrapper.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Telink Semiconductor + * Copyright (c) 2024-2026 Telink Semiconductor * * SPDX-License-Identifier: Apache-2.0 */ @@ -44,10 +44,37 @@ extern int telink_b9x_ecp_muladd_restartable(mbedtls_ecp_group *grp, extern int telink_soc_ecp_self_test(int verbose); #endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_ECP_C */ + +/********************************************************************* + * SHA256 HW accelerated functions + *********************************************************************/ + +#ifdef MBEDTLS_SHA256_C + +#include + +#if CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION +extern void telink_tlx_sha256_init(mbedtls_sha256_context *ctx); +extern int telink_tlx_sha256_starts(mbedtls_sha256_context *ctx, int is224); +extern int telink_tlx_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen); +extern int telink_tlx_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char output[32]); +extern void telink_tlx_sha256_free(mbedtls_sha256_context *ctx); + +extern void telink_tlx_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src); +#endif /* CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION */ + +#endif /* MBEDTLS_SHA256_C */ + /********************************************************************* * LD transformed software functions *********************************************************************/ +#ifdef MBEDTLS_ECP_C extern int __real_mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt); extern int __real_mbedtls_ecp_mul_restartable(mbedtls_ecp_group *grp, @@ -62,11 +89,14 @@ extern int __real_mbedtls_ecp_muladd_restartable(mbedtls_ecp_group *grp, #ifdef MBEDTLS_SELF_TEST extern int __real_mbedtls_ecp_self_test(int verbose); #endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_ECP_C */ /********************************************************************* * Call HW accelerated functionality if fails use software *********************************************************************/ +#ifdef MBEDTLS_ECP_C + int __wrap_mbedtls_ecp_check_pubkey(const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt) { @@ -182,3 +212,75 @@ int __wrap_mbedtls_ecp_self_test(int verbose) #endif /* MBEDTLS_SELF_TEST */ #endif /* MBEDTLS_ECP_C */ + +/********************************************************************* + * SHA256 wrapper functions + *********************************************************************/ + +#ifdef MBEDTLS_SHA256_C + +#ifdef CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION +void __wrap_mbedtls_sha256_init(mbedtls_sha256_context *ctx) +{ + telink_tlx_sha256_init(ctx); +} + +int __wrap_mbedtls_sha256_starts(mbedtls_sha256_context *ctx, int is224) +{ + return telink_tlx_sha256_starts(ctx, is224); +} + +int __wrap_mbedtls_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen) +{ + return telink_tlx_sha256_update(ctx, input, ilen);; +} + +int __wrap_mbedtls_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char output[32]) +{ + return telink_tlx_sha256_finish(ctx, output); +} + +void __wrap_mbedtls_sha256_free(mbedtls_sha256_context *ctx) +{ + telink_tlx_sha256_free(ctx); +} + +void __wrap_mbedtls_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + telink_tlx_sha256_clone(dst, src); +} + +int __wrap_mbedtls_sha256(const unsigned char *input, + size_t ilen, + unsigned char output[32], + int is224) +{ + mbedtls_sha256_context ctx; + int ret; + + __wrap_mbedtls_sha256_init(&ctx); + + ret = __wrap_mbedtls_sha256_starts(&ctx, is224); + if (ret != 0) { + goto exit; + } + + ret = __wrap_mbedtls_sha256_update(&ctx, input, ilen); + if (ret != 0) { + goto exit; + } + + ret = __wrap_mbedtls_sha256_finish(&ctx, output); + +exit: + __wrap_mbedtls_sha256_free(&ctx); + return ret; +} + +#endif /* CONFIG_TELINK_TLX_MBEDTLS_HW_SHA_ACCELERATION */ + +#endif /* MBEDTLS_SHA256_C */ diff --git a/hal_v2/wrapper/crypto/mbedtls/sha256_tlx_backend.c b/hal_v2/wrapper/crypto/mbedtls/sha256_tlx_backend.c new file mode 100644 index 00000000..bff23745 --- /dev/null +++ b/hal_v2/wrapper/crypto/mbedtls/sha256_tlx_backend.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2025-2026 Telink Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file sha256_tlx_backend.c + * @brief TLX hardware-accelerated SHA256 backend for mbedTLS + */ + +#include +#include +#include +#include +#include + +#include "hash/hash_portable.h" +#include "hash/sha256.h" + +/* Max concurrent SHA256 contexts */ +#define MAX_SHA256_CONTEXTS 8 + +typedef struct { + mbedtls_sha256_context *owner; + SHA256_CTX hw_ctx; + uint32_t iterator[HASH_ITERATOR_MAX_WORD_LEN]; + bool in_use; + bool started; +} sha256_slot_t; + +static sha256_slot_t g_slots[MAX_SHA256_CONTEXTS]; + +/* Protects slot table + g_hw_active_slot only */ +static struct k_spinlock g_slots_lock; + +/* Serializes access to the HW SHA engine */ +static struct k_mutex g_hw_mutex; + +static sha256_slot_t *g_hw_active_slot; + +/* ---------- HW context save / restore ---------- */ + +static void save_hw_state(sha256_slot_t *slot) +{ + if (slot && slot->started) { + hash_get_iterator((unsigned char *)slot->iterator, + HASH_ITERATOR_MAX_WORD_LEN); + } +} + +static void restore_hw_state(sha256_slot_t *slot) +{ + if (slot && slot->started) { + hash_set_iterator(slot->iterator, + HASH_ITERATOR_MAX_WORD_LEN); + } +} + +/* + * Must be called with g_slots_lock held + */ +static void acquire_hw_locked(sha256_slot_t *slot) +{ + if (g_hw_active_slot == slot) { + return; + } + + if (g_hw_active_slot) { + save_hw_state(g_hw_active_slot); + } + + restore_hw_state(slot); + g_hw_active_slot = slot; +} + +/* ---------- Slot management ---------- */ + +static sha256_slot_t *get_slot(mbedtls_sha256_context *ctx, bool allocate) +{ + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + sha256_slot_t *free_slot = NULL; + + for (int i = 0; i < MAX_SHA256_CONTEXTS; i++) { + if (g_slots[i].in_use) { + if (g_slots[i].owner == ctx) { + k_spin_unlock(&g_slots_lock, key); + return &g_slots[i]; + } + } else if (!free_slot) { + free_slot = &g_slots[i]; + } + } + + if (allocate && free_slot) { + memset(free_slot, 0, sizeof(*free_slot)); + free_slot->in_use = true; + free_slot->owner = ctx; + k_spin_unlock(&g_slots_lock, key); + return free_slot; + } + + k_spin_unlock(&g_slots_lock, key); + return NULL; +} + +static void release_slot(mbedtls_sha256_context *ctx) +{ + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + + for (int i = 0; i < MAX_SHA256_CONTEXTS; i++) { + if (g_slots[i].in_use && g_slots[i].owner == ctx) { + if (g_hw_active_slot == &g_slots[i]) { + g_hw_active_slot = NULL; + } + memset(&g_slots[i], 0, sizeof(g_slots[i])); + break; + } + } + + k_spin_unlock(&g_slots_lock, key); +} + +/* ---------- mbedTLS backend API ---------- */ + +void telink_tlx_sha256_init(mbedtls_sha256_context *ctx) +{ + release_slot(ctx); +} + +int telink_tlx_sha256_starts(mbedtls_sha256_context *ctx, int is224) +{ + if (is224) { + return MBEDTLS_ERR_SHA256_BAD_INPUT_DATA; + } + + sha256_slot_t *slot = get_slot(ctx, false); + if (!slot) { + slot = get_slot(ctx, true); + if (!slot) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + } + + /* Serialize HW access */ + k_mutex_lock(&g_hw_mutex, K_FOREVER); + + hash_dig_en(); + + if (sha256_init(&slot->hw_ctx) != 0) { + k_mutex_unlock(&g_hw_mutex); + release_slot(ctx); + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + slot->started = true; + + /* Switch HW context */ + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + acquire_hw_locked(slot); + k_spin_unlock(&g_slots_lock, key); + + k_mutex_unlock(&g_hw_mutex); + return 0; +} + +int telink_tlx_sha256_update(mbedtls_sha256_context *ctx, + const unsigned char *input, + size_t ilen) +{ + if (ilen == 0) { + return 0; + } + + sha256_slot_t *slot = get_slot(ctx, false); + if (!slot || !slot->started) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + k_mutex_lock(&g_hw_mutex, K_FOREVER); + + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + acquire_hw_locked(slot); + k_spin_unlock(&g_slots_lock, key); + + int rc = sha256_update(&slot->hw_ctx, + (unsigned char *)input, + ilen); + + key = k_spin_lock(&g_slots_lock); + save_hw_state(slot); + k_spin_unlock(&g_slots_lock, key); + + k_mutex_unlock(&g_hw_mutex); + + return rc ? MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED : 0; +} + +int telink_tlx_sha256_finish(mbedtls_sha256_context *ctx, + unsigned char output[32]) +{ + sha256_slot_t *slot = get_slot(ctx, false); + if (!slot || !slot->started) { + return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; + } + + k_mutex_lock(&g_hw_mutex, K_FOREVER); + + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + acquire_hw_locked(slot); + k_spin_unlock(&g_slots_lock, key); + + int rc = sha256_final(&slot->hw_ctx, output); + + key = k_spin_lock(&g_slots_lock); + slot->started = false; + if (g_hw_active_slot == slot) { + g_hw_active_slot = NULL; + } + k_spin_unlock(&g_slots_lock, key); + + k_mutex_unlock(&g_hw_mutex); + + return rc ? MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED : 0; +} + +void telink_tlx_sha256_free(mbedtls_sha256_context *ctx) +{ + release_slot(ctx); +} + +void telink_tlx_sha256_clone(mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src) +{ + sha256_slot_t *src_slot = + get_slot((mbedtls_sha256_context *)src, false); + if (!src_slot || !src_slot->started) { + return; + } + + sha256_slot_t *dst_slot = get_slot(dst, true); + if (!dst_slot) { + return; + } + + k_mutex_lock(&g_hw_mutex, K_FOREVER); + + k_spinlock_key_t key = k_spin_lock(&g_slots_lock); + if (g_hw_active_slot == src_slot) { + save_hw_state(src_slot); + } + + memcpy(&dst_slot->hw_ctx, + &src_slot->hw_ctx, + sizeof(SHA256_CTX)); + memcpy(dst_slot->iterator, + src_slot->iterator, + sizeof(dst_slot->iterator)); + dst_slot->started = true; + k_spin_unlock(&g_slots_lock, key); + + k_mutex_unlock(&g_hw_mutex); +} diff --git a/hal_v2/wrapper/zb_proj/drivers/multi_core/mailbox_msg.c b/hal_v2/wrapper/zb_proj/drivers/multi_core/mailbox_msg.c index 48b7c8af..f2f76764 100644 --- a/hal_v2/wrapper/zb_proj/drivers/multi_core/mailbox_msg.c +++ b/hal_v2/wrapper/zb_proj/drivers/multi_core/mailbox_msg.c @@ -25,6 +25,7 @@ #include "mailbox_msg.h" #include "mailbox_service.h" #include "utility.h" +#include static share_mem_fifo_t *sm_tx_fifo = NULL; static share_mem_fifo_t *sm_rx_fifo = NULL; @@ -91,7 +92,7 @@ void mailbox_msg_tx(share_mem_type_e type, u8 *data, u32 len) } printf("]\n"); } - +#if 0 static void mailbox_msg_tx_fifo_handler(u8 *data) { sm_tx_fifo = (share_mem_fifo_t *)BUILD_U32(data[3], data[4], data[5], data[6]); @@ -112,7 +113,7 @@ static void mailbox_msg_nv_fifo_handler(u8 *data) share_memory_set_fifo_status(sm_nv_fifo, SHARE_MEMORY_STATUS_READY); printf("sm_nv_fifo: %x\n", (u32)sm_nv_fifo); } -#if 0 + void mailbox_msg_init(void) { mailbox_service_cb_register(MAILBOX_MSG_TX_FIFO, mailbox_msg_tx_fifo_handler);