<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://devzone.nordicsemi.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Usage of interrupts from I2C device</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/107801/usage-of-interrupts-from-i2c-device</link><description>I am using the nrf9160dk and an ST lis2dw12 accelerometer. I want to be able to set up an interrupt to fire on an anymotion event. From what I understand from the nrf-connect-sdk fundamentals course, I need to configure my device tree overlay like this</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 29 Jan 2024 16:22:45 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/107801/usage-of-interrupts-from-i2c-device" /><item><title>RE: Usage of interrupts from I2C device</title><link>https://devzone.nordicsemi.com/thread/466592?ContentTypeID=1</link><pubDate>Mon, 29 Jan 2024 16:22:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:33e8a3b6-c22a-4cde-a500-1851e7dca349</guid><dc:creator>Anthony Ambuehl</dc:creator><description>&lt;p&gt;You specify the board configuration in the device tree for example:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;accel: lis2dw12@18 {
compatible = &amp;quot;st,lis2dw12&amp;quot;;
status = &amp;quot;okay&amp;quot;;
reg = &amp;lt;0x18&amp;gt;;
irq-gpios = &amp;lt;&amp;amp;gpio0 5 (GPIO_PULL_UP | GPIO_ACTIVE_LOW) &amp;gt;;
};&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;irq-gpios can hold 1-2 gpio specifiers.&amp;nbsp; In the code sample it has 1.&amp;nbsp; The &amp;amp;gpio0 indicates another device tree object named gpio0 (which happens to be a gpio device driver) the, 5 means pin 5 in gpio0 and the third option is the initial gpio configuration.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;These settings get populated into the device driver config through this macro:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#ifdef CONFIG_LIS2DW12_TRIGGER
#define LIS2DW12_CFG_IRQ(inst) \
	.gpio_int = GPIO_DT_SPEC_INST_GET(inst, irq_gpios),		\
	.int_pin = DT_INST_PROP(inst, int_pin),
#else
#define LIS2DW12_CFG_IRQ(inst)
#endif /* CONFIG_LIS2DW12_TRIGGER *&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Then in the lis2dw12_trigger code the gpio initialization includes:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;	ret = gpio_pin_configure_dt(&amp;amp;cfg-&amp;gt;gpio_int, GPIO_INPUT);
	if (ret &amp;lt; 0) {
		LOG_ERR(&amp;quot;Could not configure gpio&amp;quot;);
		return ret;
	}

	LOG_INF(&amp;quot;%s: int on %s.%02u&amp;quot;, dev-&amp;gt;name, cfg-&amp;gt;gpio_int.port-&amp;gt;name,
				      cfg-&amp;gt;gpio_int.pin);

	gpio_init_callback(&amp;amp;lis2dw12-&amp;gt;gpio_cb,
			   lis2dw12_gpio_callback,
			   BIT(cfg-&amp;gt;gpio_int.pin));

	if (gpio_add_callback(cfg-&amp;gt;gpio_int.port, &amp;amp;lis2dw12-&amp;gt;gpio_cb) &amp;lt; 0) {
		LOG_DBG(&amp;quot;Could not set gpio callback&amp;quot;);
		return -EIO;
	}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Since the callback for the gpio driver may be directly in the ISR, and its not allowed to perform blocking operations such as i2c reads in an ISR, the callback code triggers another thread to perform additional processing including calling the user specified callback.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;#if defined(CONFIG_LIS2DW12_TRIGGER_OWN_THREAD)
	k_sem_give(&amp;amp;lis2dw12-&amp;gt;gpio_sem);
#elif defined(CONFIG_LIS2DW12_TRIGGER_GLOBAL_THREAD)
	k_work_submit(&amp;amp;lis2dw12-&amp;gt;work);
#endif /* CONFIG_LIS2DW12_TRIGGER_OWN_THREAD *&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I have found some drivers will directly call the user callback from the ISR so its important to review the actual driver.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Also note that the gpio0 is itself a driver which means it might be a direct gpio interface or it might be an I/O expander, the api is the same but the actual implementation of the gpio operations will vary.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Hopefully that explains how it all works.&amp;nbsp; I will also add if you question is how to run your own user callback, you do that with the sensor_trigger_set API.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The details of sensor_trigger_set can be found in zephyr/include/zephyr/drivers/sensor.h&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;/**
 * @typedef sensor_trigger_handler_t
 * @brief Callback API upon firing of a trigger
 *
 * @param dev Pointer to the sensor device
 * @param trigger The trigger
 */
typedef void (*sensor_trigger_handler_t)(const struct device *dev,
					 const struct sensor_trigger *trigger);

/**
 * @brief Activate a sensor&amp;#39;s trigger and set the trigger handler
 *
 * @param dev Pointer to the sensor device
 * @param trig The trigger to activate
 * @param handler The function that should be called when the trigger
 * fires
 *
 * @return 0 if successful, negative errno code if failure.
 */
static inline int sensor_trigger_set(const struct device *dev,
				     const struct sensor_trigger *trig,
				     sensor_trigger_handler_t handler&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Usage of interrupts from I2C device</title><link>https://devzone.nordicsemi.com/thread/466539?ContentTypeID=1</link><pubDate>Mon, 29 Jan 2024 13:53:35 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fb9905f2-31b2-4c6e-afa5-a67f4db8d9f6</guid><dc:creator>0sleep</dc:creator><description>&lt;p&gt;Thank you so much for your advice! I think I have managed to set up the DRDY pin correctly now. I am still not quite sure how to have an interrupt service routine run on change of a pin state. How would I need to set up my devicetree overlay for this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Usage of interrupts from I2C device</title><link>https://devzone.nordicsemi.com/thread/466298?ContentTypeID=1</link><pubDate>Fri, 26 Jan 2024 17:15:51 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d74b6bb9-39f2-40a0-ad0f-92d245a33c61</guid><dc:creator>Anthony Ambuehl</dc:creator><description>&lt;p&gt;The driver code for lis2dw12 is found in $ZEPHYR_BASE/drivers/sensor/lis2dw12&amp;nbsp; &amp;nbsp; The code for handling the interrupts (aka triggers) is found in lis2dw12_trigger.c.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;The supported triggers in that code are:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;SENSOR_TRIG_DATA_READY&lt;/p&gt;
&lt;p&gt;&amp;nbsp;SENSOR_TRIG_TAP&amp;nbsp; (needs Kconfig&amp;nbsp;CONFIG_LIS2DW12_TAP=y)&lt;/p&gt;
&lt;p&gt;SENSOR_TRIG_DOUBLE_TAP&amp;nbsp;&lt;span&gt;(needs Kconfig&amp;nbsp;&lt;/span&gt;&lt;span&gt;CONFIG_LIS2DW12_TAP=y)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;SENSOR_TRIG_THRESHOLD (needs Kconfig&amp;nbsp;CONFIG_LIS2DW12_THRESHOLD, set attrs&amp;nbsp;SENSOR_ATTR_LOWER_THRESH and&amp;nbsp;SENSOR_ATTR_UPPER_THRESH)&lt;/p&gt;
&lt;p&gt;SENSOR_TRIG_FREEFALL (needs Kconfig&amp;nbsp;CONFIG_LIS2DW12_FREEFALL)&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;For other triggers, you will need to modify the driver code.&amp;nbsp; The drivers that Zephyr provides do not implement every feature found in the hardware.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;BTW -- if you know anyone looking for an embedded software developer, I&amp;#39;m currently looking.&amp;nbsp; I&amp;#39;ve been actively working with Zephyr and have worked with Nordic chips since 2013.&amp;nbsp; Here is my linkedin profile:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linkedin.com/in/anthonyambuehl/"&gt;www.linkedin.com/.../&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>