<?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>PPI and timers</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/82019/ppi-and-timers</link><description>Hello I am learning how to connect timers with gpio via PPI, i working on nrf52832dk. 
 So far I have connected the RTC 0 alarm channel to the LED no.3 (pin no.19) and its state changes every time the timer is called. 
 I tried to do the same with timer</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 01 Dec 2021 12:19:18 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/82019/ppi-and-timers" /><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/341496?ContentTypeID=1</link><pubDate>Wed, 01 Dec 2021 12:19:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:24098820-80c3-40a7-8ae3-1c4da4e9c40e</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You can look at the implementation of counter_nrfx_timer.c for details.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you look &lt;a href="https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/counter/counter_nrfx_timer.c#L21"&gt;here&lt;/a&gt; you can see that CC register 0 is used to store the top value, and CC register 1 is used every time you want to read out the current state of the timer in the &lt;a href="https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/counter/counter_nrfx_timer.c#L85"&gt;read()&lt;/a&gt; function.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The TIMER module does not allow you to read out the state of the timer without running a capture operation, and in order to do a capture you need to have a free CC register to store the capture value, which is why CC1 is assigned to this task only.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;This leaves only two more free CC registers (CC2 and CC3) to store custom values, and the &lt;a href="https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/counter/counter_nrfx_timer.c#L17"&gt;CC_TO_ID&lt;/a&gt; and ID_TO_CC macros are used to convert between CC number and channel ID.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/341299?ContentTypeID=1</link><pubDate>Tue, 30 Nov 2021 13:17:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:45379128-a07e-418b-8e76-dd3c4c5104fa</guid><dc:creator>creative.industry.ag</dc:creator><description>&lt;p&gt;Yes, but why there is this offset?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/341251?ContentTypeID=1</link><pubDate>Tue, 30 Nov 2021 11:13:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:209b6bcf-c27d-4dde-87ea-aa5534e8ad51</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That makes sense. TIMER1 in the nRF52832 has 4 CC registers (CC0-CC3), so if CC2 is used for channel ID 0 and CC3 for channel ID 1, then there are only CC registers available for 2 channels.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If you want more direct control of the timer and its registers you can use the &lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfx/drivers/timer/driver.html"&gt;nrfx_timer library&lt;/a&gt; instead.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/341115?ContentTypeID=1</link><pubDate>Mon, 29 Nov 2021 14:42:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dccf4762-d951-4d58-9c96-28cc398e3603</guid><dc:creator>creative.industry.ag</dc:creator><description>&lt;p&gt;&lt;span&gt;uint32_t&lt;/span&gt;&lt;span&gt; adr = &lt;/span&gt;&lt;span&gt;counter_get_num_of_channels&lt;/span&gt;&lt;span&gt;(timer_dev);&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;adr = 0x02&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/340828?ContentTypeID=1</link><pubDate>Fri, 26 Nov 2021 07:32:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:878d7617-ead7-4dfb-9c35-5e18b3dcd0b9</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&lt;/p&gt;
&lt;p&gt;What do you get if you run the&amp;nbsp;&lt;span&gt;counter_get_num_of_channels(..) function?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;It is not necessarily a direct mapping between the counter channel ID and the CC register value. The counter driver is probably using some CC registers for other purposes, so that it is not able to use all of them for registering alarms.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards&lt;br /&gt;Torbjørn&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/340635?ContentTypeID=1</link><pubDate>Thu, 25 Nov 2021 05:59:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fa332e5f-dbf2-4c4e-a700-dd0a44c2bd27</guid><dc:creator>creative.industry.ag</dc:creator><description>&lt;p&gt;I believe i found problem in driver, but i may be wrong.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;My code:&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;#include &amp;lt;zephyr.h&amp;gt;
#include &amp;lt;debug/ppi_trace.h&amp;gt;
#include &amp;lt;drivers/counter.h&amp;gt;
#include &amp;lt;hal/nrf_rtc.h&amp;gt;
#include &amp;lt;hal/nrf_clock.h&amp;gt;
#include &amp;lt;hal/nrf_timer.h&amp;gt;
#include &amp;lt;nrfx_timer.h&amp;gt;
#include &amp;lt;device.h&amp;gt;
#include &amp;lt;logging/log.h&amp;gt;

LOG_MODULE_REGISTER(app);
#define ALARM_PERIOD_US 1000 * 1000
#define TIMER NRF_TIMER1
#define TIMER_LABEL DT_LABEL(DT_NODELABEL(timer1))

static void timer_callback(const struct device *dev, uint8_t chan_id, uint32_t ticks,
						   void *user_data);

static struct counter_alarm_cfg TIM0_alarm_cfg = {
	.callback = timer_callback,
	.flags = 0, //?
};

static void ppi_trace_pin_setup(uint32_t pin, uint32_t evt)
{
	void *handle;

	handle = ppi_trace_config(pin, evt);
	__ASSERT(handle != NULL,
			 &amp;quot;Failed to initialize trace pin, no PPI or GPIOTE resources?&amp;quot;);

	ppi_trace_enable(handle);
}

static void ppi_trace_setup(void)
{
	ppi_trace_pin_setup(19, nrf_timer_event_address_get(TIMER, NRF_TIMER_EVENT_COMPARE0));

	ppi_trace_pin_setup(20, nrf_timer_event_address_get(TIMER, NRF_TIMER_EVENT_COMPARE2));

	LOG_INF(&amp;quot;PPI trace setup done.&amp;quot;);
}

static void timer_callback(const struct device *dev, uint8_t chan_id,
						   uint32_t ticks, void *user_data)
{
	int err;
	uint32_t alarm_cnt = (uint32_t)user_data + 1;

	TIM0_alarm_cfg.ticks = counter_us_to_ticks(dev, ALARM_PERIOD_US );
	TIM0_alarm_cfg.user_data = (void *)alarm_cnt;
	LOG_INF(&amp;quot;timer_callback %d &amp;quot;, TIM0_alarm_cfg.ticks);
	err = counter_set_channel_alarm(dev, 0, &amp;amp;TIM0_alarm_cfg);
	__ASSERT_NO_MSG(err == 0);
	(void)err;
}

static void counter_setup(void)
{
	int err;
	const struct device *dev = device_get_binding(TIMER_LABEL);

	__ASSERT(dev, &amp;quot;Sample cannot run on this board.&amp;quot;);

	TIM0_alarm_cfg.ticks = counter_us_to_ticks(dev, ALARM_PERIOD_US);

	err = counter_set_channel_alarm(dev, 0, &amp;amp;TIM0_alarm_cfg);
	__ASSERT_NO_MSG(err == 0);

	err = counter_start(dev);
	__ASSERT_NO_MSG(err == 0);
}

void main(void)
{
	ppi_trace_setup();
	counter_setup();

	while (1)
	{
		k_msleep(1000);
	}
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Description:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I working on nrf52832 dk.&lt;/p&gt;
&lt;p&gt;The problem is with the wrong selection of the timer alarm channel. I call function which should use channel 0 timer 1&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;counter_set_channel_alarm(dev_tim, NRF_TIMER_CC_CHANNEL0, &amp;amp;TIM0_alarm_cfg);&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;But the&amp;nbsp;driver has assigned an alarm interrupt on channel 2, you can see it in the CPU registers. ( active interrupt 2 not 0)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/320x240/__key/communityserver-discussions-components-files/4/pastedimage1637820415468v1.png" /&gt;&lt;/p&gt;
&lt;pre class="tw-data-text tw-text-large tw-ta" id="tw-target-text" dir="ltr"&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/340570?ContentTypeID=1</link><pubDate>Wed, 24 Nov 2021 14:05:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:64ba1609-f378-41e6-be8a-ce96c25eb3e9</guid><dc:creator>ovrebekk</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You mean to say you found the problem in your own code, or that there is a bug in the one of the drivers?&lt;/p&gt;
&lt;p&gt;Best regards&lt;br /&gt;Torbjørn&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: PPI and timers</title><link>https://devzone.nordicsemi.com/thread/340488?ContentTypeID=1</link><pubDate>Wed, 24 Nov 2021 09:55:26 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:29bbb5a8-577a-43a3-ad11-51c44d8cfa00</guid><dc:creator>creative.industry.ag</dc:creator><description>&lt;div class="FFpbKc"&gt;
&lt;div class="ZTPlmc"&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="dePhmb"&gt;
&lt;div class="eyKpYb"&gt;
&lt;div class="J0lOec"&gt;&lt;span class="VIiyi" lang="en"&gt;&lt;span class="JLqJ4b ChMk0b"&gt;&lt;span&gt;I managed to run ppi on a fast timer, it turned out that the &amp;quot;counter_set_channel_alarm&amp;quot; function that was supposed to set an alarm on channel 0 sets it on channel 2.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class="J0lOec"&gt;&lt;span class="VIiyi" lang="en"&gt;&lt;span class="JLqJ4b ChMk0b"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>