Dynamically setting the LPCOMP REFSEL

Hello,

Is there a way to change the LPCOMP reference level in Zephyr other than what is set in the devicetree overlay?

I'm happy to disable it, change it and re-enable it if that's what's needed I just can't see how that can be done through Zephyr.

Example code I currently have is basic, in premise the change I'd like is to go from reference VDD_4_8 to VDD_3_8 when the first reference is passed/a callback is triggered.

Here's the basic code I already have, thank you -

#include <zephyr/drivers/comparator.h>

#include <zephyr/drivers/gpio.h>

#include <zephyr/kernel.h>

#include <zephyr/pm/device_runtime.h>

static const struct device *test_dev = DEVICE_DT_GET(DT_ALIAS(test_comp));

static const struct gpio_dt_spec test_pin = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), test_gpios);

volatile int counter;

static void test_callback(const struct device *dev, void *user_data)

{

    counter++;

    printk("Comparator triggered, counter=%d\n", counter);

}

void main(void)

{

    int rc;



    pm_device_runtime_enable(test_dev);

    pm_device_runtime_get(test_dev);

    rc = comparator_set_trigger_callback(test_dev, test_callback, NULL);

    __ASSERT_NO_MSG(rc == 0);

    rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_FALLING_EDGE);

    __ASSERT_NO_MSG(rc == 0);

    counter = 0;

    while (1) {

        __WFE();  // Wait for event (comparator interrupt)

    }

}

Parents
  • Hi Rhys,

    Zephyr driver is not made for dynamically change the  REFSEL. You may need to use what Jorg suggested. 
    I found a sample here LPCOMP in NCS-Zephyr on NRF52 It's quite old but I guess you can give it a try.  

  • Hi Hung,

    I've got it working now thanks to that thread. Thank you for sharing that.

    Below is a working snippet for anyone else trying to do this (ncs v3.1.1 and NRF54L15)

    No device overlay

    prj.conf simply contains "CONFIG_NRFX_LPCOMP=y"

    Main.c is:
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>

    #include <hal/nrf_lpcomp.h>
    #include <hal/nrf_gpio.h>
    #include <nrfx_lpcomp.h>
    #include <nrfx_gpiote.h>
    #include <nrfx.h>

    static nrfx_lpcomp_config_t config =
        NRFX_LPCOMP_DEFAULT_CONFIG(NRF_GPIO_PIN_MAP(1, 11));

    static nrfx_err_t err;

    static void lpcomp_event_handler(nrf_lpcomp_event_t event)
    {
        if (event == NRF_LPCOMP_EVENT_DOWN) {
            printk("DOWN event! Lowering Threshold...\n");

            // Shutdown LPCOMP to make changes
            nrfx_lpcomp_disable();
            nrfx_lpcomp_uninit();

            // change reference
            config.reference = NRF_LPCOMP_REF_SUPPLY_3_8;

            // clear latched LPCOMP events before re-init
            NRF_LPCOMP->EVENTS_DOWN  = 0;
            NRF_LPCOMP->EVENTS_UP    = 0;
            NRF_LPCOMP->EVENTS_CROSS = 0;
            NRF_LPCOMP->EVENTS_READY = 0;

            err = nrfx_lpcomp_init(&config, lpcomp_event_handler);
            if (err != NRFX_SUCCESS) {
                printk("nrfx_lpcomp_init error: %08x\n", err);
                return;
            }

            nrfx_lpcomp_enable();
        }
    }

    void main(void)
    {
        IRQ_DIRECT_CONNECT(COMP_LPCOMP_IRQn, 5, nrfx_lpcomp_irq_handler, 0);

        // initial configuration
        config.reference = NRF_LPCOMP_REF_SUPPLY_4_8;
        config.detection = NRF_LPCOMP_DETECT_DOWN;
        config.hyst      = NRF_LPCOMP_HYST_ENABLED;

        err = nrfx_lpcomp_init(&config, lpcomp_event_handler);
        if (err != NRFX_SUCCESS) {
            printk("nrfx_lpcomp_init error: %08x\n", err);
            return;
        }

        nrfx_lpcomp_enable();

        printk("LPCOMP initialized\n");
    }
Reply
  • Hi Hung,

    I've got it working now thanks to that thread. Thank you for sharing that.

    Below is a working snippet for anyone else trying to do this (ncs v3.1.1 and NRF54L15)

    No device overlay

    prj.conf simply contains "CONFIG_NRFX_LPCOMP=y"

    Main.c is:
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>

    #include <hal/nrf_lpcomp.h>
    #include <hal/nrf_gpio.h>
    #include <nrfx_lpcomp.h>
    #include <nrfx_gpiote.h>
    #include <nrfx.h>

    static nrfx_lpcomp_config_t config =
        NRFX_LPCOMP_DEFAULT_CONFIG(NRF_GPIO_PIN_MAP(1, 11));

    static nrfx_err_t err;

    static void lpcomp_event_handler(nrf_lpcomp_event_t event)
    {
        if (event == NRF_LPCOMP_EVENT_DOWN) {
            printk("DOWN event! Lowering Threshold...\n");

            // Shutdown LPCOMP to make changes
            nrfx_lpcomp_disable();
            nrfx_lpcomp_uninit();

            // change reference
            config.reference = NRF_LPCOMP_REF_SUPPLY_3_8;

            // clear latched LPCOMP events before re-init
            NRF_LPCOMP->EVENTS_DOWN  = 0;
            NRF_LPCOMP->EVENTS_UP    = 0;
            NRF_LPCOMP->EVENTS_CROSS = 0;
            NRF_LPCOMP->EVENTS_READY = 0;

            err = nrfx_lpcomp_init(&config, lpcomp_event_handler);
            if (err != NRFX_SUCCESS) {
                printk("nrfx_lpcomp_init error: %08x\n", err);
                return;
            }

            nrfx_lpcomp_enable();
        }
    }

    void main(void)
    {
        IRQ_DIRECT_CONNECT(COMP_LPCOMP_IRQn, 5, nrfx_lpcomp_irq_handler, 0);

        // initial configuration
        config.reference = NRF_LPCOMP_REF_SUPPLY_4_8;
        config.detection = NRF_LPCOMP_DETECT_DOWN;
        config.hyst      = NRF_LPCOMP_HYST_ENABLED;

        err = nrfx_lpcomp_init(&config, lpcomp_event_handler);
        if (err != NRFX_SUCCESS) {
            printk("nrfx_lpcomp_init error: %08x\n", err);
            return;
        }

        nrfx_lpcomp_enable();

        printk("LPCOMP initialized\n");
    }
Children
No Data
Related