Nordic nRF54L15-DK Zephyr SAADC en Linux

Por favor refiéraze al artículo publicado anteriormente relacionado a la instalación del sistema operativo en tiempo real Zephyr. El propósito de este artículo es presentar una aplicación que obtiene los valores digitalizados del SAADC. Primeramente se crea este archivo prj.conf de la configuración del projecto Zephyr dentro del directorio de su preferencia,

#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_LOG=y
# STEP 1 - Enable the ADC API and driver
CONFIG_ADC=y

El archivo de la aplicación llamado main.c es el siguiente,

/*
 * Copyright (c) 2024 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
/* STEP 3.1 - Include the header file of the Zephyr ADC API */
#include <zephyr/drivers/adc.h>

/* STEP 3.2 - Define a variable of type adc_dt_spec for each channel */
static const struct adc_dt_spec adc_channel = ADC_DT_SPEC_GET(DT_PATH(zephyr_user));

LOG_MODULE_REGISTER(Output, LOG_LEVEL_DBG);

int main(void)
{
	int err;
	uint32_t count = 0;

	/* STEP 4.1 - Define a variable of type adc_sequence and a buffer of type uint16_t */
	int16_t buf;
	struct adc_sequence sequence = {
		.buffer = &buf,
		/* buffer size in bytes, not number of samples */
		.buffer_size = sizeof(buf),
		// Optional
		//.calibrate = true,
	};

	/* STEP 3.3 - validate that the ADC peripheral (SAADC) is ready */
	if (!adc_is_ready_dt(&adc_channel)) {
		LOG_ERR("ADC controller devivce %s not ready", adc_channel.dev->name);
		return 0;
	}
	/* STEP 3.4 - Setup the ADC channel */
	err = adc_channel_setup_dt(&adc_channel);
	if (err < 0) {
		LOG_ERR("Could not setup channel #%d (%d)", 0, err);
		return 0;
	}
	/* STEP 4.2 - Initialize the ADC sequence */
	err = adc_sequence_init_dt(&adc_channel, &sequence);
	if (err < 0) {
		LOG_ERR("Could not initalize sequnce");
		return 0;
	}

	while (1) {
		int val_mv;

		/* STEP 5 - Read a sample from the ADC */
		err = adc_read(adc_channel.dev, &sequence);
		if (err < 0) {
			LOG_ERR("Could not read (%d)", err);
			continue;
		}

		val_mv = (int)buf;
		LOG_INF("ADC reading[%u]: %s, channel %d: Raw: %d", count++, adc_channel.dev->name,
			adc_channel.channel_id, val_mv);

		/* STEP 6 - Convert raw value to mV*/
		err = adc_raw_to_millivolts_dt(&adc_channel, &val_mv);
		/* conversion to mV may not be supported, skip if not */
		if (err < 0) {
			LOG_WRN(" (value in mV not available)\n");
		} else {
			LOG_INF(" = %d mV", val_mv);
		}

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

Finalmente, se crea el siguiente archivo nrf54l15dk_nrf54l15.overlay que define el SAADC dentro de Zephyr API,

/ {
	zephyr,user {
		io-channels = <&adc 0>;
	};
};

&adc {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";
	channel@0 {
		reg = <0>;
		zephyr,gain = "ADC_GAIN_1_4";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN4>; /* P1.11 for the nRF54L15 DK */
		zephyr,resolution = <14>;
	};
}

El árbol de directorio es el siguiente,

├── CMakeLists.txt
├── nrf54l15dk_nrf54l15.overlay
├── prj.conf
└── src
    └── main.c

Ahora se procede a compilar este projecto como se muestra a continuación dentro del ambiente virtual de python,

digikey_coffee_cup (venv) $  west build -p always -b nrf54l15dk/nrf54l15/cpuapp -- -DEXTRA_DTC_OVERLAY_FILE=nrf54l15dk_nrf54l15.overlay

Por último se conecta el nRF54L15-DK por el USB y se procede a programarlo como sigue,

digikey_coffee_cup (venv) $  west flash
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner nrfutil
-- runners.nrfutil: reset after flashing requested
Using board 001057777221
-- runners.nrfutil: Flashing file: /home/engineer/Digikey/Projects/Workspace/zephyr/zephyrproject/zephyr/adc/build/zephyr/zephyr.hex
-- runners.nrfutil: Connecting to probe
-- runners.nrfutil: Programming image
-- runners.nrfutil: Verifying image
-- runners.nrfutil: Reset
-- runners.nrfutil: Board(s) with serial number(s) 1057777221 flashed successfully.

Tan pronto se programe el sistema, se procede a abrir una ventana del terminal minicom como sigue,

digikey_coffee_cup $ minicom -D /dev/ttyACM1

Welcome to minicom 2.9

OPTIONS: I18n 
Port /dev/ttyACM1, 19:28:23

Press CTRL-A Z for help on special keys

[00:04:54.044,706] <inf> Output: ADC reading[294]: adc@d5000, channel 0: Raw: 1056
[00:04:54.044,714] <inf> Output:  = 232 mV
[00:04:55.044,857] <inf> Output: ADC reading[295]: adc@d5000, channel 0: Raw: 1056
[00:04:55.044,869] <inf> Output:  = 232 mV
[00:04:56.044,994] <inf> Output: ADC reading[296]: adc@d5000, channel 0: Raw: 640
[00:04:56.045,002] <inf> Output:  = 140 mV
[00:04:57.045,145] <inf> Output: ADC reading[297]: adc@d5000, channel 0: Raw: 3840
[00:04:57.045,157] <inf> Output:  = 843 mV
[00:04:58.045,282] <inf> Output: ADC reading[298]: adc@d5000, channel 0: Raw: 4928
[00:04:58.045,290] <inf> Output:  = 1082 mV
[00:04:59.045,433] <inf> Output: ADC reading[299]: adc@d5000, channel 0: Raw: 8256
[00:04:59.045,445] <inf> Output:  = 1814 mV
[00:05:00.045,570] <inf> Output: ADC reading[300]: adc@d5000, channel 0: Raw: 8240
[00:05:00.045,578] <inf>Output:  = 1810 mV

La secuencia previa muestra como el nRF54L15-DK SAADC fue conectado al terminal externo VDIO el cuál esta a una referencia de 1.8V, el terminal abierto y el términal de tierra “Ground”, esto muestra que bajo estas condiciones esta funcionando. El nRF54L15-DK disponible en DigiKey

es una plataforma excelente para desorrallar aplicaciones para artefactos conectados al internet (IoT). Que tenga un excelente día.

Este artículo está disponbile en inglés aquí.

This article is available in english here.

1 Like