Skip to content

Commit fe506d5

Browse files
unicornxRbb666
authored andcommitted
bsp: k230: support adc
Signed-off-by: Chen Wang <[email protected]>
1 parent 01ca391 commit fe506d5

File tree

7 files changed

+365
-0
lines changed

7 files changed

+365
-0
lines changed

bsp/k230/.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,7 @@ CONFIG_PKG_ZLIB_VER="latest"
14901490
#
14911491
# Drivers Configuration
14921492
#
1493+
# CONFIG_BSP_USING_ADC is not set
14931494
CONFIG_BSP_USING_HARDLOCK=y
14941495
CONFIG_BSP_USING_SDIO=y
14951496
CONFIG_BSP_USING_SDIO0=y

bsp/k230/board/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
menu "Drivers Configuration"
22

3+
config BSP_USING_ADC
4+
bool "Enable ADC"
5+
select RT_USING_ADC
6+
default n
7+
38
config BSP_USING_HARDLOCK
49
bool "Enable Hard-Lock"
510
default y
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RT-Thread building script for component
2+
3+
from building import *
4+
5+
cwd = GetCurrentDir()
6+
src = Glob('*.c')
7+
CPPPATH = [cwd]
8+
9+
group = DefineGroup('ADC', src, depend = ['BSP_USING_ADC'], CPPPATH = CPPPATH)
10+
11+
Return('group')
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
2+
*
3+
* Redistribution and use in source and binary forms, with or without
4+
* modification, are permitted provided that the following conditions are met:
5+
* 1. Redistributions of source code must retain the above copyright
6+
* notice, this list of conditions and the following disclaimer.
7+
* 2. Redistributions in binary form must reproduce the above copyright
8+
* notice, this list of conditions and the following disclaimer in the
9+
* documentation and/or other materials provided with the distribution.
10+
*
11+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
12+
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
13+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
/*
27+
* Copyright (c) 2006-2025 RT-Thread Development Team
28+
*
29+
* SPDX-License-Identifier: Apache-2.0
30+
*/
31+
32+
#include <drivers/adc.h>
33+
#include <ioremap.h>
34+
#include <rtthread.h>
35+
#include <rthw.h>
36+
#include <rtdevice.h>
37+
#include <riscv_io.h>
38+
#include <string.h>
39+
40+
#include "board.h"
41+
#include "drv_adc.h"
42+
43+
struct k230_adc adc_dev;
44+
45+
static int k230_adc_hw_init(struct k230_adc_regs *adc_regs)
46+
{
47+
rt_uint32_t reg;
48+
49+
reg = readl(&adc_regs->trim_reg);
50+
reg &= (~(0x1));
51+
writel(reg, &adc_regs->trim_reg);
52+
53+
reg = readl(&adc_regs->trim_reg);
54+
reg |= 0x1;
55+
writel(reg, &adc_regs->trim_reg);
56+
57+
reg = readl(&adc_regs->trim_reg);
58+
reg |= (0x1 << 20);
59+
writel(reg, &adc_regs->trim_reg);
60+
61+
/* delay 150us */
62+
rt_hw_us_delay(150);
63+
64+
reg &= ~(0x1 << 20);
65+
writel(reg, &adc_regs->trim_reg);
66+
67+
writel(0x0, &adc_regs->mode_reg);
68+
69+
return RT_EOK;
70+
}
71+
72+
static int k230_adc_init()
73+
{
74+
int i;
75+
76+
adc_dev.adc_regs = (struct k230_adc_regs*)rt_ioremap((void *)ADC_BASE_ADDR, ADC_IO_SIZE);
77+
78+
for (i = 0; i < ADC_MAX_DMA_CHN; i++)
79+
{
80+
adc_dev.chn[i].chn_num = i;
81+
adc_dev.chn[i].enabled = 0;
82+
}
83+
84+
k230_adc_hw_init(adc_dev.adc_regs);
85+
86+
return RT_EOK;
87+
}
88+
89+
static int k_adc_drv_enabled(struct k230_adc_regs *adc_regs)
90+
{
91+
rt_uint32_t reg;
92+
93+
reg = readl(&adc_regs->trim_reg);
94+
reg |= 0x1;
95+
writel(reg, &adc_regs->trim_reg);
96+
97+
return RT_EOK;
98+
}
99+
100+
static int k_adc_drv_disabled(struct k230_adc_regs *adc_regs)
101+
{
102+
rt_uint32_t reg;
103+
104+
reg = readl(&adc_regs->trim_reg);
105+
reg = reg & (~(0x1));
106+
writel(reg, &adc_regs->trim_reg);
107+
108+
return RT_EOK;
109+
}
110+
111+
rt_err_t k230_adc_enabled(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled)
112+
{
113+
if (channel >= ADC_MAX_CHANNEL)
114+
return -RT_ERROR;
115+
116+
struct k230_adc *kd_adc = rt_container_of(device, struct k230_adc, dev);
117+
118+
kd_adc->chn[channel].enabled = 1;
119+
if (enabled)
120+
{
121+
kd_adc->chn[channel].enabled = 1;
122+
}
123+
else
124+
{
125+
kd_adc->chn[channel].enabled = 0;
126+
}
127+
128+
return RT_EOK;
129+
}
130+
131+
rt_err_t k230_get_adc_value(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value)
132+
{
133+
if (channel >= ADC_MAX_CHANNEL)
134+
return -RT_ERROR;
135+
136+
struct k230_adc *kd_adc = rt_container_of(device, struct k230_adc, dev);
137+
138+
if (!kd_adc->chn[channel].enabled)
139+
return -RT_ERROR;
140+
141+
writel(channel | 0x10, &kd_adc->adc_regs->cfg_reg);
142+
while ((readl(&kd_adc->adc_regs->cfg_reg) & 0x10000) == 0);
143+
*value = readl(&kd_adc->adc_regs->data_reg[channel]);
144+
145+
return RT_EOK;
146+
}
147+
148+
static const struct rt_adc_ops k230_adc_ops =
149+
{
150+
.enabled = k230_adc_enabled,
151+
.convert = k230_get_adc_value,
152+
};
153+
154+
int rt_hw_adc_init(void)
155+
{
156+
k230_adc_init();
157+
158+
rt_hw_adc_register(&adc_dev.dev, K230_ADC_NAME, &k230_adc_ops, NULL);
159+
160+
return RT_EOK;
161+
}
162+
INIT_BOARD_EXPORT(rt_hw_adc_init);
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Copyright (c) 2023, Canaan Bright Sight Co., Ltd
2+
*
3+
* Redistribution and use in source and binary forms, with or without
4+
* modification, are permitted provided that the following conditions are met:
5+
* 1. Redistributions of source code must retain the above copyright
6+
* notice, this list of conditions and the following disclaimer.
7+
* 2. Redistributions in binary form must reproduce the above copyright
8+
* notice, this list of conditions and the following disclaimer in the
9+
* documentation and/or other materials provided with the distribution.
10+
*
11+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
12+
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
13+
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
21+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
/*
27+
* Copyright (c) 2006-2025 RT-Thread Development Team
28+
*
29+
* SPDX-License-Identifier: Apache-2.0
30+
*/
31+
32+
#ifndef __DRV_ADC__
33+
#define __DRV_ADC__
34+
#include "board.h"
35+
36+
#define K230_ADC_NAME "adc"
37+
38+
#define ADC_MAX_CHANNEL 6
39+
#define ADC_MAX_DMA_CHN 3
40+
41+
struct k230_adc_regs
42+
{
43+
rt_uint32_t trim_reg; /**< 0x00 */
44+
rt_uint32_t cfg_reg; /**< 0x04 */
45+
rt_uint32_t mode_reg; /**< 0x08 */
46+
rt_uint32_t thsd_reg; /**< 0x0c */
47+
rt_uint32_t dma_intr_reg; /**< 0x10 */
48+
rt_uint32_t data_reg[ADC_MAX_CHANNEL]; /**< 0x14~0x28 */
49+
rt_uint32_t data_dma[ADC_MAX_DMA_CHN]; /**< 0x2c~0x34 */
50+
};
51+
52+
struct k230_adc_chan
53+
{
54+
rt_uint32_t chn_num;
55+
rt_int8_t enabled;
56+
};
57+
58+
struct k230_adc
59+
{
60+
struct rt_adc_device dev;
61+
struct k230_adc_regs *adc_regs;
62+
struct k230_adc_chan chn[ADC_MAX_CHANNEL];
63+
};
64+
65+
#endif /*__DRV_ADC__*/

bsp/k230/drivers/utest/SConscript

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ if GetDepend('RT_UTEST_USING_ALL_CASES') or GetDepend('BSP_UTEST_DRIVERS'):
66
src += ['test_gpio.c']
77
src += ['test_gpio_irq.c']
88

9+
if GetDepend('BSP_USING_ADC'):
10+
src += ['test_adc.c']
11+
912
if GetDepend('BSP_USING_TIMERS'):
1013
src += ['test_timer.c']
1114

bsp/k230/drivers/utest/test_adc.c

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/* Copyright 2020 Canaan Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include <rtthread.h>
17+
#include <rtdevice.h>
18+
#include <stdlib.h>
19+
#include "../interdrv/adc/drv_adc.h"
20+
#include "utest.h"
21+
22+
/*
23+
* 测试 ADC 驱动的读操作
24+
* 1. 查找 ADC 设备。
25+
* 2. 启用 ADC 设备。
26+
* 3. 启用每个 ADC 通道并读取其值。
27+
* 4. 验证读取的值在预期范围内。
28+
* 5. 禁用每个 ADC 通道并验证读取值为 0。
29+
*
30+
* 本测试基于 01Studio 开发板,该开发板自带排针,并引出 SoC 的以下 4 个 ADC 通道
31+
* 板级排针编号 | SoC 的 ADC 通道编号 | 输入电压范围
32+
* -------------+---------------------+-------------
33+
* 32 | ADC0 | (0 ~ 3.6V)
34+
* 36 | ADC1 | (0 ~ 3.6V)
35+
* 38 | ADC2 | (0 ~ 1.8V)
36+
* 40 | ADC3 | (0 ~ 1.8V)
37+
* SoC 的 ADC 通道默认只支持最大 1.8V 的输入电压,对于 ADC0 和 ADC1 通道,开发板
38+
* 通过增加功放将最大支持电压提升到 3.6V(而且同样采用了分压机制,导致实际 ADC
39+
* 通道的输入电压只有板级排针电压的一半)。
40+
*
41+
* 测试时注意连接输入的最大电压不要超过额定值,否则可能会损坏 ADC 通道。
42+
*
43+
* 另外注意这个adc 只有 12bit,所以读取的值范围是 0 ~ 4095
44+
*
45+
* 具体测试最大 1.8V 的 ADC 通道(譬如 38/40)时,可以自己通过两个 10K 欧姆的电
46+
* 阻将模拟输入从 3.3V 分压(将可调电阻调制最大时万用表实测 A 点电压为 1.69V 左右):
47+
* +----------+ +---------------+
48+
* 3.3V ----| 10K 欧姆 |----| 可调 10K 欧姆 |---- 接地
49+
* +----------+ +---------------+
50+
* A
51+
* |
52+
* ADC2/ADC3
53+
*
54+
* 具体测试最大 3.6V 的 ADC 通道(譬如 32/36)时,可以直接引入 3.3V。
55+
* +---------------+
56+
* 3.3V --------------------| 可调 10K 欧姆 |---- 接地
57+
* +---------------+
58+
* A
59+
* |
60+
* ADC0/ADC1
61+
*/
62+
static void test_read(void)
63+
{
64+
int i;
65+
rt_err_t ret = RT_EOK;
66+
rt_uint32_t value, vol;
67+
rt_adc_device_t adc_dev;
68+
69+
adc_dev = (rt_adc_device_t)rt_device_find(K230_ADC_NAME);
70+
uassert_not_null(adc_dev);
71+
72+
ret = rt_adc_enable(adc_dev, 0);
73+
uassert_int_equal(ret, RT_EOK);
74+
75+
for (i = 0; i < 4; i++)
76+
{
77+
ret = rt_adc_enable(adc_dev, i);
78+
uassert_int_equal(ret, RT_EOK);
79+
80+
value = rt_adc_read(adc_dev, i);
81+
/* 转换为对应电压值,对应 12 位 ADC 最大值 4095, 内部基准最大电压值 1.8V,数据精度乘以 100 保留 2 位小数 */
82+
vol = value * 180 / 4095;
83+
if (i == 0 || i == 1)
84+
vol = vol * 2; /* ADC0/ADC1 分压后实际电压是输入电压的二分之一 */
85+
86+
LOG_I("ADC chan[%d] read value: %d, calculated voltage is: %d.%02dV\n",
87+
i, value, vol / 100, vol % 100);
88+
}
89+
90+
for (i = 0; i < ADC_MAX_CHANNEL; i++)
91+
{
92+
ret = rt_adc_disable(adc_dev, i);
93+
uassert_int_equal(ret, RT_EOK);
94+
95+
value = rt_adc_read(adc_dev, i);
96+
uassert_int_equal(value, 0);
97+
}
98+
99+
return;
100+
}
101+
102+
static rt_err_t utest_tc_init(void)
103+
{
104+
105+
return RT_EOK;
106+
}
107+
108+
static rt_err_t utest_tc_cleanup(void)
109+
{
110+
111+
return RT_EOK;
112+
}
113+
114+
static void testcase(void)
115+
{
116+
UTEST_UNIT_RUN(test_read);
117+
}
118+
UTEST_TC_EXPORT(testcase, "adc", utest_tc_init, utest_tc_cleanup, 100);

0 commit comments

Comments
 (0)