tests/driver/adc: Add ADC accuracy test
These tests, that expects boards to be properly setup, allow one to measure ADC value and compare to expected values. Two tests are added. For one, a reference voltage is expected on the ADC - and this value can be informed to the test via devicetree. The other uses DAC to generate a value that is then read from ADC. This assumes DAC is accurate. Naturally, one could make this a DAC test if ADC is assumed to be accurate. As the board setup involve connecting physical pins, they are behind twister fixtures. Signed-off-by: Yusuf Ahmed <muhammed.ahmed@intel.com> Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
This commit is contained in:
parent
6514b3b88d
commit
f22d30b853
10
tests/drivers/adc/adc_accuracy_test/CMakeLists.txt
Normal file
10
tests/drivers/adc/adc_accuracy_test/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(dac_accuracy)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
||||
target_sources_ifdef(CONFIG_REFERENCE_VOLTAGE_TEST app PRIVATE src/ref_volt.c)
|
||||
target_sources_ifdef(CONFIG_DAC_SOURCE_TEST app PRIVATE src/dac_source.c)
|
||||
22
tests/drivers/adc/adc_accuracy_test/Kconfig
Normal file
22
tests/drivers/adc/adc_accuracy_test/Kconfig
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright (c) 2023 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
mainmenu "ADC accuracy test"
|
||||
|
||||
source "Kconfig.zephyr"
|
||||
|
||||
# Workaround to have commas on function arguments
|
||||
ZEPHYR_USER := zephyr,user
|
||||
|
||||
config DAC_SOURCE_TEST
|
||||
bool
|
||||
default y if $(dt_node_has_prop,/$(ZEPHYR_USER),dac)
|
||||
|
||||
config REFERENCE_VOLTAGE_TEST
|
||||
bool
|
||||
default y if $(dt_node_has_prop,/$(ZEPHYR_USER),reference_mv)
|
||||
|
||||
config NUMBER_OF_PASSES
|
||||
int "Number of passes"
|
||||
default 5
|
||||
21
tests/drivers/adc/adc_accuracy_test/README.txt
Normal file
21
tests/drivers/adc/adc_accuracy_test/README.txt
Normal file
@ -0,0 +1,21 @@
|
||||
ADC accuracy test
|
||||
|
||||
This test checks that ADC readings match an expected value. It is
|
||||
done using two approaches:
|
||||
|
||||
- DAC source: a board DAC pin is set to a known value, which is then
|
||||
read on an ADC one. If they match, the test passes.
|
||||
|
||||
- Reference voltage: an ADC channel is read and compared to an expected
|
||||
value.
|
||||
|
||||
For the DAC source, it is expected that DAC and ADC are connected. This
|
||||
can be indicated for twister runs by setting the fixture "dac_adc_loop".
|
||||
The test then sets DAC to half its resolution and reads the ADC to see
|
||||
if they match. Note that DAC and ADC are expected to generate/read
|
||||
voltage on the same range.
|
||||
|
||||
In the reference voltage case, the ADC is expected to be connected to a
|
||||
known voltage reference, whose value is informed, in millivolts, at
|
||||
property "reference_mv" from "zephyr,user" node. The test reads the ADC
|
||||
to see if they match.
|
||||
@ -0,0 +1 @@
|
||||
CONFIG_DAC=y
|
||||
32
tests/drivers/adc/adc_accuracy_test/boards/frdm_k64f.overlay
Normal file
32
tests/drivers/adc/adc_accuracy_test/boards/frdm_k64f.overlay
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/* Please connect J4.3 and J4.11 together to run this test.
|
||||
* J4.3 will be the ADC input and J4.11 the DAC output
|
||||
*/
|
||||
|
||||
/ {
|
||||
zephyr,user {
|
||||
io-channels = <&adc0 20>;
|
||||
dac = <&dac0>;
|
||||
dac-channel-id = <0>;
|
||||
dac-resolution = <12>;
|
||||
};
|
||||
};
|
||||
|
||||
&adc0{
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
channel@14 {
|
||||
reg = <20>;
|
||||
zephyr,gain = "ADC_GAIN_1";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,resolution = <12>;
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/ {
|
||||
zephyr,user {
|
||||
io-channels = <&adc0 12>;
|
||||
reference_mv = <1100>;
|
||||
};
|
||||
};
|
||||
|
||||
&adc0{
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "okay";
|
||||
|
||||
channel@12 {
|
||||
reg = <12>;
|
||||
zephyr,gain = "ADC_GAIN_1";
|
||||
zephyr,reference = "ADC_REF_INTERNAL";
|
||||
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
|
||||
zephyr,resolution = <12>;
|
||||
};
|
||||
};
|
||||
2
tests/drivers/adc/adc_accuracy_test/prj.conf
Normal file
2
tests/drivers/adc/adc_accuracy_test/prj.conf
Normal file
@ -0,0 +1,2 @@
|
||||
CONFIG_ZTEST=y
|
||||
CONFIG_ADC=y
|
||||
78
tests/drivers/adc/adc_accuracy_test/src/dac_source.c
Normal file
78
tests/drivers/adc/adc_accuracy_test/src/dac_source.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/drivers/dac.h>
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#define DIV 2
|
||||
|
||||
#define DAC_DEVICE_NODE DT_PROP(DT_PATH(zephyr_user), dac)
|
||||
|
||||
extern const struct adc_dt_spec *get_adc_channel(void);
|
||||
|
||||
static const struct dac_channel_cfg dac_ch_cfg = {
|
||||
.channel_id = DT_PROP(DT_PATH(zephyr_user), dac_channel_id),
|
||||
.resolution = DT_PROP(DT_PATH(zephyr_user), dac_resolution),
|
||||
.buffered = true
|
||||
};
|
||||
|
||||
static const struct device *init_dac(void)
|
||||
{
|
||||
int ret;
|
||||
const struct device *const dac_dev = DEVICE_DT_GET(DAC_DEVICE_NODE);
|
||||
|
||||
zassert_true(device_is_ready(dac_dev), "DAC device is not ready");
|
||||
|
||||
ret = dac_channel_setup(dac_dev, &dac_ch_cfg);
|
||||
zassert_equal(ret, 0,
|
||||
"Setting up of the first channel failed with code %d", ret);
|
||||
|
||||
return dac_dev;
|
||||
}
|
||||
|
||||
static int test_dac_to_adc(void)
|
||||
{
|
||||
int ret, write_val;
|
||||
int32_t sample_buffer = 0;
|
||||
|
||||
struct adc_sequence sequence = {
|
||||
.buffer = &sample_buffer,
|
||||
.buffer_size = sizeof(sample_buffer),
|
||||
};
|
||||
|
||||
const struct device *dac_dev = init_dac();
|
||||
const struct adc_dt_spec *adc_channel = get_adc_channel();
|
||||
|
||||
write_val = (1U << dac_ch_cfg.resolution) / DIV;
|
||||
|
||||
ret = dac_write_value(dac_dev, DT_PROP(DT_PATH(zephyr_user), dac_channel_id), write_val);
|
||||
|
||||
zassert_equal(ret, 0, "dac_write_value() failed with code %d", ret);
|
||||
|
||||
k_sleep(K_MSEC(10));
|
||||
|
||||
adc_sequence_init_dt(adc_channel, &sequence);
|
||||
ret = adc_read_dt(adc_channel, &sequence);
|
||||
|
||||
zassert_equal(ret, 0, "adc_read_dt() failed with code %d", ret);
|
||||
zassert_within(sample_buffer,
|
||||
(1U << adc_channel->resolution) / DIV, 32,
|
||||
"Value %d read from ADC does not match expected range.",
|
||||
sample_buffer);
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
ZTEST(adc_accuracy_test, test_dac_to_adc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NUMBER_OF_PASSES; i++) {
|
||||
zassert_true(test_dac_to_adc() == TC_PASS);
|
||||
}
|
||||
}
|
||||
33
tests/drivers/adc/adc_accuracy_test/src/main.c
Normal file
33
tests/drivers/adc/adc_accuracy_test/src/main.c
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#if DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
|
||||
static const struct adc_dt_spec adc_channel = ADC_DT_SPEC_GET(DT_PATH(zephyr_user));
|
||||
#else
|
||||
#error "Unsupported board."
|
||||
#endif
|
||||
|
||||
const struct adc_dt_spec *get_adc_channel(void)
|
||||
{
|
||||
return &adc_channel;
|
||||
}
|
||||
|
||||
static void *adc_setup(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
zassert_true(adc_is_ready_dt(&adc_channel), "ADC device is not ready");
|
||||
ret = adc_channel_setup_dt(&adc_channel);
|
||||
zassert_equal(ret, 0,
|
||||
"Setting up of the ADC channel failed with code %d", ret);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZTEST_SUITE(adc_accuracy_test, NULL, adc_setup, NULL, NULL, NULL);
|
||||
48
tests/drivers/adc/adc_accuracy_test/src/ref_volt.c
Normal file
48
tests/drivers/adc/adc_accuracy_test/src/ref_volt.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/adc.h>
|
||||
#include <zephyr/ztest.h>
|
||||
|
||||
#define REF_V DT_PROP(DT_PATH(zephyr_user), reference_mv)
|
||||
|
||||
extern const struct adc_dt_spec *get_adc_channel(void);
|
||||
|
||||
static int test_ref_to_adc(void)
|
||||
{
|
||||
int ret;
|
||||
int32_t sample_buffer = 0;
|
||||
|
||||
struct adc_sequence sequence = {
|
||||
.buffer = &sample_buffer,
|
||||
.buffer_size = sizeof(sample_buffer),
|
||||
};
|
||||
|
||||
const struct adc_dt_spec *adc_channel = get_adc_channel();
|
||||
|
||||
adc_sequence_init_dt(adc_channel, &sequence);
|
||||
|
||||
ret = adc_read_dt(adc_channel, &sequence);
|
||||
zassert_equal(ret, 0, "adc_read_dt() failed with code %d", ret);
|
||||
|
||||
ret = adc_raw_to_millivolts_dt(adc_channel, &sample_buffer);
|
||||
zassert_equal(ret, 0, "adc_raw_to_millivolts_dt() failed with code %d",
|
||||
ret);
|
||||
zassert_within(sample_buffer, REF_V, 32,
|
||||
"Value %d mV read from ADC does not match expected range (%d mV).",
|
||||
sample_buffer, REF_V);
|
||||
|
||||
return TC_PASS;
|
||||
}
|
||||
|
||||
ZTEST(adc_accuracy_test, test_ref_to_adc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CONFIG_NUMBER_OF_PASSES; i++) {
|
||||
zassert_true(test_ref_to_adc() == TC_PASS);
|
||||
}
|
||||
}
|
||||
19
tests/drivers/adc/adc_accuracy_test/testcase.yaml
Normal file
19
tests/drivers/adc/adc_accuracy_test/testcase.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
common:
|
||||
tags:
|
||||
- adc
|
||||
- drivers
|
||||
depends_on:
|
||||
- adc
|
||||
tests:
|
||||
drivers.adc.accuracy.dac_source:
|
||||
depends_on:
|
||||
- dac
|
||||
harness_config:
|
||||
fixture: dac_adc_loopback
|
||||
platform_allow:
|
||||
- frdm_k64f
|
||||
drivers.adc.accuracy.ref_volt:
|
||||
harness_config:
|
||||
fixture: adc_ref_volt
|
||||
platform_allow:
|
||||
- frdm_kl25z
|
||||
Loading…
Reference in New Issue
Block a user