samples: drivers: Add auxdisplay_digits sample

This commit introduces a new sample for the Auxiliary display driver.

The sample demonstrates counting from 0 to 1000, with an interval of 100ms
between each increment.

This sample primarily serves to demonstrate the capabilities of segment
displays.

Signed-off-by: Chen Xingyu <hi@xingrz.me>
This commit is contained in:
Chen Xingyu 2024-02-03 20:29:21 +08:00 committed by Benjamin Cabé
commit dc4e259dde
7 changed files with 205 additions and 0 deletions

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr HINTS $ENV{ZEPHYR_BASE})
project(auxdisplay_digits)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,33 @@
.. zephyr:code-sample:: auxdisplay_digits
:name: Auxiliary digits display
:relevant-api: auxdisplay_interface
Output increasing numbers to an auxiliary display.
Overview
********
This sample demonstrates the use of the
:ref:`auxiliary display driver <auxdisplay_api>` for digit-based displays, such
as 7-segment displays.
Building and Running
********************
Note that this sample requires a board with a 7-segment display setup. You can
build your own setup by fly-wiring a 7-segment display to any board you have.
A sample overlay is provided for the ``native_sim`` target. See the overlay file
:zephyr_file:`samples/drivers/auxdisplay_digits/boards/native_sim.overlay` for a
demonstration.
.. zephyr-app-commands::
:zephyr-app: samples/drivers/auxdisplay_digits
:host-os: unix
:board: native_sim
:goals: build
:compact:
If successful, the display first lights up all segments (e.g., 8.8.8. on a
3-digit display), blinks once, sequentially lights up each digit from left to
right, and then counts up from 0 to the maximum number that can be displayed.

View file

@ -0,0 +1 @@
CONFIG_GPIO=y

View file

@ -0,0 +1,30 @@
/*
* Copyright (c) 2024-2025 Chen Xingyu <hi@xingrz.me>
*
* SPDX-License-Identifier: Apache-2.0
*/
&gpio0 {
ngpios = <11>;
};
/ {
auxdisplay_0: auxdisplay {
compatible = "gpio-7-segment";
status = "okay";
columns = <3>;
rows = <1>;
segment-gpios = <&gpio0 0 0>, /* A */
<&gpio0 1 0>, /* B */
<&gpio0 2 0>, /* C */
<&gpio0 3 0>, /* D */
<&gpio0 4 0>, /* E */
<&gpio0 5 0>, /* F */
<&gpio0 6 0>, /* G */
<&gpio0 7 0>; /* DP */
digit-gpios = <&gpio0 8 0>, /* DIG1 */
<&gpio0 9 0>, /* DIG2 */
<&gpio0 10 0>; /* DIG3 */
refresh-period-ms = <1>;
};
};

View file

@ -0,0 +1,2 @@
CONFIG_AUXDISPLAY=y
CONFIG_LOG=y

View file

@ -0,0 +1,11 @@
sample:
description: Demonstration of auxdisplay driver for segment displays
name: Auxiliary (segment) display sample
tests:
sample.drivers.auxdisplay_digits:
tags: auxdisplay
platform_allow:
- native_sim
integration_platforms:
- native_sim
build_only: true

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2023 Jamie McCrae
* Copyright (c) 2024-2025 Chen Xingyu <hi@xingrz.me>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/auxdisplay.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(auxdisplay_sample, LOG_LEVEL_DBG);
#define AUXDISPLAY_NODE DT_NODELABEL(auxdisplay_0)
#define AUXDISPLAY_DIGIT_COUNT DT_PROP_LEN(AUXDISPLAY_NODE, digit_gpios)
static const struct device *const dev = DEVICE_DT_GET(AUXDISPLAY_NODE);
static uint8_t data[AUXDISPLAY_DIGIT_COUNT * 2];
int main(void)
{
int rc;
int i, len;
if (!device_is_ready(dev)) {
LOG_ERR("Auxdisplay device is not ready.");
return -ENODEV;
}
/* Light up all segments */
for (i = 0; i < AUXDISPLAY_DIGIT_COUNT; i++) {
data[i * 2] = '8';
data[i * 2 + 1] = '.';
}
rc = auxdisplay_write(dev, data, strlen(data));
if (rc != 0) {
LOG_ERR("Failed to write data: %d", rc);
return rc;
}
k_msleep(500);
/* Blinks it once */
rc = auxdisplay_display_off(dev);
if (rc != 0) {
LOG_ERR("Failed to turn display off: %d", rc);
return rc;
}
k_msleep(500);
rc = auxdisplay_display_on(dev);
if (rc != 0) {
LOG_ERR("Failed to turn display on: %d", rc);
return rc;
}
k_msleep(500);
/* Clear the display */
rc = auxdisplay_clear(dev);
if (rc != 0) {
LOG_ERR("Failed to clear display: %d", rc);
return rc;
}
k_msleep(500);
/* Test cursor movement by filling each digit with a number */
for (i = 0; i < AUXDISPLAY_DIGIT_COUNT; i++) {
snprintf(data, sizeof(data), "%d", i);
rc = auxdisplay_write(dev, data, strlen(data));
if (rc != 0) {
LOG_ERR("Failed to write data: %d", rc);
return rc;
}
k_msleep(500);
}
k_msleep(500);
/* Count from 0 up to fill all digits */
for (i = 0;; i = (i + 1) % (int)pow(10, AUXDISPLAY_DIGIT_COUNT)) {
snprintk(data, sizeof(data), "%d", i);
len = strlen(data);
rc = auxdisplay_clear(dev);
if (rc != 0) {
LOG_ERR("Failed to clear display: %d", rc);
return rc;
}
/* Right-align the number */
rc = auxdisplay_cursor_position_set(dev, AUXDISPLAY_POSITION_ABSOLUTE,
AUXDISPLAY_DIGIT_COUNT - len, 0);
if (rc != 0) {
LOG_ERR("Failed to set cursor position: %d", rc);
return rc;
}
rc = auxdisplay_write(dev, data, len);
if (rc != 0) {
LOG_ERR("Failed to write data: %d", rc);
return rc;
}
k_msleep(100);
}
return 0;
}