Lis2mdl dont launch a trigger when i program with a threshold

Hello everyone,

I have tried several different approaches to solve this issue, but I have not been successful so far.

My goal is to generate an interrupt when the LIS2MDL magnetic field measurements (X, Y, and Z) go below a defined threshold. I created a small test application (shown below) to verify the interrupt functionality.

I have experimented with many different threshold values, including very low and very high settings, but the interrupt is never triggered.

Has anyone successfully used the LIS2MDL threshold interrupt feature with Zephyr or the nRF5340? Am I missing a required configuration step, such as interrupt routing, GPIO configuration, or sensor initialization?

Alsi "I'm having an doubt verifying if a trigger was successfully programmed on the sensor. When I configure it like this:

The function always returns success (ret == 0), even when I set a trigger type that the sensor theoretically doesn't support. I have no way to verify if the trigger was actually applied or just silently ignored by the driver."

 my code :: 
````

truct sensor_trigger trig = {
        .type = SENSOR_TRIG_THRESHOLD,  
        .chan = SENSOR_CHAN_MAGN_XYZ,
    };
    ret = sensor_trigger_set(sensor, &trig, trigger_handler);
    if (ret != 0) {
        LOG_ERR("Failed to set trigger: %d\n", ret);
        return ret;
    }
    LOG_INF("trigger set successfull\n");
    return 0;````

Driver code :: 

/* link external trigger to event data ready */
int lis2mdl_trigger_set(const struct device *dev,
              const struct sensor_trigger *trig,
              sensor_trigger_handler_t handler)
{
    const struct lis2mdl_config *cfg = dev->config;
    stmdev_ctx_t *ctx = (stmdev_ctx_t *)&cfg->ctx;
    struct lis2mdl_data *lis2mdl = dev->data;
    int16_t raw[3];

    if (!cfg->trig_enabled) {
        LOG_ERR("trigger_set op not supported");
        return -ENOTSUP;
    }

    if (trig->chan == SENSOR_CHAN_MAGN_XYZ) {
        lis2mdl->handler_drdy = handler;
        lis2mdl->trig_drdy = trig;
        if (handler) {
            /* fetch raw data sample: re-trigger lost interrupt */
            LOG_ERR("trigger_set supported");
            lis2mdl_magnetic_raw_get(ctx, raw);

            //return lis2mdl_enable_int(dev, 1);
            return 0;
        } else {
            return lis2mdl_enable_int(dev, 0);
        }
    }

    return -ENOTSUP;
}````

Any suggestions would be greatly appreciated.

To configure a trigger mode i applied this configuration as say in the datasheet but no respone :: 

`````

Thank you.

Parents
  • ASMA,

    This thread is mostly about the LIS2MDL and very less about nRF solutions, but I will still try to give you some of my thoughts.

    The LIS2MDL Zephyr driver only implements the data-ready trigger. lis2mdl_trigger_set() never checks trig->type. Only trig->chan, so SENSOR_TRIG_THRESHOLD takes the data-ready path and returns 0 then arms DRDY. That is why you always seem to get success and the threshold interrupt is never firing.

    I do not think that the INT_CTRL / INT_THS are ever configured. Also, I think that the LIS2MDL threshold interrupt is "absolute value exceeds ±threshold" in hardware. There is no below-threshold mode, so you cannot get a hardware interrupt for the field dropping below a value even with a full driver. So I would recommend you to keep SENSOR_TRIG_DATA_READY, and in the handler do sensor_sample_fetch + sensor_channel_get and compare against your threshold there. Should work with the upstream driver.

  • Thank you for your response.

    Regarding the threshold trigger, I actually made some modifications to the driver. I configured the `INT_CTRL` register as well as the threshold registers (`INT_THS_L` and `INT_THS_H`). I also configured the relevant settings in `CFG_REG_C` so that the interrupt pin would be used for threshold interrupts instead of data-ready notifications.

    I based this configuration on the official LIS2MDL datasheet, which states that enabling and configuring these registers should allow the threshold interrupt to be triggered.

    As a second test, I also tried using the data-ready trigger to verify whether interrupts were working at all when new measurement data became available. For this test, I configured the required registers according to the datasheet as well. However, I still did not receive any interrupt, and the trigger callback was never executed.

    Therefore, at the moment, neither the threshold interrupt nor the data-ready interrupt appears to be

    firing.

  • I think you should be a scope or logic analyzer to sniff the interrupt pin. Check if the interrupt is firing or not, if yes, then this is an MCU side configuration issue. If the pin never toggles, then it is a sensor configuration issue. We need to get this info first so that we know to either focus on the MCU  (device tree/irq gpios, polarity etc) or what is going wrong with configuring the sensor.

  • Hello,

    Thank you for your response.

    Yes, the last week  I already checked the points you mentioned. I am facing an issue with the sensor interrupt. Although the configuration appears to be correct, the interrupt signal is never triggered.

    I tested both interrupt sources: Data Ready (DRDY) and Threshold interrupts. I expected that at least the DRDY interrupt would be triggered, but I am not observing any interrupt activity.

    For the DRDY configuration, I programmed the registers as shown in the screenshot below.

    Could you please let me know if there is anything else I should verify or if I may be missing a required configuration step?

    For the case DRDY :: 

    INT_CTRL_REG  for the case of DRDY : 0x75

    I also noticed another behavior that may be related to the issue.

    When I configure CFG_Register_A, I write the value 0x80 (Continuous Mode). However, after the sensor initialization function completes(lis2msl_init), reading back the register returns 0x82 instead of 0x80, even though there is no function in my code that intentionally modifies this register.

    In the screenshot, I highlighted the register values with different colors to track when and where the value changes. I checked the register at several points during execution: before entering main(), during the sensor initialization function, and after initialization. The value appears to change unexpectedly.

    You may also notice some "read" messages highlighted in red in the screenshot. These are only debug print messages that I colored for visibility; they are not error messages.

    Could you clarify whether the sensor might automatically set bit 1 of CFG_Register_A, or if there is another mechanism that could explain why the register changes from 0x80 to 0x82?

  • Why do you have this set to 0x82, 0x02 in that number means POWER_DOWN

    The only place that is written to that sensor is in lis2mdl_pm_action


    Seems like CONFIG_PM_DEVICE in your prj.conf is making this sensor go to low power mode by default. Try disabling CONFIG_PM_DEVICE andCONFIG_PM_DEVICE_RUNTIME just to test and see.

  • Also  INT_CTRL is the threshold-interrupt control register, it is not used for data-ready at all. Data-ready is routed only by the DRDY-on-pin bit in CFG_REG_C, which you already have set. So for the DRDY test you can ignore INT_CTRL.

Reply Children
  • So , when i did as you said , when there will be a New data(xyz)  , the interruptions pin drdy  triggered ......

    As well as ; i dont understand why when i configure the reg_A to take 0x80 , it takes and the value of reg_A displays 0x80 but when they finish the initialisation (lis2mdl_init)  it takes the default value 0x82 

  • Arebhi said:
    it takes and the value of reg_A displays 0x80 but when they finish the initialisation (lis2mdl_init)  it takes the default value 0x82 

    Good, so now you have a working system. As I mentioned in earlier reply, the CONFIG_PM is making the sensor go to sleep immediately, that is because the driver of that sensor have implemented the powre management and you have enabled that power management in your prj.conf. As to why the driver decides to do that is the question you need to ask in Zephyr forums and/or that sensor manufacturer. You can easily override it (like you just did) if you need. You can also enable those configs and change the behavior of the pm_action calls as your application requires. 

Related