Skip to content

Commit 9e50a16

Browse files
committed
samples: boards: renesas: Add sample for RX LVD driver
Add a simple sample for LVD driver on RSK-RX130-512kb Signed-off-by: Quy Tran <[email protected]>
1 parent 844a11d commit 9e50a16

File tree

6 files changed

+250
-0
lines changed

6 files changed

+250
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2025 Renesas Electronics Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
6+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
7+
project(lvd)
8+
9+
FILE(GLOB app_sources src/*.c)
10+
target_sources(app PRIVATE src/main.c)

samples/boards/renesas/lvd/README.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
.. zephyr:code-sample:: renesas-lvd
2+
:name: Renesas Low-voltage Detection Sample
3+
4+
Demonstrates monitoring and reacting to voltage levels.
5+
6+
Overview
7+
********
8+
9+
This sample application shows how to use the Renesas Low-voltage Detection (LVD)
10+
driver in Zephyr to monitor supply voltage and indicate status via LEDs.
11+
The app reads the voltage status, handles LVD interrupts, and updates
12+
LEDs based on whether the voltage is above or below a configured threshold.
13+
14+
Features
15+
********
16+
17+
- Reads voltage status from the LVD peripheral.
18+
- Handles LVD interrupts (if enabled in device tree/config).
19+
- Indicates voltage status using two LEDs:
20+
- LED_ABOVE: On when voltage is above threshold.
21+
- LED_BELOW: On when voltage is below threshold.
22+
- Prints status messages to the console.
23+
24+
Hardware Setup
25+
**************
26+
27+
- Ensure that the monitored target pin is supplied with power.
28+
29+
Building and Running
30+
********************
31+
32+
To build and flash the sample on a supported Renesas RX board:
33+
34+
.. zephyr-app-commands::
35+
:zephyr-app: samples/boards/renesas/lvd
36+
:board: rsk_rx130@512kb
37+
:goals: build flash
38+
:compact:
39+
40+
Usage
41+
*****
42+
43+
- On startup, the app prints the configured voltage threshold.
44+
- The app continuously monitors the voltage:
45+
- If voltage is **above** the threshold, LED_ABOVE is turned on, LED_BELOW is off.
46+
- If voltage is **below** the threshold, LED_BELOW is turned on, LED_ABOVE is off.
47+
- If LVD interrupt is enabled, voltage changes will trigger an interrupt and update the
48+
status immediately.
49+
50+
Customization
51+
*************
52+
53+
- You can change the voltage threshold and LVD action via device tree properties.
54+
- LED pins can be reassigned by modifying the ``led0`` and ``led1`` aliases in your
55+
board's DTS.
56+
57+
Example Output
58+
**************
59+
60+
::
61+
62+
===========================================================
63+
LVD Voltage Monitoring Sample Started
64+
Threshold Voltage Level : 384 mV
65+
===========================================================
66+
[LVD Init] Voltage is ABOVE threshold (384 mV)
67+
[LVD] Interrupt: Voltage level crossing detected!
68+
[WARNING] Voltage instability detected! Check power supply.
69+
[LVD] Voltage is BELOW threshold (384 mV)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
&pinctrl {
7+
lvd1_default: lvd1_default {
8+
group1 {
9+
/* CMPA2 */
10+
psels = <RX_PSEL(RX_PSEL_LVD, 14, 4)>;
11+
renesas,analog-enable;
12+
input-enable;
13+
};
14+
};
15+
};
16+
17+
&lvd1 {
18+
pinctrl-0 = <&lvd1_default>;
19+
pinctrl-names = "default";
20+
lvd-action = "maskable-interrupt";
21+
voltage-level = <384>;
22+
vdet-target = "cmpa";
23+
lvd-trigger = "rising";
24+
lvd-stabilization = <0>;
25+
status = "okay";
26+
};

samples/boards/renesas/lvd/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CONFIG_LOG=y
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
sample:
2+
name: Low Voltage Detector (LVD)
3+
tests:
4+
sample.boards.renesas.lvd:
5+
build_only: true
6+
platform_allow:
7+
- rsk_rx130@512kb
8+
tags: lvd

samples/boards/renesas/lvd/src/main.c

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright (c) 2025 Renesas Electronics Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/sys/util.h>
8+
#include <zephyr/drivers/misc/renesas_lvd/renesas_lvd.h>
9+
#include <zephyr/drivers/gpio.h>
10+
#include <zephyr/devicetree.h>
11+
#include <zephyr/kernel.h>
12+
#include <stdio.h>
13+
#include <stdlib.h>
14+
#include <string.h>
15+
#include <stdbool.h>
16+
17+
/* LVD node & config from Device Tree */
18+
#if DT_HAS_COMPAT_STATUS_OKAY(renesas_rx_lvd)
19+
#define LVD_NODE DT_INST(0, renesas_rx_lvd)
20+
#endif
21+
22+
#define LVD_ACTION DT_ENUM_IDX(LVD_NODE, lvd_action)
23+
#define VOLTAGE_THRESHOLD DT_PROP(LVD_NODE, voltage_level)
24+
25+
/* GPIO LEDs */
26+
#define LED_BELOW_NODE DT_ALIAS(led0)
27+
#define LED_ABOVE_NODE DT_ALIAS(led1)
28+
29+
static const struct gpio_dt_spec led_below = GPIO_DT_SPEC_GET(LED_BELOW_NODE, gpios);
30+
static const struct gpio_dt_spec led_above = GPIO_DT_SPEC_GET(LED_ABOVE_NODE, gpios);
31+
32+
/* Semaphore for LVD interrupt */
33+
static struct k_sem lvd_sem;
34+
35+
#if LVD_ACTION == 2
36+
#define LVD_INT 1
37+
#else
38+
#define LVD_INT 0
39+
#endif
40+
41+
#if LVD_INT
42+
void user_callback(const struct device *dev, void *user_data)
43+
{
44+
ARG_UNUSED(user_data);
45+
ARG_UNUSED(dev);
46+
printk("[LVD] Interrupt: Voltage level crossing detected!\n");
47+
printk("[WARNING] Voltage instability detected! Check power supply.\n");
48+
k_sem_give(&lvd_sem);
49+
}
50+
#endif
51+
52+
/* Handle voltage status: get, print, update LEDs */
53+
static void handle_voltage_status(const struct device *lvd_dev, const char *tag)
54+
{
55+
int ret;
56+
renesas_lvd_status_t status;
57+
58+
ret = renesas_lvd_get_status(lvd_dev, &status);
59+
if (ret != 0) {
60+
printk("[%s] Error: Failed to get LVD status.\n", tag);
61+
return;
62+
}
63+
64+
switch (status.position) {
65+
case RENESAS_LVD_POSITION_ABOVE:
66+
printk("[%s] Voltage is ABOVE threshold (%.2f V)\n", tag,
67+
((double)VOLTAGE_THRESHOLD / 100));
68+
gpio_pin_set_dt(&led_above, 1);
69+
gpio_pin_set_dt(&led_below, 0);
70+
break;
71+
case RENESAS_LVD_POSITION_BELOW:
72+
printk("[%s] Voltage is BELOW threshold (%.2f V)\n", tag,
73+
((double)VOLTAGE_THRESHOLD / 100));
74+
gpio_pin_set_dt(&led_below, 1);
75+
gpio_pin_set_dt(&led_above, 0);
76+
break;
77+
default:
78+
printk("[%s] Unknown voltage position\n", tag);
79+
break;
80+
}
81+
82+
ret = renesas_lvd_clear_status(lvd_dev);
83+
if (ret != 0) {
84+
printk("[%s] Warning: Failed to clear LVD status\n", tag);
85+
}
86+
}
87+
88+
int main(void)
89+
{
90+
int ret;
91+
const struct device *const lvd_dev = DEVICE_DT_GET(LVD_NODE);
92+
93+
k_sem_init(&lvd_sem, 0, 1);
94+
95+
if (!device_is_ready(lvd_dev)) {
96+
printk("[LVD] Error: LVD device not ready.\n");
97+
return -EINVAL;
98+
}
99+
100+
#if LVD_INT
101+
ret = renesas_lvd_callback_set(lvd_dev, user_callback, NULL);
102+
if (ret != 0) {
103+
printk("[LVD] Error: Failed to register callback.\n");
104+
return -EINVAL;
105+
}
106+
#endif
107+
108+
if (!gpio_is_ready_dt(&led_below) || !gpio_is_ready_dt(&led_above)) {
109+
printk("[GPIO] Error: LED GPIOs not ready.\n");
110+
return -ENODEV;
111+
}
112+
113+
ret = gpio_pin_configure_dt(&led_below, GPIO_OUTPUT_ACTIVE);
114+
if (ret < 0) {
115+
return ret;
116+
}
117+
118+
ret = gpio_pin_configure_dt(&led_above, GPIO_OUTPUT_ACTIVE);
119+
if (ret < 0) {
120+
return ret;
121+
}
122+
123+
printk("===========================================================\n");
124+
printk("LVD Voltage Monitoring Sample Started\n");
125+
printk("Threshold Voltage Level : %.2f V\n", ((double)VOLTAGE_THRESHOLD / 100));
126+
printk("===========================================================\n");
127+
128+
handle_voltage_status(lvd_dev, "LVD Init");
129+
130+
while (1) {
131+
k_sem_take(&lvd_sem, K_FOREVER);
132+
handle_voltage_status(lvd_dev, "LVD");
133+
}
134+
135+
return 0;
136+
}

0 commit comments

Comments
 (0)