bsp: k230: support adc
Some checks failed
pkgs_test / change (push) Has been skipped
RT-Thread BSP Static Build Check / 🔍 Summary of Git Diff Changes (push) Has been cancelled
RT-Thread BSP Static Build Check / ${{ matrix.legs.RTT_BSP }} (push) Has been cancelled
RT-Thread BSP Static Build Check / collect-artifacts (push) Has been cancelled
ToolsCI / Tools (push) Has been cancelled
AutoTestCI / components/cpp11 (push) Has been cancelled
AutoTestCI / kernel/atomic (push) Has been cancelled
AutoTestCI / kernel/atomic/riscv64 (push) Has been cancelled
AutoTestCI / kernel/atomic_c11 (push) Has been cancelled
AutoTestCI / kernel/atomic_c11/riscv64 (push) Has been cancelled
AutoTestCI / kernel/device (push) Has been cancelled
AutoTestCI / kernel/ipc (push) Has been cancelled
AutoTestCI / kernel/irq (push) Has been cancelled
AutoTestCI / kernel/mem (push) Has been cancelled
AutoTestCI / kernel/mem/riscv64 (push) Has been cancelled
AutoTestCI / kernel/thread (push) Has been cancelled
AutoTestCI / kernel/timer (push) Has been cancelled
AutoTestCI / rtsmart/aarch64 (push) Has been cancelled
AutoTestCI / rtsmart/arm (push) Has been cancelled
AutoTestCI / rtsmart/riscv64 (push) Has been cancelled
AutoTestCI / components/utest (push) Has been cancelled
utest_auto_run / AARCH64-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / A9-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / RISCV-rtsmart :default.cfg (push) Has been cancelled
utest_auto_run / AARCH64 :default.cfg (push) Has been cancelled
utest_auto_run / A9 :default.cfg (push) Has been cancelled
utest_auto_run / A9-smp :default.cfg (push) Has been cancelled
utest_auto_run / RISCV :default.cfg (push) Has been cancelled

Signed-off-by: Chen Wang <unicorn_wang@outlook.com>
This commit is contained in:
Chen Wang
2025-06-09 10:27:09 +08:00
committed by Rbb666
parent 01ca3911ec
commit fe506d5157
7 changed files with 365 additions and 0 deletions

View File

@@ -1490,6 +1490,7 @@ CONFIG_PKG_ZLIB_VER="latest"
#
# Drivers Configuration
#
# CONFIG_BSP_USING_ADC is not set
CONFIG_BSP_USING_HARDLOCK=y
CONFIG_BSP_USING_SDIO=y
CONFIG_BSP_USING_SDIO0=y

View File

@@ -1,5 +1,10 @@
menu "Drivers Configuration"
config BSP_USING_ADC
bool "Enable ADC"
select RT_USING_ADC
default n
config BSP_USING_HARDLOCK
bool "Enable Hard-Lock"
default y

View File

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

View File

@@ -0,0 +1,162 @@
/* 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 <drivers/adc.h>
#include <ioremap.h>
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <riscv_io.h>
#include <string.h>
#include "board.h"
#include "drv_adc.h"
struct k230_adc adc_dev;
static int k230_adc_hw_init(struct k230_adc_regs *adc_regs)
{
rt_uint32_t reg;
reg = readl(&adc_regs->trim_reg);
reg &= (~(0x1));
writel(reg, &adc_regs->trim_reg);
reg = readl(&adc_regs->trim_reg);
reg |= 0x1;
writel(reg, &adc_regs->trim_reg);
reg = readl(&adc_regs->trim_reg);
reg |= (0x1 << 20);
writel(reg, &adc_regs->trim_reg);
/* delay 150us */
rt_hw_us_delay(150);
reg &= ~(0x1 << 20);
writel(reg, &adc_regs->trim_reg);
writel(0x0, &adc_regs->mode_reg);
return RT_EOK;
}
static int k230_adc_init()
{
int i;
adc_dev.adc_regs = (struct k230_adc_regs*)rt_ioremap((void *)ADC_BASE_ADDR, ADC_IO_SIZE);
for (i = 0; i < ADC_MAX_DMA_CHN; i++)
{
adc_dev.chn[i].chn_num = i;
adc_dev.chn[i].enabled = 0;
}
k230_adc_hw_init(adc_dev.adc_regs);
return RT_EOK;
}
static int k_adc_drv_enabled(struct k230_adc_regs *adc_regs)
{
rt_uint32_t reg;
reg = readl(&adc_regs->trim_reg);
reg |= 0x1;
writel(reg, &adc_regs->trim_reg);
return RT_EOK;
}
static int k_adc_drv_disabled(struct k230_adc_regs *adc_regs)
{
rt_uint32_t reg;
reg = readl(&adc_regs->trim_reg);
reg = reg & (~(0x1));
writel(reg, &adc_regs->trim_reg);
return RT_EOK;
}
rt_err_t k230_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
{
if (channel >= ADC_MAX_CHANNEL)
return -RT_ERROR;
struct k230_adc *kd_adc = rt_container_of(device, struct k230_adc, dev);
kd_adc->chn[channel].enabled = 1;
if (enabled)
{
kd_adc->chn[channel].enabled = 1;
}
else
{
kd_adc->chn[channel].enabled = 0;
}
return RT_EOK;
}
rt_err_t k230_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
{
if (channel >= ADC_MAX_CHANNEL)
return -RT_ERROR;
struct k230_adc *kd_adc = rt_container_of(device, struct k230_adc, dev);
if (!kd_adc->chn[channel].enabled)
return -RT_ERROR;
writel(channel | 0x10, &kd_adc->adc_regs->cfg_reg);
while ((readl(&kd_adc->adc_regs->cfg_reg) & 0x10000) == 0);
*value = readl(&kd_adc->adc_regs->data_reg[channel]);
return RT_EOK;
}
static const struct rt_adc_ops k230_adc_ops =
{
.enabled = k230_adc_enabled,
.convert = k230_get_adc_value,
};
int rt_hw_adc_init(void)
{
k230_adc_init();
rt_hw_adc_register(&adc_dev.dev, K230_ADC_NAME, &k230_adc_ops, NULL);
return RT_EOK;
}
INIT_BOARD_EXPORT(rt_hw_adc_init);

View File

@@ -0,0 +1,65 @@
/* 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
*/
#ifndef __DRV_ADC__
#define __DRV_ADC__
#include "board.h"
#define K230_ADC_NAME "adc"
#define ADC_MAX_CHANNEL 6
#define ADC_MAX_DMA_CHN 3
struct k230_adc_regs
{
rt_uint32_t trim_reg; /**< 0x00 */
rt_uint32_t cfg_reg; /**< 0x04 */
rt_uint32_t mode_reg; /**< 0x08 */
rt_uint32_t thsd_reg; /**< 0x0c */
rt_uint32_t dma_intr_reg; /**< 0x10 */
rt_uint32_t data_reg[ADC_MAX_CHANNEL]; /**< 0x14~0x28 */
rt_uint32_t data_dma[ADC_MAX_DMA_CHN]; /**< 0x2c~0x34 */
};
struct k230_adc_chan
{
rt_uint32_t chn_num;
rt_int8_t enabled;
};
struct k230_adc
{
struct rt_adc_device dev;
struct k230_adc_regs *adc_regs;
struct k230_adc_chan chn[ADC_MAX_CHANNEL];
};
#endif /*__DRV_ADC__*/

View File

@@ -6,6 +6,9 @@ if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('BSP_UTEST_DRIVERS'):
src += ['test_gpio.c']
src += ['test_gpio_irq.c']
if GetDepend('BSP_USING_ADC'):
src += ['test_adc.c']
if GetDepend('BSP_USING_TIMERS'):
src += ['test_timer.c']

View File

@@ -0,0 +1,118 @@
/* Copyright 2020 Canaan Inc.
*
* 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 <rtthread.h>
#include <rtdevice.h>
#include <stdlib.h>
#include "../interdrv/adc/drv_adc.h"
#include "utest.h"
/*
* 测试 ADC 驱动的读操作
* 1. 查找 ADC 设备。
* 2. 启用 ADC 设备。
* 3. 启用每个 ADC 通道并读取其值。
* 4. 验证读取的值在预期范围内。
* 5. 禁用每个 ADC 通道并验证读取值为 0。
*
* 本测试基于 01Studio 开发板,该开发板自带排针,并引出 SoC 的以下 4 个 ADC 通道
* 板级排针编号 | SoC 的 ADC 通道编号 | 输入电压范围
* -------------+---------------------+-------------
* 32 | ADC0 | (0 ~ 3.6V)
* 36 | ADC1 | (0 ~ 3.6V)
* 38 | ADC2 | (0 ~ 1.8V)
* 40 | ADC3 | (0 ~ 1.8V)
* SoC 的 ADC 通道默认只支持最大 1.8V 的输入电压,对于 ADC0 和 ADC1 通道,开发板
* 通过增加功放将最大支持电压提升到 3.6V(而且同样采用了分压机制,导致实际 ADC
* 通道的输入电压只有板级排针电压的一半)。
*
* 测试时注意连接输入的最大电压不要超过额定值,否则可能会损坏 ADC 通道。
*
* 另外注意这个adc 只有 12bit所以读取的值范围是 0 ~ 4095
*
* 具体测试最大 1.8V 的 ADC 通道(譬如 38/40可以自己通过两个 10K 欧姆的电
* 阻将模拟输入从 3.3V 分压(将可调电阻调制最大时万用表实测 A 点电压为 1.69V 左右):
* +----------+ +---------------+
* 3.3V ----| 10K 欧姆 |----| 可调 10K 欧姆 |---- 接地
* +----------+ +---------------+
* A
* |
* ADC2/ADC3
*
* 具体测试最大 3.6V 的 ADC 通道(譬如 32/36可以直接引入 3.3V。
* +---------------+
* 3.3V --------------------| 可调 10K 欧姆 |---- 接地
* +---------------+
* A
* |
* ADC0/ADC1
*/
static void test_read(void)
{
int i;
rt_err_t ret = RT_EOK;
rt_uint32_t value, vol;
rt_adc_device_t adc_dev;
adc_dev = (rt_adc_device_t)rt_device_find(K230_ADC_NAME);
uassert_not_null(adc_dev);
ret = rt_adc_enable(adc_dev, 0);
uassert_int_equal(ret, RT_EOK);
for (i = 0; i < 4; i++)
{
ret = rt_adc_enable(adc_dev, i);
uassert_int_equal(ret, RT_EOK);
value = rt_adc_read(adc_dev, i);
/* 转换为对应电压值,对应 12 位 ADC 最大值 4095, 内部基准最大电压值 1.8V,数据精度乘以 100 保留 2 位小数 */
vol = value * 180 / 4095;
if (i == 0 || i == 1)
vol = vol * 2; /* ADC0/ADC1 分压后实际电压是输入电压的二分之一 */
LOG_I("ADC chan[%d] read value: %d, calculated voltage is: %d.%02dV\n",
i, value, vol / 100, vol % 100);
}
for (i = 0; i < ADC_MAX_CHANNEL; i++)
{
ret = rt_adc_disable(adc_dev, i);
uassert_int_equal(ret, RT_EOK);
value = rt_adc_read(adc_dev, i);
uassert_int_equal(value, 0);
}
return;
}
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_read);
}
UTEST_TC_EXPORT(testcase, "adc", utest_tc_init, utest_tc_cleanup, 100);