Sfoglia il codice sorgente

bsp:k230:add support for temperature sensor driver

Added a temperature sensor driver and a test file test_ts.c.
The test uses temperature sensor to measure the chip temperature,
to check if the driver works correctly.

Signed-off-by: XU HU 1337858472@qq.com
dannyray019 3 settimane fa
parent
commit
60b3ccb8ad

+ 100 - 2
bsp/k230/.config

@@ -710,6 +710,7 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_LHC_MODBUS is not set
 # CONFIG_PKG_USING_QMODBUS is not set
 # CONFIG_PKG_USING_PNET is not set
+# CONFIG_PKG_USING_OPENER is not set
 # end of IoT - internet of things
 
 #
@@ -843,6 +844,7 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_VOFA_PLUS is not set
 # CONFIG_PKG_USING_ZDEBUG is not set
 # CONFIG_PKG_USING_RVBACKTRACE is not set
+# CONFIG_PKG_USING_HPATCHLITE is not set
 # end of tools packages
 
 #
@@ -871,7 +873,6 @@ CONFIG_RT_USING_VDSO=y
 #
 # CONFIG_PKG_USING_CMSIS_5 is not set
 # CONFIG_PKG_USING_CMSIS_CORE is not set
-# CONFIG_PKG_USING_CMSIS_DSP is not set
 # CONFIG_PKG_USING_CMSIS_NN is not set
 # CONFIG_PKG_USING_CMSIS_RTOS1 is not set
 # CONFIG_PKG_USING_CMSIS_RTOS2 is not set
@@ -923,7 +924,6 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_ARM_2D is not set
 # CONFIG_PKG_USING_MCUBOOT is not set
 # CONFIG_PKG_USING_TINYUSB is not set
-# CONFIG_PKG_USING_CHERRYUSB is not set
 # CONFIG_PKG_USING_KMULTI_RTIMER is not set
 # CONFIG_PKG_USING_TFDB is not set
 # CONFIG_PKG_USING_QPC is not set
@@ -935,6 +935,7 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_SFDB is not set
 # CONFIG_PKG_USING_RTP is not set
 # CONFIG_PKG_USING_REB is not set
+# CONFIG_PKG_USING_RMP is not set
 # CONFIG_PKG_USING_R_RHEALSTONE is not set
 # CONFIG_PKG_USING_HEARTBEAT is not set
 # end of system packages
@@ -950,12 +951,44 @@ CONFIG_RT_USING_VDSO=y
 #
 # STM32 HAL & SDK Drivers
 #
+# CONFIG_PKG_USING_STM32F0_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32F0_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32F1_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32F1_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32F2_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32F2_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32F3_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32F3_CMSIS_DRIVER is not set
 # CONFIG_PKG_USING_STM32F4_HAL_DRIVER is not set
 # CONFIG_PKG_USING_STM32F4_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32F7_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32F7_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32G0_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32G0_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32G4_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32G4_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32H5_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32H5_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32H7_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32H7_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32H7RS_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32H7RS_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32L0_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32L0_CMSIS_DRIVER is not set
 # CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set
 # CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32L5_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32L5_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32U5_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32U5_CMSIS_DRIVER is not set
 # CONFIG_PKG_USING_STM32WB55_SDK is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_STM32WL_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32WL_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32WB_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32WB_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32MP1_M4_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32MP1_M4_CMSIS_DRIVER is not set
 # end of STM32 HAL & SDK Drivers
 
 #
@@ -988,6 +1021,60 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_NRFX is not set
 # CONFIG_PKG_USING_NUCLEI_SDK is not set
 # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
+# CONFIG_PKG_USING_MM32 is not set
+
+#
+# WCH HAL & SDK Drivers
+#
+# CONFIG_PKG_USING_CH32V20x_SDK is not set
+# CONFIG_PKG_USING_CH32V307_SDK is not set
+# end of WCH HAL & SDK Drivers
+
+#
+# AT32 HAL & SDK Drivers
+#
+# CONFIG_PKG_USING_AT32A403A_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32A403A_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32A423_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32A423_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F45x_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F45x_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F402_405_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F402_405_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F403A_407_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F403A_407_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F413_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F413_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F415_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F415_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F421_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F421_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F423_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F423_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F425_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F425_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32F435_437_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32F435_437_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_AT32M412_416_HAL_DRIVER is not set
+# CONFIG_PKG_USING_AT32M412_416_CMSIS_DRIVER is not set
+# end of AT32 HAL & SDK Drivers
+
+#
+# HC32 DDL Drivers
+#
+# end of HC32 DDL Drivers
+
+#
+# NXP HAL & SDK Drivers
+#
+# CONFIG_PKG_USING_NXP_MCX_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_NXP_MCX_SERIES_DRIVER is not set
+# CONFIG_PKG_USING_NXP_LPC_DRIVER is not set
+# CONFIG_PKG_USING_NXP_LPC55S_DRIVER is not set
+# CONFIG_PKG_USING_NXP_IMX6SX_DRIVER is not set
+# CONFIG_PKG_USING_NXP_IMX6UL_DRIVER is not set
+# CONFIG_PKG_USING_NXP_IMXRT_DRIVER is not set
+# end of NXP HAL & SDK Drivers
 # end of HAL & SDK Drivers
 
 #
@@ -1025,12 +1112,14 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_BMI088 is not set
 # CONFIG_PKG_USING_HMC5883 is not set
 # CONFIG_PKG_USING_MAX6675 is not set
+# CONFIG_PKG_USING_MAX31855 is not set
 # CONFIG_PKG_USING_TMP1075 is not set
 # CONFIG_PKG_USING_SR04 is not set
 # CONFIG_PKG_USING_CCS811 is not set
 # CONFIG_PKG_USING_PMSXX is not set
 # CONFIG_PKG_USING_RT3020 is not set
 # CONFIG_PKG_USING_MLX90632 is not set
+# CONFIG_PKG_USING_MLX90382 is not set
 # CONFIG_PKG_USING_MLX90393 is not set
 # CONFIG_PKG_USING_MLX90392 is not set
 # CONFIG_PKG_USING_MLX90394 is not set
@@ -1059,6 +1148,8 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_PAJ7620 is not set
 # CONFIG_PKG_USING_STHS34PF80 is not set
+# CONFIG_PKG_USING_P3T1755 is not set
+# CONFIG_PKG_USING_QMI8658 is not set
 # end of sensors drivers
 
 #
@@ -1150,6 +1241,9 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_BT_MX02 is not set
 # CONFIG_PKG_USING_GC9A01 is not set
 # CONFIG_PKG_USING_IK485 is not set
+# CONFIG_PKG_USING_SERVO is not set
+# CONFIG_PKG_USING_SEAN_WS2812B is not set
+# CONFIG_PKG_USING_IC74HC165 is not set
 # CONFIG_PKG_USING_SPI_TOOLS is not set
 # end of peripheral libraries and drivers
 
@@ -1166,6 +1260,7 @@ CONFIG_RT_USING_VDSO=y
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
 # CONFIG_PKG_USING_R_TINYMAIX is not set
+# CONFIG_PKG_USING_LLMCHAT is not set
 # end of AI packages
 
 #
@@ -1242,6 +1337,7 @@ CONFIG_PKG_ZLIB_VER="latest"
 # CONFIG_PKG_USING_KI is not set
 # CONFIG_PKG_USING_ARMv7M_DWT is not set
 # CONFIG_PKG_USING_CRCLIB is not set
+# CONFIG_PKG_USING_LIBCRC is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
 # CONFIG_PKG_USING_DESIGN_PATTERN is not set
@@ -1252,6 +1348,7 @@ CONFIG_PKG_ZLIB_VER="latest"
 # CONFIG_PKG_USING_SOEM is not set
 # CONFIG_PKG_USING_QPARAM is not set
 # CONFIG_PKG_USING_CorevMCU_CLI is not set
+# CONFIG_PKG_USING_DRMP is not set
 # end of miscellaneous packages
 
 #
@@ -1495,6 +1592,7 @@ CONFIG_PKG_ZLIB_VER="latest"
 # Drivers Configuration
 #
 # CONFIG_BSP_USING_ADC is not set
+# CONFIG_BSP_USING_TS is not set
 # CONFIG_BSP_USING_PWM is not set
 CONFIG_BSP_USING_HARDLOCK=y
 CONFIG_BSP_USING_SDIO=y

+ 5 - 0
bsp/k230/board/Kconfig

@@ -4,6 +4,11 @@ menu "Drivers Configuration"
         bool "Enable ADC"
         select RT_USING_ADC
         default n
+    
+    config BSP_USING_TS
+        bool "Enable Temperature Sensor"
+        select RT_USING_TS
+        default n
 
     menuconfig BSP_USING_PWM
         bool "Enable PWM"

+ 11 - 0
bsp/k230/drivers/interdrv/ts/SConscript

@@ -0,0 +1,11 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('TS', src, depend = ['BSP_USING_TS'], CPPPATH = CPPPATH)
+
+Return('group')

+ 371 - 0
bsp/k230/drivers/interdrv/ts/drv_ts.c

@@ -0,0 +1,371 @@
+/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2006-2025 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include "drv_ts.h"
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+
+#ifdef RT_USING_POSIX
+#include <dfs_posix.h>
+#include <dfs_poll.h>
+#include <posix_termios.h>
+#endif
+
+#include "math.h"
+#include "rtdbg.h"
+#include "board.h"
+#include <riscv_io.h>
+#include "ioremap.h"
+
+// Register offsets
+#define REG_TSENW_OFFSET          0x000
+#define REG_TSENR_OFFSET          0x004
+
+// Bit positions for REG_TSENW
+#define TSENW_TS_TEST_EN_POS      6
+#define TSENW_TS_TRIM_POS         2
+#define TSENW_TS_CONV_MODE_POS    1
+#define TSENW_TS_EN_POS           0
+
+// Bit positions for REG_TSENR
+#define TSENR_TS_DOUT_VALID_POS   12
+#define TSENR_TS_DOUT_MASK        0xFFF
+
+static struct rt_mutex ts_mutex;
+static uint8_t ts_trim = 8;
+static uint8_t ts_mode = RT_DEVICE_TS_CTRL_MODE_CONTINUUOS;
+static void *ts_base_addr = RT_NULL;
+
+static rt_err_t tsensor_start(void)
+{
+    uint32_t reg_val;
+
+    if (ts_base_addr == RT_NULL)
+        return -RT_ERROR;
+
+    reg_val = readl(ts_base_addr + REG_TSENW_OFFSET);
+
+    if (RT_DEVICE_TS_CTRL_MODE_CONTINUUOS == ts_mode)
+        reg_val |= (1 << TSENW_TS_CONV_MODE_POS);
+    else
+        reg_val &= ~(1 << TSENW_TS_CONV_MODE_POS);
+
+    reg_val |= (1 << TSENW_TS_EN_POS);
+
+    writel(reg_val, ts_base_addr + REG_TSENW_OFFSET);
+
+    return RT_EOK;
+}
+
+static rt_err_t tsensor_stop(void)
+{
+    if (ts_base_addr == RT_NULL)
+        return -RT_ERROR;
+
+    uint32_t reg_val = readl(ts_base_addr + REG_TSENW_OFFSET);
+    reg_val &= ~(1 << TSENW_TS_EN_POS);
+    writel(reg_val, ts_base_addr + REG_TSENW_OFFSET);
+
+    return RT_EOK;
+}
+
+static int tsensor_read_data(uint16_t *data, uint32_t timeout_ms)
+{
+    if (ts_base_addr == RT_NULL || data == RT_NULL) // Ensure base address is set
+        return -RT_ERROR;
+
+    uint32_t max_attempts = timeout_ms; // Max attempts for the given timeout in ms
+
+    for (uint32_t attempt = 0; attempt < max_attempts; attempt++)
+    {
+        // Check if the data is valid
+        if ((readl(ts_base_addr + REG_TSENR_OFFSET) >> TSENR_TS_DOUT_VALID_POS) & 0x1)
+        {
+            // Read the 12-bit temperature data
+            *data = readl(ts_base_addr + REG_TSENR_OFFSET) & TSENR_TS_DOUT_MASK;
+            return RT_EOK; // Success
+        }
+
+        // Delay before next polling attempt
+        rt_thread_mdelay(1); // Delay in microseconds
+    }
+
+    return -RT_ETIMEOUT; // Timeout error
+}
+
+static double tsensor_calculate_temperature(uint16_t data)
+{
+    return (1e-10 * pow(data, 4) * 1.01472
+            - 1e-6 * pow(data, 3) * 1.10063
+            + 4.36150 * 1e-3 * pow(data, 2)
+            - 7.10128 * data
+            + 3565.87);
+}
+
+static rt_err_t tsensor_init(void)
+{
+    if (ts_base_addr == RT_NULL)
+    {
+        return -RT_ERROR;
+    }
+
+    if (RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n", __func__);
+        return -RT_ETIMEOUT;
+    }
+
+    uint32_t reg_val = readl(ts_base_addr + REG_TSENW_OFFSET);
+    reg_val &= ~(0xF << TSENW_TS_TRIM_POS);
+    reg_val |= (ts_trim << TSENW_TS_TRIM_POS);
+    writel(reg_val, ts_base_addr + REG_TSENW_OFFSET);
+
+    rt_mutex_release(&ts_mutex);
+
+    return RT_EOK;
+}
+
+
+static rt_err_t k230_tsensor_set_trim(uint8_t trim)
+{
+    if(RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n");
+        return -RT_ETIMEOUT;
+    }
+
+    // Ensure the trim_value is within range (4 bits)
+    ts_trim = trim & 0xF;
+    rt_mutex_release(&ts_mutex);
+    tsensor_init();
+    return RT_EOK;
+}
+
+static uint8_t k230_tsensor_get_trim(void)
+{
+    uint8_t temp;
+
+    if(RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n");
+        return -RT_ETIMEOUT;
+    }
+
+    temp = ts_trim;
+
+    rt_mutex_release(&ts_mutex);
+
+    return temp;
+}
+
+static rt_err_t k230_tsensor_set_mode(uint8_t mode)
+{
+    if(RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n");
+        return -RT_ETIMEOUT;
+    }
+    ts_mode = mode;
+    rt_mutex_release(&ts_mutex);
+    return RT_EOK;
+}
+
+static uint8_t k230_tsensor_get_mode(void)
+{
+    uint8_t temp;
+
+    if(RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n");
+        return -RT_ETIMEOUT;
+    }
+
+    temp = ts_mode;
+    rt_mutex_release(&ts_mutex);
+    return temp;
+}
+
+static rt_err_t k230_tsensor_read_temp(double *temp)
+{
+    uint16_t data;
+    rt_err_t ret = RT_EOK;
+    if (RT_EOK != rt_mutex_take(&ts_mutex, rt_tick_from_millisecond(500)))
+    {
+        LOG_E("%s mutex take timeout.\n");
+        return -RT_ETIMEOUT;
+    }
+
+    ret = tsensor_start();
+    if (ret != RT_EOK)
+    {
+        return ret;
+    }
+
+    rt_thread_mdelay(10);
+
+    if (0x00 == tsensor_read_data(&data, 100))
+    {
+        *((double *)temp) = tsensor_calculate_temperature(data);
+        tsensor_stop();
+        rt_mutex_release(&ts_mutex);
+        return RT_EOK;
+    }
+    else
+    {
+        tsensor_stop();
+        rt_mutex_release(&ts_mutex);
+        return -RT_ERROR;
+    }
+}
+
+static rt_err_t ts_device_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    rt_err_t ret;
+
+    ret = tsensor_init();
+    return ret;
+}
+
+static rt_err_t ts_device_close(rt_device_t dev)
+{
+    rt_err_t ret;
+    ret = tsensor_stop();
+    return ret;
+}
+
+static rt_ssize_t ts_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_err_t ret;
+
+    if (sizeof(double) != size)
+    {
+        LOG_E("%s invalid buffer size %u\n", __func__, size);
+        return -RT_ERROR;
+    }
+
+    ret = k230_tsensor_read_temp((double *)buffer);
+    if (ret != 0x00)
+    {
+        return -RT_ERROR;
+    }
+    return sizeof(double);
+}
+
+static rt_err_t ts_device_control(rt_device_t dev, int cmd, void *args)
+{
+    uint8_t trim_val = k230_tsensor_get_trim();
+    uint8_t work_mode = k230_tsensor_get_mode();
+    rt_err_t ret = RT_EOK;
+
+    switch(cmd)
+    {
+        case RT_DEVICE_TS_CTRL_SET_MODE:
+            work_mode = *(uint8_t *)args;
+            ret = k230_tsensor_set_mode(work_mode);
+            break;
+        case RT_DEVICE_TS_CTRL_GET_MODE:
+            *(uint8_t *)args = work_mode;
+            break;
+        case RT_DEVICE_TS_CTRL_SET_TRIM:
+            trim_val = *(uint8_t *)args;
+            ret = k230_tsensor_set_trim(trim_val);
+            break;
+        case RT_DEVICE_TS_CTRL_GET_TRIM:
+            *(uint8_t *)args = trim_val;
+            break;
+        default:
+            LOG_E("%s unsupported cmd 0x%x\n", __func__, cmd);
+            ret = -RT_ERROR;
+            break;
+    }
+
+    return ret;
+}
+
+static struct rt_device ts_device;
+
+static const struct rt_device_ops ts_ops =
+{
+    .open    = ts_device_open,
+    .close   = ts_device_close,
+    .read    = ts_device_read,
+    .control = ts_device_control
+};
+
+static rt_err_t register_ts_device(void)
+{
+    rt_device_t device;
+    rt_err_t ret = RT_EOK;
+
+    device = &ts_device;
+
+#ifdef RT_USING_DEVICE_OPS
+    device->ops = &ts_ops;
+#else
+    device->init       =     RT_NULL;
+    device->open       =     ts_device_open;
+    device->close      =     ts_device_close;
+    device->read       =     ts_device_read;
+    device->write      =     RT_NULL;
+    device->control    =     ts_device_control;
+#endif
+
+    ret = rt_device_register(device, "ts", RT_DEVICE_FLAG_RDWR);
+    if(ret != RT_EOK)
+    {
+        LOG_E("ts device register fail\n");
+        return -RT_ERROR;
+    }
+    return ret;
+}
+
+static int rt_hw_ts_init(void)
+{
+    ts_base_addr = rt_ioremap((void *)TS_BASE_ADDR, TS_IO_SIZE);
+    if (ts_base_addr == RT_NULL)
+    {
+        LOG_E("ts ioremap error\n");
+        return -RT_ERROR;
+    }
+    if (RT_EOK != register_ts_device())
+    {
+        LOG_E("ts device register error\n");
+        return -RT_ERROR;
+    }
+    if (RT_EOK != rt_mutex_init(&ts_mutex, "dev_ts", RT_IPC_FLAG_PRIO))
+    {
+        LOG_E("ts mutex init error\n");
+        return -RT_ERROR;
+    }
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_ts_init);

+ 15 - 0
bsp/k230/drivers/interdrv/ts/drv_ts.h

@@ -0,0 +1,15 @@
+
+#ifndef __DRV_TS__
+#define __DRV_TS__
+
+#include <rtdef.h>
+
+#define RT_DEVICE_TS_CTRL_SET_MODE          1
+#define RT_DEVICE_TS_CTRL_GET_MODE          2
+#define RT_DEVICE_TS_CTRL_SET_TRIM          3
+#define RT_DEVICE_TS_CTRL_GET_TRIM          4
+
+#define RT_DEVICE_TS_CTRL_MODE_SINGLE       0x01
+#define RT_DEVICE_TS_CTRL_MODE_CONTINUUOS   0x02
+
+#endif /*__DRV_TS__*/

+ 4 - 1
bsp/k230/drivers/utest/SConscript

@@ -20,7 +20,10 @@ if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('BSP_UTEST_DRIVERS'):
 
     if GetDepend('BSP_USING_PDMA'):
         src += ['test_pdma.c']
-     
+
+    if GetDepend('BSP_USING_TS'):
+        src += ['test_ts.c']
+        
 group = DefineGroup('utestcases', src, depend = [''])
 
 Return('group')

+ 133 - 0
bsp/k230/drivers/utest/test_ts.c

@@ -0,0 +1,133 @@
+/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2006-2025 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rtdef.h>
+#include <stdlib.h>
+#include "utest.h"
+#include <math.h>
+#include "drv_ts.h"
+#include <page.h>
+
+/*
+ * 测试温度传感器驱动的读取功能
+ *
+ * 1. 查找名为 "ts" 的温度传感器设备。
+ * 2. 打开设备,并确保设备成功初始化。
+ * 3. 通过 rt_device_read 接口读取温度数据:
+ *    - 每次读取的数据类型为 double;
+ *    - 读取操作执行 5 次,以连续获取温度值;
+ *    - 每次读取后打印温度值,格式为 "Temperature = XX.XX C"。
+ * 4. 读取完成后,关闭设备并释放申请的内存。
+ *
+ * 硬件说明:
+ * - 本测试基于 K230-01studio 开发板;
+ * - 温度传感器为板载设备;
+ * - 驱动已将硬件寄存器读取的原始 ADC 值转换为摄氏度的 double 值;
+ * - 测试过程中,可在串口终端实时观察温度变化。
+ */
+
+#define TS_DEV_NAME               "ts"
+rt_device_t ts_dev = RT_NULL;
+
+static void test_ts_read(void)
+{
+    rt_uint32_t reval;
+    rt_uint32_t cnt;
+    rt_err_t ret = RT_EOK;
+    double temp = 0;
+    ts_dev = (rt_device_t)rt_device_find(TS_DEV_NAME);
+    uassert_not_null(ts_dev);
+    ret = rt_device_open(ts_dev, RT_DEVICE_OFLAG_RDWR);
+    uassert_int_equal(ret, RT_EOK);
+
+    for(cnt = 0; cnt < 5; cnt++)
+    {
+        reval = rt_device_read(ts_dev, 0, &temp, sizeof(double));
+        uassert_true(reval > 0);
+        LOG_I("Temperature = %.2f C\n", temp);
+        rt_thread_mdelay(1000);
+    }
+    rt_device_close(ts_dev);
+}
+
+static void test_ts_control(void)
+{
+    rt_err_t ret = RT_EOK;
+    uint8_t val;
+
+    ts_dev = (rt_device_t)rt_device_find(TS_DEV_NAME);
+    uassert_not_null(ts_dev);
+    ret = rt_device_open(ts_dev, RT_DEVICE_OFLAG_RDWR);
+    uassert_int_equal(ret, RT_EOK);
+
+    /* SET_MODE */
+    val = 1;
+    ret = rt_device_control(ts_dev, RT_DEVICE_TS_CTRL_SET_MODE, &val);
+    uassert_int_equal(ret, RT_EOK);
+
+    /* GET_MODE */
+    val = 0xFF;
+    ret = rt_device_control(ts_dev, RT_DEVICE_TS_CTRL_GET_MODE, &val);
+    uassert_int_equal(ret, RT_EOK);
+    LOG_I("Current MODE = %d\n", val);
+
+    /* SET_TRIM */
+    val = 2;
+    ret = rt_device_control(ts_dev, RT_DEVICE_TS_CTRL_SET_TRIM, &val);
+    uassert_int_equal(ret, RT_EOK);
+
+    /* GET_TRIM */
+    val = 0xFF;
+    ret = rt_device_control(ts_dev, RT_DEVICE_TS_CTRL_GET_TRIM, &val);
+    uassert_int_equal(ret, RT_EOK);
+    LOG_I("Current TRIM = %d\n", val);
+
+    rt_device_close(ts_dev);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+    return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+    return RT_EOK;
+}
+
+static void testcase(void)
+{
+    UTEST_UNIT_RUN(test_ts_read);
+    UTEST_UNIT_RUN(test_ts_control);
+}
+UTEST_TC_EXPORT(testcase, "ts", utest_tc_init, utest_tc_cleanup, 100);

+ 16 - 0
bsp/k230/rtconfig.h

@@ -478,6 +478,22 @@
 /* Kendryte SDK */
 
 /* end of Kendryte SDK */
+
+/* WCH HAL & SDK Drivers */
+
+/* end of WCH HAL & SDK Drivers */
+
+/* AT32 HAL & SDK Drivers */
+
+/* end of AT32 HAL & SDK Drivers */
+
+/* HC32 DDL Drivers */
+
+/* end of HC32 DDL Drivers */
+
+/* NXP HAL & SDK Drivers */
+
+/* end of NXP HAL & SDK Drivers */
 /* end of HAL & SDK Drivers */
 
 /* sensors drivers */