Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test for ADC pins #5

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions boards/test_stm32f405_feather/test_stm32f405_feather.dts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@
status = "okay";
};

&adc1 {
st,adc-prescaler = <2>;
status = "okay";
};

zephyr_udc0: &usbotg_fs {
pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>;
pinctrl-names = "default";
Expand Down
9 changes: 9 additions & 0 deletions samples/test_adc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(test_adc)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
5 changes: 5 additions & 0 deletions samples/test_adc/VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
VERSION_MAJOR = 0
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
EXTRAVERSION =
67 changes: 67 additions & 0 deletions samples/test_adc/boards/test_stm32f405_feather.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Copyright (c) 2025 Lucian Copeland for Adafruit Industries
SPDX-License-Identifier: Apache-2.0 */

/ {
zephyr,user {
/* adjust channel number according to pinmux in board.dts */
io-channels = <&adc1 4>, <&adc1 5>, <&adc1 6>, <&adc1 7>, <&adc1 14>, <&adc1 15>;
};
};

&adc1 {
#address-cells = <1>;
#size-cells = <0>;

pinctrl-0 = <&adc1_in4_pa4>, <&adc1_in5_pa5>, <&adc1_in6_pa6>, <&adc1_in7_pa7>,
<&adc1_in14_pc4>, <&adc1_in15_pc5>;
pinctrl-names = "default";

/* Define ADC channels */
channel@4 {
reg = <4>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};

channel@5 {
reg = <5>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};

channel@6 {
reg = <6>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};

channel@7 {
reg = <7>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};

channel@14 {
reg = <14>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};

channel@15 {
reg = <15>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};
};
1 change: 1 addition & 0 deletions samples/test_adc/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_ADC=y
102 changes: 102 additions & 0 deletions samples/test_adc/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2020 Libre Solar Technologies GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
ADC_DT_SPEC_GET_BY_IDX(node_id, idx),

/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
DT_SPEC_AND_COMMA)
};

int main(void)
{
int err;
uint32_t count = 0;
uint16_t buf;
struct adc_sequence sequence = {
.buffer = &buf,
/* buffer size in bytes, not number of samples */
.buffer_size = sizeof(buf),
};

/* Configure channels individually prior to sampling. */
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
if (!adc_is_ready_dt(&adc_channels[i])) {
printk("ADC controller device %s not ready\n", adc_channels[i].dev->name);
return 0;
}

err = adc_channel_setup_dt(&adc_channels[i]);
if (err < 0) {
printk("Could not setup channel #%d (%d)\n", i, err);
return 0;
}
}

#ifndef CONFIG_COVERAGE
while (1) {
#else
for (int k = 0; k < 10; k++) {
#endif
printk("ADC reading[%u]:\n", count++);
for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
int32_t val_mv;

printk("- %s, channel %d: ",
adc_channels[i].dev->name,
adc_channels[i].channel_id);

(void)adc_sequence_init_dt(&adc_channels[i], &sequence);

err = adc_read_dt(&adc_channels[i], &sequence);
if (err < 0) {
printk("Could not read (%d)\n", err);
continue;
}

/*
* If using differential mode, the 16 bit value
* in the ADC sample buffer should be a signed 2's
* complement value.
*/
if (adc_channels[i].channel_cfg.differential) {
val_mv = (int32_t)((int16_t)buf);
} else {
val_mv = (int32_t)buf;
}
printk("%"PRId32, val_mv);
err = adc_raw_to_millivolts_dt(&adc_channels[i],
&val_mv);
/* conversion to mV may not be supported, skip if not */
if (err < 0) {
printk(" (value in mV not available)\n");
} else {
printk(" = %"PRId32" mV\n", val_mv);
}
}

k_sleep(K_MSEC(1000));
}
return 0;
}