From 7a06b97283351d1217c1dac4081d2772d6d15fc2 Mon Sep 17 00:00:00 2001 From: Henrik Brix Andersen Date: Wed, 15 Jan 2025 22:26:55 +0000 Subject: [PATCH] app: led: represent LEDs as LEDs, not GPIOs Switch from representing LEDs as GPIOs to representing LEDs as LEDs: - Rename the state-gpios/activity-gpios devicetree properties to state-led/activity-leds and use phandles to refer to existing LED devicetree nodes. This simplifies the CANnectivity firmware devicetree overlays and avoids having to repeat LED GPIO specifications already present in the board devicetree. - Switch from using the Zephyr GPIO API for controlling LEDs to using the Zephyr LED API. This allows using LEDs controlled by a dedicated LED controller IP/external IC. Suggested-by: Fabio Baltieri Signed-off-by: Henrik Brix Andersen --- README.md | 2 +- app/CMakeLists.txt | 2 +- app/Kconfig | 16 ++-- app/boards/canbardo_same70n20b.overlay | 8 +- app/boards/candlelight_stm32f072xb.overlay | 3 +- app/boards/candlelightfd_stm32g0b1xx.overlay | 3 +- .../candlelightfd_stm32g0b1xx_dual.overlay | 4 +- app/boards/lpcxpresso55s16_lpc55s16.overlay | 4 +- .../mks_canable_v20_stm32g431xx.overlay | 4 +- app/boards/native_sim.overlay | 46 +++++++-- app/boards/nucleo_h723zg_stm32h723xx.overlay | 4 +- app/boards/ucan_stm32f072xb.overlay | 3 +- app/boards/usb2canfdv1_stm32g0b1xx.overlay | 5 +- app/dts/bindings/cannectivity.yaml | 26 +++-- app/src/dfu.c | 21 ++-- app/src/led.c | 96 ++++++++++--------- app/src/main.c | 4 +- doc/index.rst | 2 +- 18 files changed, 143 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 47e0fa0..a79f495 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The CANnectivity firmware supports the following features, some of which depend - CAN FD (flexible data rate) - Fast-speed and Hi-speed USB - Multiple, independent CAN channels -- GPIO-controlled LEDs: +- LEDs: - CAN channel state LEDs - CAN channel activity LEDs - Visual CAN channel identification diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 9ddf7a4..5c45976 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -20,7 +20,7 @@ target_sources(app PRIVATE src/usb.c ) -target_sources_ifdef(CONFIG_CANNECTIVITY_LED_GPIO app PRIVATE +target_sources_ifdef(CONFIG_CANNECTIVITY_LED app PRIVATE src/led.c ) diff --git a/app/Kconfig b/app/Kconfig index 75953b5..450993b 100644 --- a/app/Kconfig +++ b/app/Kconfig @@ -65,13 +65,13 @@ configdefault USB_MAX_POWER endif # USB_DEVICE_STACK -config CANNECTIVITY_LED_GPIO +config CANNECTIVITY_LED bool "LED support" default y - depends on $(dt_compat_any_has_prop,cannectivity-channel,state-gpios) || \ - $(dt_compat_any_has_prop,cannectivity-channel,activity-gpios) || \ + depends on $(dt_compat_any_has_prop,cannectivity-channel,state-led) || \ + $(dt_compat_any_has_prop,cannectivity-channel,activity-leds) || \ ($(dt_alias_enabled,led0) && !$(dt_compat_enabled,cannectivity-channel)) - select GPIO + select LED select SMF select SMF_ANCESTOR_SUPPORT select SMF_INITIAL_TRANSITION @@ -79,9 +79,9 @@ config CANNECTIVITY_LED_GPIO select USB_DEVICE_GS_USB_IDENTIFICATION if USB_DEVICE_GS_USB select USBD_GS_USB_IDENTIFICATION if USBD_GS_USB help - Enable support for GPIO-controlled CAN channel status/activity LEDs. + Enable support for CAN channel status/activity LEDs. -if CANNECTIVITY_LED_GPIO +if CANNECTIVITY_LED config CANNECTIVITY_LED_EVENT_MSGQ_SIZE int "LED event message queue size" @@ -101,7 +101,7 @@ config CANNECTIVITY_LED_THREAD_PRIO help Priority level for the LED finite-state machine thread. -endif # CANNECTIVITY_LED_GPIO +endif # CANNECTIVITY_LED config CANNECTIVITY_TIMESTAMP_COUNTER bool "Hardware timestamp support" @@ -137,6 +137,7 @@ config CANNECTIVITY_DFU_BUTTON bool "DFU button support" default y depends on $(dt_alias_enabled,mcuboot-button0) + select GPIO select REBOOT help Enable support for rebooting into Device Firmware Upgrade (DFU) mode by holding the DFU @@ -155,6 +156,7 @@ config CANNECTIVITY_DFU_LED bool # hidden default y depends on $(dt_alias_enabled,mcuboot-led0) + select LED help Enable support for controlling the Device Firmware Upgrade (DFU) LED (identified by the "mcuboot-led0" devicetree alias). diff --git a/app/boards/canbardo_same70n20b.overlay b/app/boards/canbardo_same70n20b.overlay index 1e03bb4..1d92e84 100644 --- a/app/boards/canbardo_same70n20b.overlay +++ b/app/boards/canbardo_same70n20b.overlay @@ -14,16 +14,16 @@ compatible = "cannectivity-channel"; can-controller = <&can0>; termination-gpios = <&piod 1 GPIO_ACTIVE_HIGH>; - state-gpios = <&piod 22 GPIO_ACTIVE_LOW>; - activity-gpios = <&piod 24 GPIO_ACTIVE_LOW>; + state-led = <&can_0_ledg>; + activity-leds = <&can_0_ledy>; }; channel1 { compatible = "cannectivity-channel"; can-controller = <&can1>; termination-gpios = <&piod 13 GPIO_ACTIVE_HIGH>; - state-gpios = <&piod 17 GPIO_ACTIVE_LOW>; - activity-gpios = <&piod 18 GPIO_ACTIVE_LOW>; + state-led = <&can_1_ledg>; + activity-leds = <&can_1_ledy>; }; }; }; diff --git a/app/boards/candlelight_stm32f072xb.overlay b/app/boards/candlelight_stm32f072xb.overlay index 3cf081a..25fd13a 100644 --- a/app/boards/candlelight_stm32f072xb.overlay +++ b/app/boards/candlelight_stm32f072xb.overlay @@ -14,8 +14,7 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&can1>; - activity-gpios = <&gpioa 0 GPIO_ACTIVE_LOW>, - <&gpioa 1 GPIO_ACTIVE_LOW>; + activity-leds = <&led_rx &led_tx>; }; }; }; diff --git a/app/boards/candlelightfd_stm32g0b1xx.overlay b/app/boards/candlelightfd_stm32g0b1xx.overlay index a672f07..3dedc97 100644 --- a/app/boards/candlelightfd_stm32g0b1xx.overlay +++ b/app/boards/candlelightfd_stm32g0b1xx.overlay @@ -14,8 +14,7 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&fdcan1>; - activity-gpios = <&gpioa 3 GPIO_ACTIVE_LOW>, - <&gpioa 4 GPIO_ACTIVE_LOW>; + activity-leds = <&led_rx &led_tx>; }; }; }; diff --git a/app/boards/candlelightfd_stm32g0b1xx_dual.overlay b/app/boards/candlelightfd_stm32g0b1xx_dual.overlay index 4e05872..3459f33 100644 --- a/app/boards/candlelightfd_stm32g0b1xx_dual.overlay +++ b/app/boards/candlelightfd_stm32g0b1xx_dual.overlay @@ -15,14 +15,14 @@ compatible = "cannectivity-channel"; can-controller = <&fdcan1>; /* Use RX LED for channel 0 state + activity */ - state-gpios = <&gpioa 3 GPIO_ACTIVE_LOW>; + state-led = <&led_rx>; }; channel1 { compatible = "cannectivity-channel"; can-controller = <&fdcan2>; /* Use TX LED for channel 0 state + activity */ - state-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>; + state-led = <&led_tx>; }; }; }; diff --git a/app/boards/lpcxpresso55s16_lpc55s16.overlay b/app/boards/lpcxpresso55s16_lpc55s16.overlay index aa16066..896a7db 100644 --- a/app/boards/lpcxpresso55s16_lpc55s16.overlay +++ b/app/boards/lpcxpresso55s16_lpc55s16.overlay @@ -15,8 +15,8 @@ compatible = "cannectivity-channel"; can-controller = <&can0>; termination-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; /* Red LED for testing */ - state-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; + state-led = <&blue_led>; + activity-leds = <&green_led>; }; }; }; diff --git a/app/boards/mks_canable_v20_stm32g431xx.overlay b/app/boards/mks_canable_v20_stm32g431xx.overlay index 496df21..cca3e87 100644 --- a/app/boards/mks_canable_v20_stm32g431xx.overlay +++ b/app/boards/mks_canable_v20_stm32g431xx.overlay @@ -14,8 +14,8 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&fdcan1>; - state-gpios = <&gpioa 15 GPIO_ACTIVE_LOW>; /* blue led */ - activity-gpios = <&gpioa 0 GPIO_ACTIVE_LOW>; /* green led */ + state-led = <&blue_led>; + activity-leds = <&green_led>; }; }; }; diff --git a/app/boards/native_sim.overlay b/app/boards/native_sim.overlay index 35606ac..4b13835 100644 --- a/app/boards/native_sim.overlay +++ b/app/boards/native_sim.overlay @@ -7,6 +7,40 @@ #include / { + leds { + compatible = "gpio-leds"; + + led_ch0_state: led_ch0_state { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "Channel 0 state LED"; + }; + + led_ch0_activity: led_ch0_activity { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "Channel 0 activity LED"; + }; + + led_ch1_state: led_ch1_state { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + label = "Channel 1 state LED"; + }; + + led_ch1_activity: led_ch1_activity { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + label = "Channel 1 activity LED"; + }; + + led_ch2_state: led_ch2_state { + gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; + label = "Channel 2 state LED"; + }; + + led_ch2_activity: led_ch2_activity { + gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + label = "Channel 2 activity LED"; + }; + }; + cannectivity: cannectivity { compatible = "cannectivity"; timestamp-counter = <&counter0>; @@ -15,24 +49,24 @@ compatible = "cannectivity-channel"; can-controller = <&can_loopback0>; termination-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; - state-gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + state-led = <&led_ch0_state>; + activity-leds = <&led_ch0_activity>; }; channel1 { compatible = "cannectivity-channel"; can-controller = <&can_loopback1>; termination-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; - state-gpios = <&gpio0 4 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>; + state-led = <&led_ch1_state>; + activity-leds = <&led_ch1_activity>; }; channel2 { compatible = "cannectivity-channel"; can-controller = <&can_loopback2>; termination-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; - state-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + state-led = <&led_ch2_state>; + activity-leds = <&led_ch2_activity>; }; }; diff --git a/app/boards/nucleo_h723zg_stm32h723xx.overlay b/app/boards/nucleo_h723zg_stm32h723xx.overlay index 74baa22..d90b482 100644 --- a/app/boards/nucleo_h723zg_stm32h723xx.overlay +++ b/app/boards/nucleo_h723zg_stm32h723xx.overlay @@ -14,8 +14,8 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&fdcan1>; - state-gpios = <&gpiob 0 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpioe 1 GPIO_ACTIVE_HIGH>; + state-led = <&green_led>; + activity-leds = <&yellow_led>; }; }; }; diff --git a/app/boards/ucan_stm32f072xb.overlay b/app/boards/ucan_stm32f072xb.overlay index bed06db..25fd13a 100644 --- a/app/boards/ucan_stm32f072xb.overlay +++ b/app/boards/ucan_stm32f072xb.overlay @@ -14,8 +14,7 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&can1>; - activity-gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>, - <&gpioa 1 GPIO_ACTIVE_HIGH>; + activity-leds = <&led_rx &led_tx>; }; }; }; diff --git a/app/boards/usb2canfdv1_stm32g0b1xx.overlay b/app/boards/usb2canfdv1_stm32g0b1xx.overlay index 802027f..12f7534 100644 --- a/app/boards/usb2canfdv1_stm32g0b1xx.overlay +++ b/app/boards/usb2canfdv1_stm32g0b1xx.overlay @@ -14,9 +14,8 @@ channel0 { compatible = "cannectivity-channel"; can-controller = <&fdcan1>; - state-gpios = <&gpioa 2 GPIO_ACTIVE_LOW>; - activity-gpios = <&gpioa 0 GPIO_ACTIVE_LOW>, - <&gpioa 1 GPIO_ACTIVE_LOW>; + state-led = <&led_ready>; + activity-leds = <&led_rxd &led_txd>; }; }; }; diff --git a/app/dts/bindings/cannectivity.yaml b/app/dts/bindings/cannectivity.yaml index 29d3d38..2259df4 100644 --- a/app/dts/bindings/cannectivity.yaml +++ b/app/dts/bindings/cannectivity.yaml @@ -13,16 +13,16 @@ description: | compatible = "cannectivity-channel"; can-controller = <&can0>; termination-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; - state-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; + state-led = <&ch0_state_led>; + activity-leds = <&ch0_activity_led>; }; channel { compatible = "cannectivity-channel"; can-controller = <&can1>; termination-gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>; - state-gpios = <&gpio0 10 GPIO_ACTIVE_HIGH>; - activity-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>; + state-led = <&ch1_state_led>; + activity-leds = <&ch1_activity_led>; }; }; @@ -59,17 +59,15 @@ child-binding: active when the CAN termination is enabled and inactive when the CAN termination is disabled. - state-gpios: - type: phandle-array + state-led: + type: phandle description: | - GPIO to use to control the CAN channel state LED. This GPIO is driven active when - the LED is to be turned on and inactive when the LED is to be turned off. + Phandle for the CAN channel state LED. - activity-gpios: - type: phandle-array + activity-leds: + type: phandles description: | - GPIO to use to control the CAN channel activity LED. This GPIO is driven active when the LED - is to be turned on and inactive when the LED is to be turned off. + Phandle(s) for the CAN channel activity LED(s). - If two GPIOs are specified, the GPIO at index 0 will be used for indicating RX activity, and - the GPIO at index 1 will be used for indicating TX activity. + If two LED phandles are specified, the LED phandle at index 0 will be used for indicating RX + activity, and the LED phandle at index 1 will be used for indicating TX activity. diff --git a/app/src/dfu.c b/app/src/dfu.c index 9541f42..55cf498 100644 --- a/app/src/dfu.c +++ b/app/src/dfu.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,7 @@ LOG_MODULE_REGISTER(dfu, CONFIG_CANNECTIVITY_LOG_LEVEL); #define DFU_BUTTON_NODE DT_ALIAS(mcuboot_button0) #ifdef CONFIG_CANNECTIVITY_DFU_LED -struct gpio_dt_spec dfu_led = GPIO_DT_SPEC_GET(DFU_LED_NODE, gpios); +struct led_dt_spec dfu_led = LED_DT_SPEC_GET(DFU_LED_NODE); #endif /* CONFIG_CANNECTIVITY_DFU_LED */ #ifdef CONFIG_CANNECTIVITY_DFU_BUTTON @@ -47,7 +48,11 @@ static void dfu_button_poll(struct k_work *work) if (err > 0) { #ifdef CONFIG_CANNECTIVITY_DFU_LED - err = gpio_pin_toggle_dt(&dfu_led); + if (k_sem_count_get(&dfu_button_sem) % 2U == 0U) { + err = led_on_dt(&dfu_led); + } else { + err = led_off_dt(&dfu_led); + } if (err != 0) { LOG_ERR("failed to toggle DFU LED (err %d)", err); goto done; @@ -66,7 +71,7 @@ static void dfu_button_poll(struct k_work *work) done: #ifdef CONFIG_CANNECTIVITY_DFU_LED - err = gpio_pin_set_dt(&dfu_led, 0); + err = led_off_dt(&dfu_led); if (err != 0) { LOG_ERR("failed to turn off DFU LED (err %d)", err); return; @@ -128,19 +133,11 @@ static int dfu_button_init(void) #ifdef CONFIG_CANNECTIVITY_DFU_LED static int dfu_led_init(void) { - int err; - - if (!gpio_is_ready_dt(&dfu_led)) { + if (!led_is_ready_dt(&dfu_led)) { LOG_ERR("DFU LED device not ready"); return -ENODEV; } - err = gpio_pin_configure_dt(&dfu_led, GPIO_OUTPUT_INACTIVE); - if (err != 0) { - LOG_ERR("failed to turn off DFU LED (err %d)", err); - return err; - } - return 0; } #endif /* CONFIG_CANNECTIVITY_DFU_LED */ diff --git a/app/src/led.c b/app/src/led.c index c721ef1..ea7fa6e 100644 --- a/app/src/led.c +++ b/app/src/led.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include @@ -18,7 +18,7 @@ LOG_MODULE_REGISTER(led, CONFIG_CANNECTIVITY_LOG_LEVEL); /* LED ticks */ #define LED_TICK_MS 50U #define LED_TICKS_ACTIVITY 2U -#define LED_TICKS_IDENTIFY 10U +#define LED_TICKS_IDENTIFY 20U /* LED finite-state machine states */ enum led_state { @@ -57,42 +57,44 @@ struct led_ctx { led_event_t event; uint16_t ch; bool started; - struct gpio_dt_spec state_led; + struct led_dt_spec state_led; int identify_ticks; k_timepoint_t activity[LED_ACTIVITY_COUNT]; int ticks[LED_ACTIVITY_COUNT]; - struct gpio_dt_spec activity_led[LED_ACTIVITY_COUNT]; + struct led_dt_spec activity_led[LED_ACTIVITY_COUNT]; }; /* Devicetree accessor macros */ -#define CHANNEL_LED_GPIO_DT_SPEC_GET(node_id) \ +#define CHANNEL_LED_DT_SPEC_GET(node_id) \ { \ - .state_led = GPIO_DT_SPEC_GET_OR(node_id, state_gpios, {0}), \ - .activity_led[0] = GPIO_DT_SPEC_GET_BY_IDX_OR(node_id, activity_gpios, 0, {0}), \ - .activity_led[1] = GPIO_DT_SPEC_GET_BY_IDX_OR(node_id, activity_gpios, 1, {0}), \ + .state_led = LED_DT_SPEC_GET_OR(DT_PHANDLE(node_id, state_led), {0}), \ + .activity_led[0] = LED_DT_SPEC_GET_OR(DT_PHANDLE_BY_IDX(node_id, activity_leds, 0),\ + {0}), \ + .activity_led[1] = LED_DT_SPEC_GET_OR(DT_PHANDLE_BY_IDX(node_id, activity_leds, 1),\ + {0}), \ } -#define CHANNEL_LED0_GPIO_DT_SPEC_GET() \ +#define CHANNEL_LED0_DT_SPEC_GET() \ { \ - .state_led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios), \ + .state_led = LED_DT_SPEC_GET(DT_ALIAS(led0)), \ } /* Array of LED finite-state machine channel contexts */ struct led_ctx led_channel_ctx[] = { #if CANNECTIVITY_DT_HAS_CHANNEL - CANNECTIVITY_DT_FOREACH_CHANNEL_SEP(CHANNEL_LED_GPIO_DT_SPEC_GET, (,)) + CANNECTIVITY_DT_FOREACH_CHANNEL_SEP(CHANNEL_LED_DT_SPEC_GET, (,)) #else /* CANNECTIVITY_DT_HAS_CHANNEL */ - CHANNEL_LED0_GPIO_DT_SPEC_GET() + CHANNEL_LED0_DT_SPEC_GET() #endif /* !CANNECTIVITY_DT_HAS_CHANNEL */ }; /* Helper macros */ #define LED_CTX_HAS_STATE_LED(_led_ctx) \ - (_led_ctx->state_led.port != NULL) + (_led_ctx->state_led.dev != NULL) #define LED_CTX_HAS_ACTIVITY_LED(_led_ctx) \ - (_led_ctx->activity_led[LED_ACTIVITY_RX].port != NULL) + (_led_ctx->activity_led[LED_ACTIVITY_RX].dev != NULL) #define LED_CTX_HAS_DUAL_ACTIVITY_LEDS(_led_ctx) \ - (_led_ctx->activity_led[LED_ACTIVITY_TX].port != NULL) + (_led_ctx->activity_led[LED_ACTIVITY_TX].dev != NULL) /* Forward declarations */ static const struct smf_state led_states[]; @@ -130,7 +132,11 @@ static void led_indicate_state(struct led_ctx *lctx, bool state) int err; if (LED_CTX_HAS_STATE_LED(lctx)) { - err = gpio_pin_set_dt(&lctx->state_led, state); + if (state) { + err = led_on_dt(&lctx->state_led); + } else { + err = led_off_dt(&lctx->state_led); + } if (err != 0) { LOG_ERR("failed to turn %s channel %u state LED (err %d)", state ? "on" : "off", lctx->ch, err); @@ -140,7 +146,7 @@ static void led_indicate_state(struct led_ctx *lctx, bool state) static void led_indicate_activity(struct led_ctx *lctx, enum led_activity type, bool activity) { - struct gpio_dt_spec *led = NULL; + struct led_dt_spec *led = NULL; int value = activity; int err; @@ -171,7 +177,11 @@ static void led_indicate_activity(struct led_ctx *lctx, enum led_activity type, } if (led != NULL) { - err = gpio_pin_set_dt(led, value); + if (value) { + err = led_on_dt(led); + } else { + err = led_off_dt(led); + } if (err != 0) { LOG_ERR("failed to turn %s channel %u activity LED (err %d)", value ? "on" : "off", lctx->ch, err); @@ -283,22 +293,34 @@ static void led_state_identify_entry(void *obj) static void led_state_identify_run(void *obj) { struct led_ctx *lctx = obj; - struct gpio_dt_spec *leds[3]; + struct led_dt_spec *leds[3]; int err; int i; switch (lctx->event) { case LED_EVENT_TICK: - if (--lctx->identify_ticks == 0U) { - leds[0] = &lctx->state_led; - leds[1] = &lctx->activity_led[LED_ACTIVITY_RX]; - leds[2] = &lctx->activity_led[LED_ACTIVITY_TX]; + leds[0] = &lctx->state_led; + leds[1] = &lctx->activity_led[LED_ACTIVITY_RX]; + leds[2] = &lctx->activity_led[LED_ACTIVITY_TX]; + lctx->identify_ticks--; + + if (lctx->identify_ticks == LED_TICKS_IDENTIFY / 2U) { + for (i = 0; i < ARRAY_SIZE(leds); i++) { + if (leds[i]->dev != NULL) { + err = led_off_dt(leds[i]); + if (err != 0) { + LOG_ERR("failed to turn channel %u LED %d off" + "(err %d)", lctx->ch, i, err); + } + } + } + } else if (lctx->identify_ticks == 0U) { for (i = 0; i < ARRAY_SIZE(leds); i++) { - if (leds[i]->port != NULL) { - err = gpio_pin_toggle_dt(leds[i]); + if (leds[i]->dev != NULL) { + err = led_on_dt(leds[i]); if (err != 0) { - LOG_ERR("failed to toggle channel %u LED %d " + LOG_ERR("failed to turn channel %u LED %d on " "(err %d)", lctx->ch, i, err); } } @@ -480,7 +502,6 @@ int cannectivity_led_init(void) { struct led_ctx *lctx; uint16_t ch; - int err; int i; for (ch = 0; ch < ARRAY_SIZE(led_channel_ctx); ch++) { @@ -492,33 +513,18 @@ int cannectivity_led_init(void) } if (LED_CTX_HAS_STATE_LED(lctx)) { - if (!gpio_is_ready_dt(&lctx->state_led)) { + if (!led_is_ready_dt(&lctx->state_led)) { LOG_ERR("state LED for channel %u not ready", ch); return -ENODEV; } - - err = gpio_pin_configure_dt(&lctx->state_led, GPIO_OUTPUT_INACTIVE); - if (err != 0) { - LOG_ERR("failed to configure channel %d state LED GPIO (err %d)", - ch, err); - return err; - } } for (i = 0; i < ARRAY_SIZE(lctx->activity_led); i++) { - if (lctx->activity_led[i].port != NULL) { - if (!gpio_is_ready_dt(&lctx->activity_led[i])) { + if (lctx->activity_led[i].dev != NULL) { + if (!led_is_ready_dt(&lctx->activity_led[i])) { LOG_ERR("activity LED %d for channel %u not ready", i, ch); return -ENODEV; } - - err = gpio_pin_configure_dt(&lctx->activity_led[i], - GPIO_OUTPUT_INACTIVE); - if (err != 0) { - LOG_ERR("failed to configure channel %d activity LED %d " - "GPIO (err %d)", ch, i, err); - return err; - } } } diff --git a/app/src/main.c b/app/src/main.c index 9bf8073..1d9b22a 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -30,7 +30,7 @@ static const struct gs_usb_ops gs_usb_ops = { #ifdef CONFIG_CANNECTIVITY_TIMESTAMP_COUNTER .timestamp = cannectivity_timestamp_get, #endif -#ifdef CONFIG_CANNECTIVITY_LED_GPIO +#ifdef CONFIG_CANNECTIVITY_LED .event = cannectivity_led_event, #endif #ifdef CONFIG_CANNECTIVITY_TERMINATION_GPIO @@ -60,7 +60,7 @@ int main(void) return 0; } - if (IS_ENABLED(CONFIG_CANNECTIVITY_LED_GPIO)) { + if (IS_ENABLED(CONFIG_CANNECTIVITY_LED)) { err = cannectivity_led_init(); if (err != 0) { return 0; diff --git a/doc/index.rst b/doc/index.rst index 3b15380..161805e 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -39,7 +39,7 @@ The CANnectivity firmware supports the following features, some of which depend * CAN FD (flexible data rate) * Fast-speed and Hi-speed USB * Multiple, independent CAN channels -* GPIO-controlled LEDs: +* LEDs: * CAN channel state LEDs * CAN channel activity LEDs