Skip to content

Commit

Permalink
sample: sensor: add gecko acmp sample
Browse files Browse the repository at this point in the history
- Add sample for Gecko ACMP sensor driver

Signed-off-by: Romain Pelletant <[email protected]>
  • Loading branch information
Romain Pelletant committed Jan 3, 2025
1 parent 1d25248 commit 8d965a7
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 0 deletions.
9 changes: 9 additions & 0 deletions samples/sensor/gecko_acmp/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(gecko_acmp)

FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})
31 changes: 31 additions & 0 deletions samples/sensor/gecko_acmp/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.. zephyr:code-sample:: gecko_acmp
:name: SiLabs Gecko Analog Comparator (ACMP)
:relevant-api: sensor_interface

Get analog comparator data from an SiLabs Gecko Analog Comparator (ACMP).

Overview
********

This sample show how to use the SiLabs Gecko Analog Comparator (ACMP) driver.

In this application, the negative input port of the ACMP is muxed to the internal
low-power reference voltage 1.25V.
The positive input port is muxed to VDD (VSENSE01DIV4LP) divided by 4.
The threshold value is set to 20h (32d).
Corresponding voltage threshold VREFOUT = VREFIN * (VREFDIV / 63) = (1.25V * 4) * (32 / 63) = 2.54V.
The ACMP output shall be set to 1 when VDD voltage is under 2.54V and is reported on the console.

Building and Running
********************

Building and Running for SiLabs EFR32MG24 Mighty Gecko Board dev kit
=========================================
Build the application for the :zephyr:board:`xg24_dk2601b` board, and adjust the
ACMP positive/negative input ports and vrefdiv in xg24_dk2601b.overlay file directly.

.. zephyr-app-commands::
:zephyr-app: samples/sensor/gecko_acmp
:board: xg24_dk2601b
:goals: build flash
:compact:
17 changes: 17 additions & 0 deletions samples/sensor/gecko_acmp/boards/xg24_dk2601b.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2025 Kickmaker
*
* SPDX-License-Identifier: Apache-2.0
*/

&acmp0 {
status = "okay";
bias-level = <0>;
input-range = "Reduced";
accuracy = "Low";
vrefdiv = <0x20>;
hysteresis-level = "Disabled";
positive-input = "VSENSE01DIV4LP";
negative-input = "VREFDIV1V25LP";
interrupt-mode = "FallingEdge";
};
2 changes: 2 additions & 0 deletions samples/sensor/gecko_acmp/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_SENSOR=y
CONFIG_GECKO_ACMP_TRIGGER=y
23 changes: 23 additions & 0 deletions samples/sensor/gecko_acmp/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
sample:
description: Demonstration of the SiLabs Gecko ACMP driver
name: SiLabs Gecko ACMP sample
common:
platform_allow:
- xg24_dk2601b
integration_platforms:
- xg24_dk2601b
tags:
- drivers
- sensor
tests:
sample.sensor.gecko_acmp:
harness: console
harness_config:
type: one_line
ordered: true
regex:
- "ACMP input [a-z]* threshold"
sample.sensor.gecko_acmp.no_trigger:
build_only: true
extra_configs:
- CONFIG_GECKO_ACMP_TRIGGER=n
136 changes: 136 additions & 0 deletions samples/sensor/gecko_acmp/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright Kickmaker 2025
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/gecko_acmp.h>
#include <zephyr/kernel.h>
#include <stdio.h>

#ifdef CONFIG_GECKO_ACMP_TRIGGER
static const int16_t triggers[] = {
SENSOR_TRIG_GECKO_ACMP_OUTPUT_RISING,
SENSOR_TRIG_GECKO_ACMP_OUTPUT_FALLING,
};
#endif /* CONFIG_GECKO_ACMP_TRIGGER */

static void acmp_input_handler(bool above_threshold)
{
if (above_threshold) {
printf("ACMP input above threshold\n");
} else {
printf("ACMP input below threshold\n");
}
}

#ifdef CONFIG_GECKO_ACMP_EDGE_COUNTER
static void acmp_read_edge_counters(const struct device *dev, struct sensor_value *val)
{
int err;

if (!val) {
return;
}

err = sensor_sample_fetch(dev);
if (err) {
printf("failed to fetch sample (err %d)\n", err);
return;
}

err = sensor_channel_get(dev, SENSOR_CHAN_GECKO_ACMP_RISING_EDGE_COUNTER, val);
if (err) {
printf("failed to get channel (err %d)\n", err);
return;
}

printf("Rising edge counter: %d\n", val.val1);

err = sensor_channel_get(dev, SENSOR_CHAN_GECKO_ACMP_FALLING_EDGE_COUNTER, &val);
if (err) {
printf("failed to get channel (err %d)\n", err);
return;
}

printf("Falling edge counter: %d\n", val.val1);
}
#endif /* CONFIG_GECKO_ACMP_EDGE_COUNTER */

#ifdef CONFIG_GECKO_ACMP_TRIGGER
static void acmp_trigger_handler(const struct device *dev, const struct sensor_trigger *trigger)
{
ARG_UNUSED(dev);

acmp_input_handler((int16_t)trigger->type == SENSOR_TRIG_GECKO_ACMP_OUTPUT_RISING);
}
#endif /* CONFIG_GECKO_ACMP_TRIGGER */

int main(void)
{
#ifdef CONFIG_GECKO_ACMP_TRIGGER
struct sensor_trigger trigger[ARRAY_SIZE(triggers)] = {
[0] = {
.chan = SENSOR_CHAN_GECKO_ACMP_OUTPUT,
.type = triggers[0],
},
[1] = {
.chan = SENSOR_CHAN_GECKO_ACMP_OUTPUT,
.type = triggers[1],
}
};
#endif /* CONFIG_GECKO_ACMP_TRIGGER */
const struct device *const acmp = DEVICE_DT_GET(DT_NODELABEL(acmp0));
int err;

if (!device_is_ready(acmp)) {
printf("ACMP device not ready\n");
return 0;
}

#ifdef CONFIG_GECKO_ACMP_TRIGGER
/* Set ACMP triggers */
for (uint8_t i = 0; i < ARRAY_SIZE(triggers); i++) {
err = sensor_trigger_set(acmp, &trigger[i], acmp_trigger_handler);
if (err) {
printf("failed to set trigger %d (err %d)\n", i, err);
return 0;
}
}

/* Await trigger */
while (true) {
#ifdef CONFIG_GECKO_ACMP_EDGE_COUNTER
struct sensor_value val;

acmp_read_edge_counters(acmp, &val);
#endif /* CONFIG_GECKO_ACMP_EDGE_COUNTER */
k_sleep(K_SECONDS(1));
}
#else /* !CONFIG_GECKO_ACMP_TRIGGER */
while (true) {
struct sensor_value val;

err = sensor_sample_fetch(acmp);
if (err) {
printf("failed to fetch sample (err %d)\n", err);
return 0;
}

err = sensor_channel_get(acmp, SENSOR_CHAN_GECKO_ACMP_OUTPUT, &val);
if (err) {
printf("failed to get channel (err %d)\n", err);
return 0;
}

acmp_input_handler(val.val1 == 1);

k_sleep(K_MSEC(1));
}

#endif /* CONFIG_GECKO_ACMP_TRIGGER */

return 0;
}

0 comments on commit 8d965a7

Please sign in to comment.