data ready interrupt in hdc2010.

I’m trying to interface with the HDC2010 sensor, which uses the I2C protocol. I’ve successfully done this using the polling method, but now I want to implement it using the Data Ready (DRDY) interrupt method. I’ve connected the INT1 pin of the sensor to a GPIO pin on my microcontroller. When I manually trigger the interrupt, it correctly enters the interrupt service routine. However, it’s not automatically generating interrupts when new data is available.

 

#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/gpio.h>
#define I2C_NODE DT_NODELABEL(hdc2010)

// config reg
#define CONFIG_REG 0X0E
#define MEASUREMENT_CONFIG 0x0F

// who i am reg
#define DEVICE_ID_L 0xFE
#define DEVICE_ID_H 0xFF

// menu id
#define MENU_ID_L 0xFC
#define MENU_ID_H 0xFD

// reading temp reg
#define TEMP_L 0X00
#define TEMP_H 0X01

// config interrupt pin
#define INTERRUPT_CONFIG 0x07

// init flag
int initFlag = 0;
// init temp flag
int tempFlag = 0;
// init hum flag
int humFlag = 0;

uint8_t config[2] = {CONFIG_REG, 0x80};

#define SW0_NODE DT_ALIAS(sw5)
int temp;
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(SW0_NODE, gpios);
static const struct i2c_dt_spec hdc2010 = I2C_DT_SPEC_GET(I2C_NODE);

int dataReady = 0;
static struct gpio_callback button_cb_data;

// who am i
int readDeviceId(const struct i2c_dt_spec *hdc2010, uint16_t *id, uint16_t *id1)
{
        int ret;
        // first reading device id
        uint8_t reg[2] = {DEVICE_ID_L, DEVICE_ID_H};
        uint8_t device_id[2] = {DEVICE_ID_L, DEVICE_ID_H};
        ret = i2c_write_read_dt(hdc2010, &reg[0], 1, &device_id[0], 1);
        if (ret)
        {
                printk("device id error\n");
                return -1;
        }
        ret = i2c_write_read_dt(hdc2010, &reg[1], 1, &device_id[1], 1);
        if (ret)
        {
                printk("device id error\n");
                return -1;
        }
        *id = (device_id[1] << 8) | device_id[0];
        // second reading menu id
        reg[0] = MENU_ID_L;
        reg[1] = MENU_ID_H;
        ret = i2c_write_read_dt(hdc2010, &reg[0], 1, &device_id[0], 1);
        if (ret)
        {
                printk("menu id error\n");
                return -1;
        }
        ret = i2c_write_read_dt(hdc2010, &reg[1], 1, &device_id[1], 1);
        if (ret)
        {
                printk("menu id error");
                return -1;
        }
        *id1 = (device_id[1] << 8) | device_id[0];
        printk("%x %x device id and menu id\n", *id, *id1);
        return 0;
}
// init
int hdc2010Init(const struct i2c_dt_spec *hdc2010)
{
        uint8_t oldConfig;
        int ret;
        if (initFlag)
        {
                return 0;
        }

        uint8_t tempReg[2] = {CONFIG_REG, 0};

        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        uint8_t newConfig = oldConfig | 7 << 4;
        config[1] = newConfig;
        ret = i2c_write_dt(hdc2010, config, sizeof(config));
        if (ret != 0)
        {
                printk("soft reseting is fail\n");
                return -1;
        }

        /*
        Bits 2 and 1 of the MEASUREMENT_CONFIG register controls
        the measurement mode
        */
        // Upper two bits of the MEASUREMENT_CONFIG register controls the temperature resolution
        // default value is 14
        // Bit 0 of the MEASUREMENT_CONFIG register can be used to trigger measurements

        config[0] = MEASUREMENT_CONFIG;
        config[1] = 0X4b;
        ret = i2c_write_dt(hdc2010, config, sizeof(config));
        if (ret != 0)
        {
                printk("setup measurement config failed \n");
                return -1;
        }
        initFlag = 1;
        tempFlag = 1;
        return 0;
}

// deinit hdc2010
int hdc2010DeInit()
{
        tempFlag = 0;
        humFlag = 0;
        initFlag = 0;
        return 0;
}
// reading values for sensor temperature
int Hdc2010ReadingTemperature(const struct i2c_dt_spec *hdc2010, int *val)
{
        int ret;
        volatile uint16_t temp;
        float intermediate, value;
        hdc2010Init(hdc2010);
        uint8_t tempReg[2] = {TEMP_L, TEMP_H};
        uint8_t reading[2];
        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &reading[0], 1);
        if (ret)
        {
                printk("failed at reading temperature\n");
                return -1;
        }
        ret = i2c_write_read_dt(hdc2010, &tempReg[1], 1, &reading[1], 1);
        if (ret)
        {
                printk("failed at reading temperature\n");
                return -1;
        }
        temp = (reading[1] << 8) | reading[0];
        intermediate = temp / 65536.0;
        intermediate = intermediate * 165;
        value = intermediate - 40.00;
        *val = value;
        printk("%0.2f C\n", value);
        hdc2010DeInit();
        return 0;
}

int hdc_enable_interrupt(const struct i2c_dt_spec *hdc2010)
{
        uint8_t oldConfig;
        int ret;
        uint8_t tempReg[2] = {CONFIG_REG, 0};

        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("reading in reg problem int\n");
                return -1;
        }
        uint8_t newConfig = oldConfig | 1 << 2; // setting intEn pin in config reg
        tempReg[1] = newConfig;

        ret = i2c_write_dt(hdc2010, tempReg, sizeof(tempReg));
        if (ret)
        {
                printk("setting int pin is not set\n");
                return -1;
        }
        return ret;
}
// setting up polarity for interrupt
int hdc2010_setInterruptPolarity(const struct i2c_dt_spec *hdc2010, int polarity)
{
        uint8_t oldConfig;
        int ret;
        uint8_t tempReg[2] = {CONFIG_REG, 0};

        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        uint16_t newConfig;
        if (polarity)
        {
                newConfig = oldConfig | 1 << 1; // setting polarity of pin active high
        }
        else
        {
                newConfig = oldConfig & ~(1 << 1); // setting polarity of pin active low
        }
        tempReg[1] = newConfig;

        ret = i2c_write_dt(hdc2010, tempReg, sizeof(tempReg));
        if (ret)
        {
                printk("setting int pin is not set\n");
                return -1;
        }
        return ret;
}
// trigger reading
int triggerMeasurement(const struct i2c_dt_spec *hdc2010)
{
        uint8_t oldConfig;
        int ret;
        uint8_t tempReg[2] = {MEASUREMENT_CONFIG, 0};

        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        uint8_t newConfig = oldConfig | 1 << 0; // setting start measurement
        tempReg[1] = newConfig;

        ret = i2c_write_dt(hdc2010, tempReg, sizeof(tempReg));
        if (ret)
        {
                printk("setting int pin is not set\n");
                return -1;
        }
        return 0;
}
// setting up drdy bit
int hdc2010_enableDRDYInterrupt(const struct i2c_dt_spec *hdc2010)
{
        uint8_t config;
        int ret;
        uint8_t tempReg[2] = {INTERRUPT_CONFIG, 0};

        ret = i2c_write_read_dt(hdc2010, &tempReg[0], 1, &config, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        uint8_t newConfig = config | 1 << 7; // setting intEn pin in config reg
        tempReg[1] = newConfig;

        ret = i2c_write_dt(hdc2010, tempReg, sizeof(tempReg));
        if (ret)
        {
                printk("setting int pin is not set\n");
                return -1;
        }
        return 0;
}

// setting up interrupt drdy
int HDC2010_Enable_DRDY_Interrupt(const struct i2c_dt_spec *hdc2010, int polarity)
{

        int ret = hdc2010_enableDRDYInterrupt(hdc2010);
        ret = hdc_enable_interrupt(hdc2010);
        if (ret)
        {
                printk("hdc2010 enable interrupt error\n");
                return -1;
        }
        ret = hdc2010_setInterruptPolarity(hdc2010, polarity);
        if (ret)
        {
                printk("hdc2010 enabling polarity error\n");
        }
        ret = triggerMeasurement(hdc2010);

        return 0;
}

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
        dataReady = 1;
        printk("interrupt triggered\n");
        /// Hdc2010ReadingTemperature(&hdc2010, &temp);
        //  triggerMeasurement(&hdc2010);
}
int main(void)
{
        int ret;
        if (!device_is_ready(button.port))
        {
                printk("inti problem\n");
                return;
        }
        //    static const struct i2c_dt_spec hdc2010 = I2C_DT_SPEC_GET(I2C_NODE);
        if (!device_is_ready(hdc2010.bus))
        {
                printk("device is not ready\n");
                return 0;
        }

        // sensor init part is here
        ret = hdc2010Init(&hdc2010);
        if (ret)
        {
                printk("hdc2010 sensor init failed\n");
                return -1;
        }

        printk("init completed\n");
        ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
        ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
        if (ret)
        {
                printk("error\n");
                return 0;
        }
        // // temp part
        uint8_t tempReg[2] = {MEASUREMENT_CONFIG, 0};
        uint8_t oldConfig;
        ret = i2c_write_read_dt(&hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        printk("%x measurement\n", oldConfig);
        tempReg[0] = CONFIG_REG;
        oldConfig;
        ret = i2c_write_read_dt(&hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }

        printk("%x config\n", oldConfig);

        gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
        gpio_add_callback(button.port, &button_cb_data);
        int temp;

        ret = HDC2010_Enable_DRDY_Interrupt(&hdc2010, 0);
        if (ret)
        {
                printk("error\n");
                return 0;
        }
        tempReg[0] = INTERRUPT_CONFIG;
        ret = i2c_write_read_dt(&hdc2010, &tempReg[0], 1, &oldConfig, 1);
        if (ret)
        {
                printk("writing in reg problem\n");
                return -1;
        }
        printk("%x DRDY BIT\n", oldConfig);
        while (1)
        {
                k_msleep(1000);
        }
        return 0;
}

this is code i have written , drivers were not available in zephyr so i have to wrote them, see if there is problem.

&i2c0 {
    status = "okay";
    hdc2010: hdc2010@40 {
        compatible = "i2c-device";
        status = "okay";
        reg = <0x40>;
    };
};
/ {
    buttons {
        compatible = "gpio-keys";
        button5: button_5 {
            gpios = <&gpio0 4 (GPIO_PULL_UP | GPIO_ACTIVE_HIGH)>;

        };

    };
    aliases{
        sw5=&button5;
    };

};
 
and this is my overlay file.

Parents
  • Hi Tejas,

    I think you need to revisit the datasheet for your sensor.

    The issue, I believe, is coming from sensor side, not from the SoC side.

    Just to test, when the data is available, can you check by logic analyzer that the signal is generated on the INT pin of the sensor?

    Also, why are you using POL=0, while you have setup the gpio-button as ACTIVE-HIGH?

Reply
  • Hi Tejas,

    I think you need to revisit the datasheet for your sensor.

    The issue, I believe, is coming from sensor side, not from the SoC side.

    Just to test, when the data is available, can you check by logic analyzer that the signal is generated on the INT pin of the sensor?

    Also, why are you using POL=0, while you have setup the gpio-button as ACTIVE-HIGH?

Children
No Data
Related