Instructions

Asset Tracker Template

tags
Asset Tracker Template

To add a new zbus event, complete the following procedure:

  1. Create a header for the new channel and message type at app/src/modules/uart_power_control/uart_power_control.h.

    #ifndef UART_POWER_CONTROL_H_
    #define UART_POWER_CONTROL_H_
    
    #include <zephyr/zbus/zbus.h>
    
    enum vbus_msg_type {
        /* VBUS power supply is connected. */
        VBUS_CONNECTED,
    
        /* VBUS power supply is disconnected. */
        VBUS_DISCONNECTED,
    };
    
    struct vbus_msg {
        enum vbus_msg_type type;
    };
    
    ZBUS_CHAN_DECLARE(vbus_chan);
    
    #endif /* UART_POWER_CONTROL_H_ */
    
  2. Define the channel and publish events from the existing event_callback() function in app/src/modules/uart_power_control/uart_power_control.c. Add the include and channel definition near the top of the file:

    #include "uart_power_control.h"
    #include "app_common.h"
    
    ZBUS_CHAN_DEFINE(vbus_chan,
                     struct vbus_msg,
                     NULL,
                     NULL,
                     ZBUS_OBSERVERS_EMPTY,
                     ZBUS_MSG_INIT(0));
    

    Then publish the events from inside event_callback():

    if (pins & BIT(NPM13XX_EVENT_VBUS_DETECTED)) {
        LOG_DBG("VBUS detected");
        vbus_present = true;
    
        struct vbus_msg msg = { .type = VBUS_CONNECTED };
        int pub_err = zbus_chan_pub(&vbus_chan, &msg, PUB_TIMEOUT);
    
        if (pub_err) {
            LOG_ERR("zbus_chan_pub, error: %d", pub_err);
            SEND_FATAL_ERROR();
        }
    
        // ... existing code ...
    }
    
    if (pins & BIT(NPM13XX_EVENT_VBUS_REMOVED)) {
        LOG_DBG("VBUS removed");
        vbus_present = false;
    
        struct vbus_msg msg = { .type = VBUS_DISCONNECTED };
        int pub_err = zbus_chan_pub(&vbus_chan, &msg, PUB_TIMEOUT);
    
        if (pub_err) {
            LOG_ERR("zbus_chan_pub, error: %d", pub_err);
            SEND_FATAL_ERROR();
        }
    
        // ... existing code ...
    }
    
  3. Make sure the channel is observed by the subscriber module. In app/src/main.c, add vbus_chan to the CHANNEL_LIST so it is gated by CONFIG_APP_UART_POWER_CONTROL:

    #include "uart_power_control.h"
    
    #define CHANNEL_LIST(X)                                         \
        X(cloud_chan,       struct cloud_msg)                       \
        X(fota_chan,        struct fota_msg)                        \
        X(network_chan,     struct network_msg)                     \
        X(location_chan,    struct location_msg)                    \
        X(storage_chan,     struct storage_msg)                     \
        X(timer_chan,       struct timer_msg)                       \
        X(priv_main_chan,   struct priv_main_msg)                   \
        IF_ENABLED(CONFIG_APP_BUTTON, (X(button_chan, struct button_msg)))  \
        IF_ENABLED(CONFIG_APP_POWER,  (X(power_chan,  struct power_msg)))   \
        IF_ENABLED(CONFIG_APP_UART_POWER_CONTROL, (X(vbus_chan, struct vbus_msg)))
    

    If you are subscribing from a different module, add the channel to that module's CHANNEL_LIST instead.

  4. Implement a handler for the new events in the subscriber module. For example, add the following block to the running_run() state handler in app/src/main.c:

    if (state_object->chan == &vbus_chan) {
        const struct vbus_msg *msg =
            (const struct vbus_msg *)state_object->msg_buf;
    
        if (msg->type == VBUS_CONNECTED) {
            LOG_DBG("VBUS connected, request white LED blinking rapidly for 10 seconds");
    
            struct led_msg led_msg = {
                .type = LED_RGB_SET,
                .red = 255,
                .green = 255,
                .blue = 255,
                .duration_on_msec = 300,
                .duration_off_msec = 300,
                .repetitions = 10,
            };
    
            int err = zbus_chan_pub(&led_chan, &led_msg, PUB_TIMEOUT);
    
            if (err) {
                LOG_ERR("zbus_chan_pub, error: %d", err);
                SEND_FATAL_ERROR();
            }
    
            return SMF_EVENT_HANDLED;
        } else if (msg->type == VBUS_DISCONNECTED) {
            LOG_DBG("VBUS disconnected, request purple LED blinking slowly for 10 seconds");
    
            struct led_msg led_msg = {
                .type = LED_RGB_SET,
                .red = 255,
                .green = 0,
                .blue = 255,
                .duration_on_msec = 1000,
                .duration_off_msec = 700,
                .repetitions = 10,
            };
    
            int err = zbus_chan_pub(&led_chan, &led_msg, PUB_TIMEOUT);
    
            if (err) {
                LOG_ERR("zbus_chan_pub, error: %d", err);
                SEND_FATAL_ERROR();
            }
    
            return SMF_EVENT_HANDLED;
        }
    }
    
  5. Test the implementation by connecting and disconnecting VBUS to verify the LED patterns change as expected.