En el previo artículo se demonstró como conectar a un Sensor TDK ICOM-20948 vía Qwiic de Sparkfun en una actual aplicación de Zephyr) para rastrear las direcciones de los sensores en la linea I2C desde el shell de Zephyr. En este artículo la función de escribir a un artefacto se desarrollará aqui en Digikey dentro de un aplicación de Zephyr. El sistema operativo Zephyr ya provee un mecanismo para muchos sensores usando herramientas como KConfig y Devicetree, pero este artículo provee una alternativa para aquellos que quieren desarrollar directamente con la interfaz de I2C dentro de Zephyr, donde algunos casos puede ser necesario. También, dentro del proceso de crear la aplicación, los archivos esenciales y la estructura de directorio sera descrita para el Raspberry Pico 2. Primero, abra un terminal de minicom, el cual se usara luego para ver la salida de la aplicación de la Raspberry Pico 2 que está corriendo Zephyr,
$ minicom -D /dev/ttyACM0
Welcome to minicom 2.8
OPTIONS: I18n
Port /dev/ttyACM0, 12:41:43
Press CTRL-A Z for help on special keys
Dentro del directorio conocido como Zephyr se crea un directorio llamado myproject, entonces, dentro de ese directorio se crean los siguientes archivos,
The CMake file named CMakeLists.txt,
cmake_minimum_required(VERSION 3.25.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(i2c_scanner)
target_sources(app PRIVATE src/main.c)
El archivo de configuración Zephyr OS llamado prj.conf,
CONFIG_I2C=y
CONFIG_RTIO=y
CONFIG_I2C_RTIO=y
CONFIG_I2C_TARGET=y
CONFIG_I2C_TARGET_BUFFER_MODE=y
El archivo del sistema operativo Zephyr conocido comoe el Overlay file en este caso llamado RP2350.overlay que define el puerto I2C en este caso i2c port 0 en la Raspberry Pico 2
/ {
aliases {
scan-i2c = &i2c0;
};
};
El programa main.c desarrollado aqui en Digikey reside en un subdirectorio llamado src
/*Digikey Coffee Cup*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/i2c/rtio.h>
#include <string.h>
#define CONFIG_I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE 1
#define CONFIG_I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE 1
#define I2C_TARGET_ADDR 0x69
static const struct device *scan_dev = DEVICE_DT_GET(DT_ALIAS(scan_i2c));
static uint8_t sample_write_data[CONFIG_I2C_RTIO_LOOPBACK_DATA_WRITE_MAX_SIZE];
static uint8_t sample_write_buf[sizeof(sample_write_data)];
static uint32_t sample_write_buf_pos;
static uint8_t sample_read_data[CONFIG_I2C_RTIO_LOOPBACK_DATA_READ_MAX_SIZE];
static uint32_t sample_read_data_pos;
static uint8_t sample_read_buf[sizeof(sample_read_data)];
uint8_t david_digikey_coffee_cup_zephyr_i2c_write(uint8_t address, uint8_t value)
{
uint8_t error = 0u;
struct i2c_msg msgs[2];
msgs[0].buf = &address;
msgs[0].len = 1U;
msgs[0].flags = I2C_MSG_WRITE;
msgs[1].buf = &value;
msgs[1].len = sizeof(value);
msgs[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
error = i2c_transfer(scan_dev, msgs, 2, I2C_TARGET_ADDR);
if (error == 0) {
printk("I2C Bus Digikey Coffee Cup Write Complete\n");
}
else {
printk("I2C Bus Digikey Coffee Cup Error\n");
}
return error;
}
int main(void)
{
k_sleep(K_SECONDS(1));
if (!scan_dev) {
printk("I2C: Device driver not found.\n");
return -1;
}
printk("*** David Digikey Coffee Cup Zephyr I2C ***\n");
printk("Board: %s\n", CONFIG_BOARD);
printk("I2C device: %s\n", scan_dev->name);
uint8_t address = 0x00;
uint8_t theregister = 0x00;
uint8_t value = 0x00;
while(1)
{
printk("david_digikey_coffee_cup_zephyr_i2c_write(address, value)\n");
address = 0x05;
value = 0x00;
david_digikey_coffee_cup_zephyr_i2c_write(address, value);
k_sleep(K_MSEC(500));
}
return 0;
}
El previo programa demuestra como escribir al sensor cada 500 mS en la linea I2C usando el sistema operativo Zephyr en la Raspberry Pico 2.
El directorio myproject es el siguiente,
|-- CMakeLists.txt
|-- prj.conf
|-- RP2350.overlay
`-- src
`-- main.c
Ahora se procede a construir la aplicación en el sistema operativo Zephyr en la Raspberry Pico 2 usando el previo archivo RP2350.overlay file como sigue,
(venv) $ west build -p always -b rpi_pico2/rp2350a/m33 -S cdc-acm-console -- -DCONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -DEXTRA_DTC_OVERLAY_FILE=RP2350.overlay
El Sparkfun 8-channel USB Logic Analyzer previamente descrito aqui Techforum article se configuró como se muestra en la siguiente foto usando estos cables I2C Qwiic para monitorear la linea I2C usando el voltaje apropiado, PIN6 (SDA), PIN7 (SCL) (I2C Port 0) y el PIN 38 (GND) en la Raspberry Pico 2,
y la configuración del bread board de evaluación de Digikey,
El Sparkfun 8-channel USB Logic Analyzer fue conectado al SCL, SDA (Señales de la linea I2C) y el GND (Ground) como se muestran anteriormente (No la forma optima de conección debido a los cables muy extensos). Ahora se procede a programar la aplicación de Zephyr en la Raspberry Pico 2
(venv) $ west flash --runner uf2
En el terminal de minicom se verá lo siguiente,
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
I2C Bus Digikey Coffee Cup Write Complete
david_digikey_coffee_cup_zephyr_i2c_write(address, value)
........
El Sparkfun 8-channel USB Logic Analyzer
confirma que el programa bajo Zephyr corriendo dentro del Raspberry Pico 2 use sola definición de I2C en el archivo overlay del sistema operativo Zephyr funciona.. La secuencia apropiada de la interfaz I2C, I2C_MSG_WRITE, I2C_MSG_WRITE, I2C_MSG_STOP definida en el main.c desarrollada aqui en Digikey para la maquina de estados finitos internas esta aquí,
Esta transacción de I2C confirmada por el logic analyzer en la linea I2C, cambia el modo de operación de baja potencia para remove duty cycled mode de los sensores MEMS. Que tenga un buen día.
Este articulo esta disponble en idioma inglés aquí.
This article is also available in english here.


