Skip to content

Commit 3ac971b

Browse files
gmarullcarlescufi
authored andcommitted
drivers: blink: blink-gpio-led: add initial implementation
Add a blink driver implementation for a GPIO-controlled LED. Signed-off-by: Gerard Marull-Paretas <[email protected]>
1 parent 1bc1eb1 commit 3ac971b

File tree

5 files changed

+143
-0
lines changed

5 files changed

+143
-0
lines changed

drivers/blink/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
zephyr_library()
5+
zephyr_library_sources_ifdef(CONFIG_BLINK_GPIO_LED gpio_led.c)

drivers/blink/Kconfig

+2
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ module = BLINK
1818
module-str = blink
1919
source "subsys/logging/Kconfig.template.log_config"
2020

21+
rsource "Kconfig.gpio_led"
22+
2123
endif # BLINK

drivers/blink/Kconfig.gpio_led

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config BLINK_GPIO_LED
5+
bool "GPIO-controlled LED blink driver"
6+
default y
7+
depends on DT_HAS_BLINK_GPIO_LED_ENABLED
8+
select GPIO
9+
help
10+
Enable this option to use the GPIO-controlled LED blink driver. This
11+
demonstrates how to implement a driver for a custom driver class.

drivers/blink/gpio_led.c

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#define DT_DRV_COMPAT blink_gpio_led
7+
8+
#include <zephyr/device.h>
9+
10+
#include <zephyr/devicetree.h>
11+
#include <zephyr/drivers/gpio.h>
12+
#include <zephyr/kernel.h>
13+
#include <zephyr/logging/log.h>
14+
15+
#include <app/drivers/blink.h>
16+
17+
LOG_MODULE_REGISTER(blink_gpio_led, CONFIG_BLINK_LOG_LEVEL);
18+
19+
struct blink_gpio_led_data {
20+
struct k_timer timer;
21+
};
22+
23+
struct blink_gpio_led_config {
24+
struct gpio_dt_spec led;
25+
unsigned int period_ms;
26+
};
27+
28+
static void blink_gpio_led_on_timer_expire(struct k_timer *timer)
29+
{
30+
const struct device *dev = k_timer_user_data_get(timer);
31+
const struct blink_gpio_led_config *config = dev->config;
32+
int ret;
33+
34+
ret = gpio_pin_toggle_dt(&config->led);
35+
if (ret < 0) {
36+
LOG_ERR("Could not toggle LED GPIO (%d)", ret);
37+
}
38+
}
39+
40+
static int blink_gpio_led_set_period_ms(const struct device *dev,
41+
unsigned int period_ms)
42+
{
43+
const struct blink_gpio_led_config *config = dev->config;
44+
struct blink_gpio_led_data *data = dev->data;
45+
46+
if (period_ms == 0) {
47+
k_timer_stop(&data->timer);
48+
return gpio_pin_set_dt(&config->led, 0);
49+
}
50+
51+
k_timer_start(&data->timer, K_MSEC(period_ms), K_MSEC(period_ms));
52+
53+
return 0;
54+
}
55+
56+
static const struct blink_driver_api blink_gpio_led_api = {
57+
.set_period_ms = &blink_gpio_led_set_period_ms,
58+
};
59+
60+
static int blink_gpio_led_init(const struct device *dev)
61+
{
62+
const struct blink_gpio_led_config *config = dev->config;
63+
struct blink_gpio_led_data *data = dev->data;
64+
int ret;
65+
66+
if (!gpio_is_ready_dt(&config->led)) {
67+
LOG_ERR("LED GPIO not ready");
68+
return -ENODEV;
69+
}
70+
71+
ret = gpio_pin_configure_dt(&config->led, GPIO_OUTPUT_INACTIVE);
72+
if (ret < 0) {
73+
LOG_ERR("Could not configure LED GPIO (%d)", ret);
74+
return ret;
75+
}
76+
77+
k_timer_init(&data->timer, blink_gpio_led_on_timer_expire, NULL);
78+
k_timer_user_data_set(&data->timer, (void *)dev);
79+
80+
if (config->period_ms > 0) {
81+
k_timer_start(&data->timer, K_MSEC(config->period_ms),
82+
K_MSEC(config->period_ms));
83+
}
84+
85+
return 0;
86+
}
87+
88+
#define BLINK_GPIO_LED_DEFINE(inst) \
89+
static struct blink_gpio_led_data data##inst; \
90+
\
91+
static const struct blink_gpio_led_config config##inst = { \
92+
.led = GPIO_DT_SPEC_INST_GET(inst, led_gpios), \
93+
.period_ms = DT_INST_PROP_OR(inst, blink_period_ms, 0U), \
94+
}; \
95+
\
96+
DEVICE_DT_INST_DEFINE(inst, blink_gpio_led_init, NULL, &data##inst, \
97+
&config##inst, POST_KERNEL, \
98+
CONFIG_BLINK_INIT_PRIORITY, \
99+
&blink_gpio_led_api);
100+
101+
DT_INST_FOREACH_STATUS_OKAY(BLINK_GPIO_LED_DEFINE)
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: |
5+
A generic binding for a GPIO-controlled blinking LED. Note that this binding
6+
has no vendor prefix, as it does not target a specific device or vendor.
7+
8+
Example definition in devicetree:
9+
10+
blink-gpio-led {
11+
compatible = "blink-gpio-led";
12+
led-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
13+
blink-period-ms = <1000>;
14+
};
15+
16+
compatible: "blink-gpio-led"
17+
18+
include: base.yaml
19+
20+
properties:
21+
led-gpios:
22+
type: phandle-array
23+
required: true
24+
description: GPIO-controlled LED.
25+
26+
blink-period-ms:
27+
type: int
28+
description: Initial blinking period in milliseconds.

0 commit comments

Comments
 (0)