<?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>Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/96248/offset-in-saadc-samples-with-easy-dma</link><description>Hello, 
 
 I am experiencing a similar issue to the the following post where the channels sampled from SAADC buffer are becoming out of order (i.e {channels 0 , channel1, channel 6 ... } are becoming miss-aligned as {channel 6, channel 0, channel 1 .</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 06 Feb 2023 17:16:04 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/96248/offset-in-saadc-samples-with-easy-dma" /><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/408372?ContentTypeID=1</link><pubDate>Mon, 06 Feb 2023 17:16:04 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:6ca31c32-aa0e-4def-9546-294cb3de1a55</guid><dc:creator>mattmacleod</dc:creator><description>&lt;p&gt;Great! Thanks for your help!&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/408249?ContentTypeID=1</link><pubDate>Mon, 06 Feb 2023 11:25:59 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e1183383-a764-4cae-b37e-3a5bcd711ac8</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Yes, your implementation looks correct!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/408106?ContentTypeID=1</link><pubDate>Sat, 04 Feb 2023 00:51:37 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b38f97f6-b6f1-4e53-9146-c426fb60fb1d</guid><dc:creator>mattmacleod</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;span&gt;J&amp;oslash;rgen,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This solution appeared to fix my issue, Im going to do some further testing but I had a little trouble associating the correct macros to the PUBLISH_END, SUBSCRIBE START registers for the GPPI driver api.&amp;nbsp; Is this the correct implementation?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;pre class="ui-code" data-mode="text"&gt;	/* Configure  one-to-one connection connection between NRF_SAADC-&amp;gt;PUBLISH_END and NRF_SAADC-&amp;gt;SUBSCRIBE_START
	 */
	nrfx_gppi_channel_endpoints_setup(channel2,
		nrf_saadc_event_address_get(NRF_SAADC, NRF_SAADC_EVENT_END   ),
			nrf_saadc_task_address_get(NRF_SAADC, NRF_SAADC_TASK_START));
&lt;/pre&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thank you very much for your help.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Matt&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/407906?ContentTypeID=1</link><pubDate>Fri, 03 Feb 2023 08:20:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b11885e6-5c44-41bd-9219-c7e8c48b3e61</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;You can&amp;#39;t use the same channel for the END-&amp;gt;START connection as you use for TIMER_COMPARE-&amp;gt;SAADC_SAMPLE, this will create a many-to-many connection and will cause START task to be triggered by TIMER and SAMPLE task to be triggered by the END event. This will cause more problems than what you are trying to solve. Since you already use the dppi/gppi driver API for setting up the sampling, I recommend that you continue using this and allocate a new (D)PPI channel for this new task. This way you avoid choose a channel that is used by another library/driver.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/407867?ContentTypeID=1</link><pubDate>Fri, 03 Feb 2023 01:32:30 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:266361aa-1148-4a70-b3a3-e9513fb0cafd</guid><dc:creator>mattmacleod</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;span&gt;J&amp;oslash;rgen,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Thanks for you reply.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt; I tried&amp;nbsp;&lt;/span&gt;setting the registers directly through the bate metal implementation you linked and it didnt seem to fix the issue. Could you take a look at my code and see what Im missing? see lines 359-363.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;

/*
	API for reading MFTM ADC Channels 
	- battery is measured 1/sec 
	- Force sensors are measured 6000Hz 
*/

#include &amp;lt;logging/log.h&amp;gt;
#include &amp;quot;mftm_adc_init.h&amp;quot;
#include &amp;quot;msg_nrf_sensors.h&amp;quot;
#include &amp;quot;msg_npb.h&amp;quot;
#include &amp;quot;msg_pkt.h&amp;quot;
#include &amp;quot;mftm_fsm.h&amp;quot;
#include &amp;quot;mftm_adc_init.h&amp;quot;
#include &amp;quot;mftm_gpio_init.h&amp;quot;
#include &amp;lt;zephyr.h&amp;gt;
#include &amp;lt;helpers/nrfx_gppi.h&amp;gt;
#include &amp;lt;nrfx_dppi.h&amp;gt;
#include &amp;lt;nrfx_saadc.h&amp;gt;
#include &amp;lt;nrfx_timer.h&amp;gt;
#include &amp;lt;logging/log.h&amp;gt;


#if defined(SEND_FORCE_DATA) || defined (SEND_BAT_DATA)

LOG_MODULE_REGISTER(mftm_adc, CONFIG_LOG_DEFAULT_LEVEL);

msg_buffer_t msg_bat; 
msg_buffer_t msg_force; 

static bool force_fsm_enabled =  true; //variable to syncronize temp with fsm 
// //at present we want to sample battery 1/sec. 
//At 165us samples x 150 sample buffers = 24.750 ms~ 25ms 
//therefore we will call the battery function 1 every 40 saadc interrupts
#define BATTERY_ADC_NUM_ITERATIONS (40) 

#define SAMPLE_RATE_DEFAULT	 165UL	//165uS sampling desired 
nrfx_timer_t timer1 = NRFX_TIMER_INSTANCE(1);		//timer instance

//global bool for timer syncronization between api calls
bool timer_running = false; 
uint8_t channel;


int16_t saadc_buf1[SAADC_BUF_SIZE];
int16_t saadc_buf2[SAADC_BUF_SIZE];
int channels_to_read = 0; // actual number of channles we detect
bool send_force_raw = false; //guard for sending force measurments once stop command has been sent to fsm
static bool saadc_prev_enabled = false; 
static bool timer_prev_enabled = false; 

static nrfx_saadc_channel_t channels[ADC_NUM_CHANNELS] = {NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN0, 0),
                                                             NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN1, 1),
                                                             NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN2, 2),
                                                             NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN3, 3),
															 NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN4, 4),
															 NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN5, 5),
															 NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN6, 6),
															 NRFX_SAADC_DEFAULT_CHANNEL_SE(NRF_SAADC_INPUT_AIN7, 7)};	

#if defined(SEND_BAT_DATA)
// function to send bettery messages to TX buffer, since it will be different than the force sensor messages
// these will also be used in the BLE advertisment
static int send_battery_messages(int32_message_t raw_data){

  #if defined(TEST_DECODE_BATTERY)
   //send raw bytes to be serialized and then queued up  
    queue_data(MessageID_BAT, &amp;amp;raw_data.bytes, sizeof(int32_message_t),true, &amp;amp;msg_bat); 
  #else 
    queue_data(MessageID_BAT,  &amp;amp;raw_data.bytes, sizeof(int32_message_t), false, &amp;amp;msg_bat); 
  #endif //defined(TEST_DECODE_BATTERY)

  
} // defined(SEND_BAT_DATA)

#endif

#if defined(SEND_FORCE_DATA)
/*
	Description: PB Serializes Force messages and puts them on the bt_tx fifo 
	Note: for the mftm we are sending the 16 bit force values together, this is to conserve throughput 
*/
static int send_force_messages(adc_chan_t * forceData){

	#if defined(TEST_DECODE_FORCE)
	//send raw bytes to be serialized and then queued up  
		queue_data(MessageID_FORCE,  &amp;amp;forceData-&amp;gt;bytes,sizeof(Force), true, &amp;amp;msg_force); 
	#else 
		queue_data(MessageID_FORCE,  &amp;amp;forceData-&amp;gt;bytes,sizeof(Force), false, &amp;amp;msg_force); 

	#endif //defined(TEST_DECODE_FORCE)
	
}
#endif //defined(SEND_FORCE_DATA)




void saadc_evt_handler(nrfx_saadc_evt_t const * p_event)
{
	adc_chan_t * p_raw_adc; 
	static int32_t sample_adc_count = 0; 
	nrfx_err_t err = NRFX_SUCCESS;
	static uint8_t counter = 0;
	if(p_event-&amp;gt;type == NRFX_SAADC_EVT_DONE)
	{		

		// toggle_tp1(); //REMOVE once satisfied with force samples

		sample_adc_count++; 
	#if defined(SEND_FORCE_DATA)
		
		if(send_force_raw ){
				
			//at present, we only have 2 16 bit adc force samples that need to be transmitted at 6000Hz
			//minimum size of protobuffer is 32 bits, se we will currently send them both out as a combined adc value to reduce throughput by half
			//send force messages

			p_raw_adc = (adc_chan_t*)p_event-&amp;gt;data.done.p_buffer; 
			send_force_messages(p_raw_adc);
		}	
    #endif 
		//initalize bat channel  
    #if defined(SEND_BAT_DATA) &amp;amp;&amp;amp; !defined(SEND_FORCE_DATA) 
		int32_message_t bat_raw; 

		
		if(sample_adc_count == BATTERY_ADC_NUM_ITERATIONS) {

			//reset adc access count
			sample_adc_count = 0; 
			//allocate raw bat_value
			//we will disguard other 49 samples for now 
			bat_raw.value = p_event-&amp;gt;data.done.p_buffer[2]; 
			//send battery messages
			send_battery_messages(bat_raw);
		
		}
    #endif 
	}
	
	else if(p_event-&amp;gt;type == NRFX_SAADC_EVT_CALIBRATEDONE)
	{
		LOG_INF(&amp;quot;SAADC calibrated.&amp;quot;);
	}
	else if(p_event-&amp;gt;type == NRFX_SAADC_EVT_BUF_REQ)
	{
		counter++;

		if(counter%2)
		{
			err = nrfx_saadc_buffer_set(saadc_buf1, SAADC_BUF_SIZE);
			if(err != NRFX_SUCCESS)
			{
				LOG_ERR(&amp;quot;saadc_evt_handler(). Could not set buffer2: %d&amp;quot;, err);
			}
		}
		else
		{
			err = nrfx_saadc_buffer_set(saadc_buf2, SAADC_BUF_SIZE);
			if(err != NRFX_SUCCESS)
			{
				LOG_ERR(&amp;quot;saadc_evt_handler(). Could not set buffer1: %d&amp;quot;, err);
			}
		}
		
	}
	else if(p_event-&amp;gt;type == NRFX_SAADC_EVT_FINISHED)
	{
		LOG_INF(&amp;quot;SAADC finished sampling&amp;quot;);
	}
}

void timer1_evt_handler(nrf_timer_event_t event_type, void * p_context)	//called when timer is triggered
{
	// Nothing to do here, the timer&amp;#39;s IRQ is not enabled

}

void timer_init(uint32_t sample_rate)
{
	nrfx_err_t err = NRFX_SUCCESS;
	uint32_t time_ticks;

	nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
	
	timer_cfg.frequency          = NRF_TIMER_FREQ_16MHz;
    timer_cfg.mode               = NRF_TIMER_MODE_TIMER;
    timer_cfg.bit_width          = NRF_TIMER_BIT_WIDTH_32;		
    timer_cfg.interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY;

	//if the timer has already been enabled, we want to disable the instance 
	if(timer_prev_enabled){ 
		nrfx_timer_uninit(&amp;amp;timer1); 

	}
	err = nrfx_timer_init(&amp;amp;timer1, &amp;amp;timer_cfg, timer1_evt_handler);
	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;timer_init(). Could not initialize TIMER1: %d&amp;quot;, err);
		return; //return from the function if something went wrong 
	}else{ 
		timer_prev_enabled = true;
	}
	time_ticks = nrfx_timer_us_to_ticks(&amp;amp;timer1, (unsigned long)sample_rate);


	nrfx_timer_extended_compare(&amp;amp;timer1, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false);	

}

/*
	Decsription: Initalization function to parse the saadcCondig struct and create a bit mask to set the corresponding saadc channels
	Input: Pointer to saadc struct 
	Ouput: bit mask of enabled channels 
*/
uint32_t init_chan_cfgs(saadcConfig *saadcConfig){ 
	uint32_t chan_bit_mask = 0; 
	nrfx_err_t err; 
	int8_t i = 0;
	bool *pchan_cfg = &amp;amp;saadcConfig-&amp;gt;enableChan0;  //set pointer to address of battery channel
	
	//initalize channels chronologically 
	for ( i = 0; i &amp;lt;= ADC_NUM_CHANNELS; i++) {
		//if paramter is set to true, initalize that channnel 
		if (*pchan_cfg){ 
			err = nrfx_saadc_channel_config(&amp;amp;channels[i]);
			if(err != NRFX_SUCCESS)
			{
				LOG_ERR(&amp;quot;init_chan_cfgs(). Could not configure SAADC channel: %d on error: %d&amp;quot;,i, err);
			}else{	
				chan_bit_mask |= (1 &amp;lt;&amp;lt; i); 
				channels_to_read++; 
			}
		}
		pchan_cfg++;

	}
	return chan_bit_mask;
}


/*
	Description: saadc initalzation function 
	input: saadcConfig struct  
*/
void saadc_init(saadcConfig *saadc_cfg)
{
	nrfx_err_t err = NRFX_SUCCESS;
	uint32_t chan_bit_mask = 0; 

	nrfx_saadc_adv_config_t saadc_adv_cfg = NRFX_SAADC_DEFAULT_ADV_CONFIG;
	saadc_adv_cfg.start_on_end = false; //set this to false to avoid double triggering 
	
	//disable saadc if there already exists an instance 
	if(saadc_prev_enabled){ 

		nrfx_saadc_uninit(); 	
		k_sleep(K_MSEC(100));
	}
	
	err = nrfx_saadc_init(IRQ_PRIO_LOWEST);

	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init(). Could not initialize SAADC: %x&amp;quot;, err);
		return; //return from the function if something went wrong 
	}else{ 
		saadc_prev_enabled = true;
	}

	err = nrfx_saadc_offset_calibrate(NULL);
	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init(). Could not calibrate offset: %d&amp;quot;, err);
	}

	// set up ADC channels 
	chan_bit_mask = init_chan_cfgs(saadc_cfg); 

	err = nrfx_saadc_advanced_mode_set(chan_bit_mask, NRF_SAADC_RESOLUTION_12BIT, &amp;amp;saadc_adv_cfg, saadc_evt_handler);

	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init() Could not set advanced SAADC mode: %d&amp;quot;, err);
	}

	err = nrfx_saadc_buffer_set(saadc_buf1, SAADC_BUF_SIZE);
	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init(). Could not set buffer1: %d&amp;quot;, err);
	}

	err = nrfx_saadc_buffer_set(saadc_buf2, SAADC_BUF_SIZE);
	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init(). Could not set buffer2: %d&amp;quot;, err);
	}

	err = nrfx_saadc_mode_trigger();
	if(err != NRFX_SUCCESS)
	{
		LOG_ERR(&amp;quot;saadc_init(). Could trigger mode: %d&amp;quot;, err);
	}else{
		LOG_INF(&amp;quot;saadc_init(). Saadc initalizated&amp;quot;); 

	}	
}


/*
	Description: Initalization function for saadc channels. This function initalizes the dppi channels to allow for non-cpu bound hardware timer interrupts for the saadc channels
	Input: void pointer to saadc struct  
	Output: number of channels initalized
	Note: in order to meet the 7.5ms BLE connection interval time, the cpu could not be bound for less than 7.5ms in the ISR so
	the sample buffer size had to be hard coded as 150 (corresponding to ~25ms interupt latency) to provide us with some margin 
*/
int saadc_driver_config(saadcConfig *saadc_cfg)
{
	if(saadc_cfg == NULL){ 
		return 0 ;
	}

	nrfx_err_t err;

	force_fsm_enabled = saadc_cfg-&amp;gt;enabled;
	if(!force_fsm_enabled){ 
		stop_mftm_adc(); // stop adc sample collection 
		LOG_INF(&amp;quot;ssaadc_driver_config(). driver disabled&amp;quot;);
		return 0; // return 0 force sensors have been enabled 
	}
	/* Connect SAADC IRQ to nrfx_saadc_irq_handler */
	IRQ_CONNECT(SAADC_IRQn, IRQ_PRIO_LOWEST, nrfx_isr, nrfx_saadc_irq_handler, 0);
	//initalize hardware timer
	timer_init(saadc_cfg-&amp;gt;odr);
	//initalize saadc driver 
	saadc_init(saadc_cfg);


	//allocate dppi channels
	err = nrfx_dppi_channel_alloc(&amp;amp;channel);

	if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;mftm_adc_channels_init(). DPPI channel allocation error: %08x&amp;quot;, err);
		return 0 ;
	}

	/* Configure endpoints of the channel so that the TIMER1 CAPTURE0
		event is connected with the SAADC SAMPLE task. This means that each time
		TIMER1 reaches it&amp;#39;s set compare value, the SAADC will sample all 
		enabled channel once.
	 */
	nrfx_gppi_channel_endpoints_setup(channel,
		nrfx_timer_event_address_get(&amp;amp;timer1, NRF_TIMER_EVENT_COMPARE0),
			nrf_saadc_task_address_get(NRF_SAADC, NRF_SAADC_TASK_SAMPLE));

	
	NRF_SAADC-&amp;gt;PUBLISH_END  =  channel | 0x01;

	NRF_SAADC-&amp;gt;SUBSCRIBE_START   = channel | 0x01;
	
	NRF_DPPIC-&amp;gt;CHENSET = (1 &amp;lt;&amp;lt; channel);


	nrfx_dppi_channel_disable(channel);

	nrfx_timer_disable(&amp;amp;timer1);

	LOG_INF(&amp;quot;mftm_adc_channels_init(). nrfx_saadc initalized on %s&amp;quot;, CONFIG_BOARD);
	
	return channels_to_read;

}


void start_mftm_adc(bool send_force){ 

	/*  Trigger offset calibration
	 	As this generates a _DONE and _RESULT event
	    the first result will be incorrect.
	 */

	send_force_raw = send_force; 
	int err; 

	if(!timer_running){ 
		err = nrfx_dppi_channel_enable(channel);

		if (err != NRFX_SUCCESS) {
			LOG_ERR(&amp;quot;Failed to enable (D)PPI channel, error: %08x&amp;quot;, err);
			return;
		}

		nrfx_timer_enable(&amp;amp;timer1);

		timer_running = true; 
	}

}


void stop_mftm_adc(){ 
	//kill the timer to stop sample measurments 	
	if(timer_running){ 
		nrfx_dppi_channel_disable(channel);
		nrfx_timer_disable(&amp;amp;timer1);
		timer_running = false; 
	}

}


#endif //defined(SEND_FORCE_DATA)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thanks for your help.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Matt&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Offset in SAADC samples with Easy DMA.</title><link>https://devzone.nordicsemi.com/thread/407839?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 15:55:00 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:dd82ef79-125c-41df-8ffc-d9a4bf89d35a</guid><dc:creator>J&amp;#248;rgen Holmefjord</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The solution will be exactly the same when using DPPI as it is with normal PPI, the only difference is how the (D)PPI is configured. You need to setup a &lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/dppi.html#concept_kxv_krt_v1b"&gt;one-to-one connection&lt;/a&gt;&amp;nbsp;between NRF_SAADC-&amp;gt;&lt;a href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/saadc.html?cp=4_0_0_6_28_10#register.PUBLISH_END"&gt;PUBLISH_END&lt;/a&gt;&amp;nbsp;and NRF_SAADC-&amp;gt;&lt;a title="SUBSCRIBE_START" href="https://infocenter.nordicsemi.com/topic/ps_nrf5340/saadc.html?cp=4_0_0_6_28_10_4#register.SUBSCRIBE_START"&gt;SUBSCRIBE_START&lt;/a&gt;. You should also disable the trigger in your application, by setting &amp;quot;saadc_adv_cfg.start_on_end = false;&amp;quot;, to avoid issue with double triggering of the START task.&lt;/p&gt;
&lt;p&gt;There are helper functions available in nrfx that you can use, which provides a common API for PPI and DPPI, see&amp;nbsp;&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.2.0/nrfx/nrfx_api/gppi.html"&gt;Generic PPI Layer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;br /&gt;Jørgen&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>