samples: button: devicetree cleanups

Use a gpio_dt_spec, dropping device_get_binding. This in turn lets us
write everything in a single main() without sacrificing readability
since the LED is optional.

Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
This commit is contained in:
Martí Bolívar 2021-04-26 13:57:47 -07:00 committed by Carles Cufí
commit fff2644189

View file

@ -15,32 +15,23 @@
#define SLEEP_TIME_MS 1
/*
* Get button configuration from the devicetree sw0 alias.
*
* At least a GPIO device and pin number must be provided. The 'flags'
* cell is optional.
* Get button configuration from the devicetree sw0 alias. This is mandatory.
*/
#define SW0_NODE DT_ALIAS(sw0)
#if DT_NODE_HAS_STATUS(SW0_NODE, okay)
#define SW0_GPIO_LABEL DT_GPIO_LABEL(SW0_NODE, gpios)
#define SW0_GPIO_PIN DT_GPIO_PIN(SW0_NODE, gpios)
#define SW0_GPIO_FLAGS (GPIO_INPUT | DT_GPIO_FLAGS(SW0_NODE, gpios))
#else
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
#error "Unsupported board: sw0 devicetree alias is not defined"
#define SW0_GPIO_LABEL ""
#define SW0_GPIO_PIN 0
#define SW0_GPIO_FLAGS 0
#endif
/* LED helpers, which use the led0 devicetree alias if it's available. */
static const struct device *initialize_led(void);
static void match_led_to_button(const struct device *button,
const struct device *led);
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios,
{0});
static struct gpio_callback button_cb_data;
/*
* The led0 devicetree alias is optional. If present, we'll use it
* to turn on the LED whenever the button is pressed.
*/
static struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(DT_ALIAS(led0), gpios,
{0});
void button_pressed(const struct device *dev, struct gpio_callback *cb,
uint32_t pins)
{
@ -49,101 +40,59 @@ void button_pressed(const struct device *dev, struct gpio_callback *cb,
void main(void)
{
const struct device *button;
const struct device *led;
int ret;
button = device_get_binding(SW0_GPIO_LABEL);
if (button == NULL) {
printk("Error: didn't find %s device\n", SW0_GPIO_LABEL);
if (!device_is_ready(button.port)) {
printk("Error: button device %s is not ready\n",
button.port->name);
return;
}
ret = gpio_pin_configure(button, SW0_GPIO_PIN, SW0_GPIO_FLAGS);
ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
if (ret != 0) {
printk("Error %d: failed to configure %s pin %d\n",
ret, SW0_GPIO_LABEL, SW0_GPIO_PIN);
ret, button.port->name, button.pin);
return;
}
ret = gpio_pin_interrupt_configure(button,
SW0_GPIO_PIN,
ret = gpio_pin_interrupt_configure_dt(&button,
GPIO_INT_EDGE_TO_ACTIVE);
if (ret != 0) {
printk("Error %d: failed to configure interrupt on %s pin %d\n",
ret, SW0_GPIO_LABEL, SW0_GPIO_PIN);
ret, button.port->name, button.pin);
return;
}
gpio_init_callback(&button_cb_data, button_pressed, BIT(SW0_GPIO_PIN));
gpio_add_callback(button, &button_cb_data);
printk("Set up button at %s pin %d\n", SW0_GPIO_LABEL, SW0_GPIO_PIN);
gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb_data);
printk("Set up button at %s pin %d\n", button.port->name, button.pin);
led = initialize_led();
if (led.port && !device_is_ready(led.port)) {
printk("Error %d: LED device %s is not ready; ignoring it\n",
ret, led.port->name);
led.port = NULL;
}
if (led.port) {
ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT);
if (ret != 0) {
printk("Error %d: failed to configure LED device %s pin %d\n",
ret, led.port->name, led.pin);
led.port = NULL;
} else {
printk("Set up LED at %s pin %d\n", led.port->name, led.pin);
}
}
printk("Press the button\n");
if (led.port) {
while (1) {
match_led_to_button(button, led);
/* If we have an LED, match its state to the button's. */
int val = gpio_pin_get(button.port, button.pin);
if (val >= 0) {
gpio_pin_set(led.port, led.pin, val);
}
k_msleep(SLEEP_TIME_MS);
}
}
/*
* The led0 devicetree alias is optional. If present, we'll use it
* to turn on the LED whenever the button is pressed.
*/
#define LED0_NODE DT_ALIAS(led0)
#if DT_NODE_HAS_STATUS(LED0_NODE, okay) && DT_NODE_HAS_PROP(LED0_NODE, gpios)
#define LED0_GPIO_LABEL DT_GPIO_LABEL(LED0_NODE, gpios)
#define LED0_GPIO_PIN DT_GPIO_PIN(LED0_NODE, gpios)
#define LED0_GPIO_FLAGS (GPIO_OUTPUT | DT_GPIO_FLAGS(LED0_NODE, gpios))
#endif
#ifdef LED0_GPIO_LABEL
static const struct device *initialize_led(void)
{
const struct device *led;
int ret;
led = device_get_binding(LED0_GPIO_LABEL);
if (led == NULL) {
printk("Didn't find LED device %s\n", LED0_GPIO_LABEL);
return NULL;
}
ret = gpio_pin_configure(led, LED0_GPIO_PIN, LED0_GPIO_FLAGS);
if (ret != 0) {
printk("Error %d: failed to configure LED device %s pin %d\n",
ret, LED0_GPIO_LABEL, LED0_GPIO_PIN);
return NULL;
}
printk("Set up LED at %s pin %d\n", LED0_GPIO_LABEL, LED0_GPIO_PIN);
return led;
}
static void match_led_to_button(const struct device *button,
const struct device *led)
{
bool val;
val = gpio_pin_get(button, SW0_GPIO_PIN);
gpio_pin_set(led, LED0_GPIO_PIN, val);
}
#else /* !defined(LED0_GPIO_LABEL) */
static const struct device *initialize_led(void)
{
printk("No LED device was defined\n");
return NULL;
}
static void match_led_to_button(const struct device *button,
const struct device *led)
{
return;
}
#endif /* LED0_GPIO_LABEL */