<?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>4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/96079/4-second-current-spikes-during-sleep</link><description>Hello All, 
 
 I am getting these ~3.5mA current spikes very 4 seconds and I can&amp;#39;t seem to figure what the cause of them is. some of the spikes have a single spike/pulse while other have multiple. please see the attached images. I have commented out everything</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 06 Mar 2023 12:46:58 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/96079/4-second-current-spikes-during-sleep" /><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/413533?ContentTypeID=1</link><pubDate>Mon, 06 Mar 2023 12:46:58 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:28a53c73-3f6e-4d7d-b633-9efb895023fb</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;The EasyDMA current you are seeing&amp;nbsp;comes from the 64 MHz clock and is not really affected by the RAM retention settings. There is not much that can be done about this, other than increasing the VDD voltage with DCDC enabled, unfortunately.&lt;/p&gt;
&lt;p&gt;RAM retention has more impact on the System ON idle current as you can see from the PS values here:&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1678106201678v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;The retention current for each 4K RAM section&amp;nbsp;is about 30 nA on average.&lt;/p&gt;
[quote user="whazin"]are there any library functions/APIs to do these kind of things?[/quote]
&lt;p&gt;Support for this is currently not integrated in Zephyr as far as I can tell. However, you can use the HAL to access the settings directly:&amp;nbsp;&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfx/drivers/power/hal.html#c.nrf_power_rampower_mask_on"&gt;https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrfx/drivers/power/hal.html#c.nrf_power_rampower_mask_on&lt;/a&gt;.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/413335?ContentTypeID=1</link><pubDate>Fri, 03 Mar 2023 18:59:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4a70d6d6-eda6-493a-9c8c-0f9e2408d74f</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;Hi Vidar,&lt;/p&gt;
&lt;p&gt;I hope all is well with you. I have noticed that one can control the different RAM regions with&amp;nbsp;RAM[n].POWER registers. Can this allow me to save on the EasyDMA current consumption(~2mA) if I was to powerdown some of the RAM regions? if so, how would I go about doing that? are there any library functions/APIs to do these kind of things? As always, your help will be greatly appreciated.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Wael&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/409573?ContentTypeID=1</link><pubDate>Mon, 13 Feb 2023 12:09:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:736cd797-09e9-406d-ad2b-476d05fae3ca</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;bt_gatt_notify_cb() uses the system work queue to run the callback function. This is why&amp;nbsp;it behaves differently&amp;nbsp;if called from the same work queue context. If it hadn&amp;#39;t, it&amp;nbsp;could&amp;nbsp;have become stuck waiting for the resource to be freed.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;From the API documentation (&lt;a href="https://developer.nordicsemi.com/nRF_Connect_SDK/doc/2.2.0/zephyr/connectivity/bluetooth/api/gatt.html#c.bt_gatt_notify_cb"&gt;link&lt;/a&gt;):&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1676287001317v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;A solution may be to queue up &amp;#39;CONFIG_BT_CONN_TX_MAX&amp;#39; notification packets, then wait for the callbacks&amp;nbsp;to arrive before queueing up more packets again.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/409425?ContentTypeID=1</link><pubDate>Fri, 10 Feb 2023 21:35:08 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:1ce949ea-fb87-47cc-bac9-84ec2290b2a6</guid><dc:creator>Wael</dc:creator><description>&lt;p style="margin-left:.25in;"&gt;hi Vidar,&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;Again, thanks for your reply. With regards to the 4k SPIM transfer issue, my receive buffer length was set to 256. dumb mistake on my part.&amp;nbsp; My next task after implementing the the GPIOTE/SPIM/PPI functionality is to upload the FRAM data via BLE to a PC. So I did a little search to see what the best path for uploading data with the maximum throughput and I came across the following link:&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/guides/nrf-connect-sdk-guides/b/software/posts/building-a-bluetooth-application-on-nrf-connect-sdk-part-3-optimizing-the-connection"&gt;Building a Bluetooth application on nRF Connect SDK - Part 3 Optimizing the connection&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;which is great and what exactly what I&amp;#39;m looking for.&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;so I grabbed the thread function they implemented their test in and added it to my code. ran as expected. since I don&amp;#39;t want to use a thread, I implemented a work item with the same logic. when using the work item, I receive the error &amp;quot;&amp;nbsp;bt_conn: Unable to allocate TX context&amp;quot; because the transmit buffers are getting full. but when using the thread, this does not happen and the thread blocks til new packet space becomes available. The following is from the post:&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;&amp;quot;&lt;em&gt;In this example, the application sends as quick as possible 300 notification packets in a simple loop.&amp;nbsp;What we noticed from the test was that bt_gatt_notify_cb() will not return -ENOMEM when the buffer is full. Instead, the function that requests the notification buffer will wait with K_FOREVER for the buffer to be available. This is different from the legacy Softdevice.&amp;nbsp;In Softdevice, if we queue the notification and receive&amp;nbsp;NRF_ERROR_RESOURCES (buffer full), we will need to wait for the&amp;nbsp;BLE_GATTS_EVT_HVN_TX_COMPLETE to retry again. In nRF Connect SDK, it&amp;#39;s a blocking function instead, and we need to keep the&amp;nbsp;data alive until the function is returned. Note that unlike bare-metal applications (e.g nRF5 SDK) blocking function in RTOS won&amp;#39;t keep the CPU in a busy loop.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;I can NOT figure out why the same function calls behave differently between the thread and a work item. I also noticed in the work item, the connection parameters are requested but the connection parameter completed isn&amp;#39;t completed unless I change the connection parameters by hand on the NRF Connect BLE App. As always, any help would be greatly appreciated.&amp;nbsp;&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;Regards,&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;Wael&lt;/p&gt;
&lt;p style="margin-left:.25in;"&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/408902?ContentTypeID=1</link><pubDate>Wed, 08 Feb 2023 14:02:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:232888f7-78bb-4159-87ed-8e99cf7ff63c</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;span&gt;Wael,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Sorry for the delayed response. I cannot think of any explanation for why it fails with larger buffers. The 52833 has a 16 bit wide DMA pointer, so it should have no problem with a 4K buffer. Also, it should not&amp;nbsp;make any difference&amp;nbsp;if the SPIM start task was triggered in SW or in HW by the PPI.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Are you able to check to read out the SPIM registers when it hangs? It would be&amp;nbsp;interesting to know what the&amp;nbsp;RXD.MAXCNT and RXD.AMOUNT registers are set to when this happens.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
[quote user="whazin"]thank again for your reply. I completely understand what mean by not being able to perform my design requirements without cpu intervention. All I&amp;#39;m trying to say is that because of the spec I mentioned, the assumption I made; since no constraints were given with regards to timing between the PPI/SPIM/CPU, one would assume the functionality I was trying to so is a feasible task. I think the spec needs to be updated to highlight the timing shortcomings I encountered.&amp;nbsp;[/quote]
&lt;p&gt;I agree it&amp;nbsp;may make sense to include a section&amp;nbsp;with&amp;nbsp;best practices when it comes to the use of the PPI. I will report this as a feature request/improvement internally.&lt;/p&gt;
[quote user="whazin"]I have already implemented the timing fix last week using a 16us delay and it works as expected. Not sure how to implement a spim callback post&amp;nbsp;a ppi transaction. I would like to see a piece of code to show how to implement that if possible. again, thank you for all your help.[/quote]
&lt;p&gt;PPI is more suitable when you want to perform a repeated transfer. For single transfers such as writing dummy bytes to wake up the fram, or to set the WREN, I think it&amp;#39;s better to not use PPI at all.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/408408?ContentTypeID=1</link><pubDate>Tue, 07 Feb 2023 00:32:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:67c304a7-6986-4063-bec4-70c78a9e1ef5</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;hi Vidar,&lt;/p&gt;
&lt;p&gt;one last question, why am I not able to receive 4K bytes via the spim 1 bus, NOT using PPI? it seems to hang. when I lower the rx value to something below or equal to 255, it works.&amp;nbsp; your help will be greatly appreciated.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/408341?ContentTypeID=1</link><pubDate>Mon, 06 Feb 2023 15:16:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e0ccec4f-6bb0-46b8-9fe8-ae3cbced17c5</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;thank again for your reply. I completely understand what mean by not being able to perform my design requirements without cpu intervention. All I&amp;#39;m trying to say is that because of the spec I mentioned, the assumption I made; since no constraints were given with regards to timing between the PPI/SPIM/CPU, one would assume the functionality I was trying to so is a feasible task. I think the spec needs to be updated to highlight the timing shortcomings I encountered.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I have already implemented the timing fix last week using a 16us delay and it works as expected. Not sure how to implement a spim callback post&amp;nbsp;a ppi transaction. I would like to see a piece of code to show how to implement that if possible. again, thank you for all your help.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Wael&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407978?ContentTypeID=1</link><pubDate>Fri, 03 Feb 2023 11:18:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8e4c1655-d68b-4547-adcc-6716e2ac4106</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;What I meant to say is that&amp;nbsp;our PPI and DMA do&amp;nbsp;not offer the&amp;nbsp;flexibility needed to perform all&amp;nbsp;your SPI transactions in HW without CPU involvement, not that you could have used the PPI differently. Because even with double buffering, you still need the CPU to update the buffer pointers.&amp;nbsp;A task which is not synchronized to your TIMER/PPI&amp;nbsp;processes&amp;nbsp;running in the background.&lt;/p&gt;
&lt;p&gt;The EasyDMA array list feature coupled with a TIMER and PPI works great when you want to perform repeated SPI transfers in the background (each array element must be of the same size). For instance, when sampling a high-speed ADC or refreshing a display.&amp;nbsp;&lt;span style="font-family:inherit;"&gt;PPI has many other uses too. Often it is used to trigger a task with&amp;nbsp;consistent timing (e.g. for bit banging a serial protocol). It can also be&amp;nbsp;useful for&amp;nbsp;reducing the number of interrupts in CPU bound applications.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
[quote user="whazin"]How else do you suggest to use the CPU more?&amp;nbsp;[/quote]
&lt;p&gt;You could for instance enable the SPIM callback and schedule&amp;nbsp;subsequent transfers from there, but this would require major changes to your design, which I can understand is not desirable at this point.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:inherit;"&gt;As a workaround, maybe you can add a delay between step 4) and 5) like&amp;nbsp;the one you had on step 3? Alternatively, try to change the WREN transaction as I suggested in my previous reply.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:inherit;"&gt;Regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:inherit;"&gt;&lt;span style="font-family:inherit;"&gt;Vidar&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407856?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 20:23:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:61edc4dc-4550-4115-9df7-abf6c161948d</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m not sure I fully understand by what you mean when you say:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;It will&amp;nbsp;not be possible to completely offload&amp;nbsp;the CPU with PPI/DMA in this case&amp;nbsp;because the transfers have varying lengths.&amp;nbsp;&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This is from the 52833 product spec....&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;The .PTR and .MAXCNT registers are double-buffered. They can be updated and prepared for the next transmission immediately after having received the STARTED event.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;a href="https://infocenter.nordicsemi.com/index.jsp?topic=%2Fdrivers_nrfx_v2.8.0%2Fgroup__nrfx__gpiote.html"&gt;https://infocenter.nordicsemi.com/index.jsp?topic=%2Fdrivers_nrfx_v2.8.0%2Fgroup__nrfx__gpiote.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;This is exactly what I&amp;#39;m doing!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;How else am I suppose to update these pointers aside from an ISR? is there any other way?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;what am I missing and what is the point of the PPI if this can&amp;#39;t be done?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;How else do you suggest to use the CPU more?&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I agree with your edit and will update that.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I really appreciate&amp;nbsp;your help and not trying to sound upset but I am a little frustrated. I need to put this issue behind me and any help will be greatly appreciated.&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 again,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Wael&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407853?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 19:57:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:246aa418-ff9f-43c5-9aa6-c729131ef632</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;The problem as I see it is that you need to rely on the timer ISR to set up&amp;nbsp;your transfers. Whether&amp;nbsp;the timer ISR will be serviced in time depends on the interrupt latency, if the IRQ&amp;nbsp;becomes blocked by other interrupts in the system, and the time it takes to complete&amp;nbsp;a current ongoing SPI transfer.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It will&amp;nbsp;not be possible to completely offload&amp;nbsp;the CPU with PPI/DMA in this case&amp;nbsp;because the transfers have varying lengths. While I can understand why you want to&amp;nbsp;leverage the PPI to optimize&amp;nbsp;performance, I do think&amp;nbsp;this implementation would have benefited by using the CPU more.&amp;nbsp;This would&amp;nbsp;have made it easier to control the transfer sequences and reduced the overall complexity. I am not&amp;nbsp;sure if the PPI will lead to any noticeable power savings either considering how &amp;quot;cheap&amp;quot; CPU processing has become.&lt;/p&gt;
[quote user="whazin"]I also tried your suggestion to to do a FRAM read which requires 4 bytes(1 byte command, 3 byte address), I see what I would expect from this timing issue,[/quote]
&lt;p&gt;Sorry, what I meant to suggest was that you changed your WREN transaction to include 10 RX bytes. I am not sure if your FRAM IC will like this, but it should increase the transfer time, at least.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;void fram_spim_start_count_ppi_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
{
    uint32_t timer_value = 0;
    uint8_t CMD_WRITE_ENABLE;
    uint8_t CMD_HIBERNATE;
    uint32_t dummy[10];

    if(event_type == NRF_TIMER_EVENT_COMPARE0) // for 2nd fram write
    {
        timer_value = nrfx_timer_capture_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL0);
        CMD_WRITE_ENABLE = ENUM_TO_UINT8(FRAM_CMD_WRITE_ENABLE);
        spim1_fram.p_reg-&amp;gt;TXD.PTR = (uint32_t)&amp;amp;CMD_WRITE_ENABLE;
        spim1_fram.p_reg-&amp;gt;RXD.PTR = &amp;amp;dummy;
        spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = 1;
        spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 10; 
       // LOG_INF(&amp;quot;Setup for 2nd fram write.........&amp;quot;);

        //nrfx_timer_clear(&amp;amp;m_imu_acq_cnt_timer);
        // LOG_HEXDUMP_INF(IMU_Recv_ArrayList-&amp;gt;buffer,364,&amp;quot;received FIFO Data&amp;quot;);
    }
    else if(event_type == NRF_TIMER_EVENT_COMPARE1) // for 3rd fram write
    ...&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Edit:&amp;nbsp;&lt;/strong&gt;forgot to add that you should consider placing the CMD_WRITE_ENABLE and CMD_HIBERNATE variable in static memory. Otherwise, there is a risk that they can become overwritten&amp;nbsp;by another interrupt before the SPI has&amp;nbsp;transferred the command. The same goes for my dummy array, except the consequences may be worse as it can potentially lead to stack corruption.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407851?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 18:59:27 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:d48a7acd-f673-4531-8ba5-b12c12cdd92d</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;thanks for your reply. The issue is exactly as you describe and what I tried to do also, lol.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;quot;race where PPI is triggering the FRAM SPI start task before the CPU has had time to update the transaction details from your timer ISR. Thus, causing the WREN byte to be sent twice instead of proceeding with IMU data transfer as it is supposed to.&amp;quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And that is what I am seeing on the oscilloscope. when I have the 2nd SPIM transaction configured for 10 bytes with 8 MHz speed, I see the following which is what I expect to see:&lt;/p&gt;
&lt;p&gt;3500 byte transfer from IMU -&amp;gt; 4 byte &lt;span&gt;transfer&amp;nbsp;&lt;/span&gt;to FRAM -&amp;gt; 8ms time delay -&amp;gt; &lt;strong&gt;10 byte transfer to FRAM&lt;/strong&gt; -&amp;gt; 3500 byte &lt;span&gt;transfer&amp;nbsp;&lt;/span&gt;to FRAM -&amp;gt; 1 byte &lt;span&gt;transfer&amp;nbsp;to&amp;nbsp;&lt;/span&gt;FRAM&lt;/p&gt;
&lt;p&gt;if I change the&amp;nbsp;&lt;span&gt;&amp;nbsp;&amp;quot;&lt;/span&gt;&lt;strong&gt;10 byte transfer to FRAM&amp;quot;&amp;nbsp;&lt;/strong&gt;to anything less than 10, say X, I would see the following:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;3500 byte transfer from IMU -&amp;gt; 4 byte&amp;nbsp;&lt;/span&gt;&lt;span&gt;transfer&amp;nbsp;&lt;/span&gt;&lt;span&gt;to FRAM -&amp;gt; 8ms time delay -&amp;gt;&amp;nbsp;X&lt;/span&gt;&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;span&gt;&amp;nbsp;-&amp;gt; X&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;-&amp;gt; X&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;the only way to get the &amp;quot;X&amp;quot; number to be 1 as I need is to have the FRAM SPIM bus configured to 1 MHz.&lt;/p&gt;
&lt;p&gt;so clearly the timer ISR to update the transaction details is not getting triggered. This is also happening on subsequent transactions.&lt;/p&gt;
&lt;p&gt;I also tried your suggestion to to do a FRAM read which requires 4 bytes(1 byte command, 3 byte address), I see what I would expect from this timing issue,&lt;/p&gt;
&lt;p&gt;&lt;span&gt;3500 byte transfer from IMU -&amp;gt; 4 byte&amp;nbsp;&lt;/span&gt;&lt;span&gt;transfer&amp;nbsp;&lt;/span&gt;&lt;span&gt;to FRAM -&amp;gt; 8ms time delay -&amp;gt;&amp;nbsp;4&lt;/span&gt;&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;span&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;4&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;4&lt;strong&gt;&amp;nbsp;byte transfer to FRAM&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;so my conclusion is that the PPI/SPIM mechanism for multiple transaction is not functioning as intended because of the race condition I am seeing. Therefore, I really need some workaround to&amp;nbsp;get me by. Can you please check internally maybe with the design team to try to get to the bottom of this. can this have something to do with the&amp;nbsp;errata&amp;nbsp;issue?&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Even using the 1MHz SPIM speed leaves me extremely&amp;nbsp;uncomfortable as I do not know if more logic added to my application may increase the likelihood of the race condition.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;as always, your help will be greatly appreciated.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Wael&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;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407828?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 15:01:12 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8d1a82ac-4283-4f8b-8425-11fe4a719dfd</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;I am&amp;nbsp;happy to hear you found the errata which caused the issue. This errata is quite rare and is usually more intermittent due to the accurate timing conditions needed for&amp;nbsp;it&amp;nbsp;to arise.&amp;nbsp;&lt;/p&gt;
[quote user="whazin"]Just confirmed my feeling from my previous post where the time to write one byte(step 4 only from previous post) was creating a timing issue. when I changed that to 10 bytes and the FRAM SPIM freq to 8MHz, it worked. anything under 10 bytes will not. [/quote]
&lt;p&gt;I wonder if the problem&amp;nbsp;could be caused by a&amp;nbsp;race where PPI is triggering the FRAM SPI start task before the CPU has had time to update the transaction details from your timer ISR. Thus, causing the WREN byte to be sent twice instead of proceeding with IMU data transfer as it is supposed to.&amp;nbsp;Or does this not&amp;nbsp;match with what you are seeing on&amp;nbsp;the oscilloscope?&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As a test, maybe you can read out 10 dummy bytes in the WREN transaction to see if it has the same effect as sending 10 bytes.&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407660?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 00:49:43 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:cef5e7f0-d52b-4464-ba47-641ba5a6adbb</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;Hi&amp;nbsp;&lt;span&gt;Vidar,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Just confirmed my feeling from my previous post where the time to write one byte(step 4 only from previous post) was creating a timing issue. when I changed that to 10 bytes and the FRAM SPIM freq to 8MHz, it worked. anything under 10 bytes will not. Not sure how I&amp;#39;m suppose to handle this issue. I need to only write one byte, which is a command, and the CS line needs to be toggled. Your help will be greatly appreciated.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Wael&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407659?ContentTypeID=1</link><pubDate>Thu, 02 Feb 2023 00:16:39 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e734da49-49ad-4641-985d-0550cea5dca3</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;hi Vidar,&lt;/p&gt;
&lt;p&gt;thanks for the reply. I did try TIMER SHUTDOWN and that did not work. what did work was the following:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;// nRF52833 Revision 2 Errata&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;// [246] System: Intermittent extra current consumption when going to sleep&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;// Extra current consumption in the range of 350 &amp;micro;A when in System On Idle.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;// A high-speed peripheral (CPU for example) accesses a RAM block which is being accessed by &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;// a low-speed peripheral through the DMA bus, with a specific timing, and the high-speed peripheral has&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;// higher priority than the low-speed peripheral.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;// NOTE: Workaround consequences: Up to 40 &amp;micro;A current increase when the 16 MHz clock is used.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;*(&lt;/span&gt;&lt;span&gt;volatile&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uint32_t&lt;/span&gt;&lt;span&gt; *)&lt;/span&gt;&lt;span&gt;0x4007AC84ul&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;0x00000002ul&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;I placed that line of code in my main function and the current went back down close to what&amp;#39;s&amp;nbsp;expected. still need to figure out where about 20uA is going.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;having said that, I now have the issue where if I increase my FRAM SPIM frequency to anything above 1 MHz, the PPI logic does not work. IMU SPIM frequency is set to 8 MHz. recall that the IMU and FRAM are on separate&amp;nbsp;buses.&amp;nbsp;recall, my app does the following using PPI&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;p&gt;the PPI configuration is as follow:&lt;/p&gt;
&lt;p&gt;1) Upon receiving a GPIOTE trigger from an IMU(every 8.3 seconds), read its data (this is operating on a dedicated spi bus, SPIM0) (~3500 bytes)&lt;/p&gt;
&lt;p&gt;2)&amp;nbsp;write a dummy read command to an FRAM IC to wake it up from hibernate state (SPIM1 bus)(4 bytes)&lt;/p&gt;
&lt;p&gt;3) trigger timer for 8ms from the start of the FRAM SPIM transaction(step 2)(8ms is the period for FRAM to become stable from hibernate state)&lt;/p&gt;
&lt;p&gt;4) write the WREN(write enable) command(1 Byte) to the FRAM upon completion of the 8ms timer&lt;/p&gt;
&lt;p&gt;5) write the (write command, address, data) to the FRAM(~3500 bytes)&lt;/p&gt;
&lt;p&gt;6) write the hibernate command to the FRAM(1 byte)&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;so when the FRAM SPIM freq=1 MHz, everything looks good and I can see things operating as expected on a scope.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;when I change the freq. to say 2 MHz or more, it&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;does everything as expected with the exception&amp;nbsp;of step 5. it only writes ONE byte. its seems as though the fram_spim_start_count_ppi_timer_event_handler is not getting executed on when the count=2(to setup for the 3rd FRAM write) to update the SPIM ptr and tx/rx parameters. I am assuming the 2nd spi transaction(which is one byte) got executed so fast that the spi parameters never get updated for the next transaction. Not sure on how to handle this issue. I need the speed to save on power. any thoughts and/or hints? As always, your help would be greatly appreciated.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;Regards,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;span&gt;Wael&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407529?ContentTypeID=1</link><pubDate>Wed, 01 Feb 2023 12:50:23 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:50dfd0e1-32c0-413d-b621-37d580b7e9e0</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;Sorry, I thought you were using the nRF5340 for some reason. A current draw in the 5-600 uA range on the nRF52 series usually indicates that a peripheral keep requesting the 16 MHz clock. For instance, a running TIMER instance. However,&amp;nbsp;this should have led to a more constant draw, not like the waveform shown in your screenshot.&lt;/p&gt;
&lt;p&gt;The DMA current is closer to 2 mA with VDD @ 1.8 v. But as you said, this current should only be seen during transmissions when the CPU is idle.&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Either way, to try narrow down the problem, could try to issue the TIMER SHUTDOWN tasks for your timers after the transaction is complete by calling &lt;a href="https://github.com/zephyrproject-rtos/hal_nordic/blob/master/nrfx/drivers/src/nrfx_timer.c#L149"&gt;nrfx_timer_disable&lt;/a&gt;&lt;span&gt;(). Also, is it possible to power off the IMU and FRAM IC (make sure you do not have any floating inputs if you do this)?&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Best regards,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Vidar&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407439?ContentTypeID=1</link><pubDate>Tue, 31 Jan 2023 22:26:03 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:28d2b02c-b17a-47e3-8c85-70fe0fab3de0</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;Hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thank you for your suggestion, but I am not using the 5340 which is what your link, I am using 52833 and SDK 2.0.0.&lt;/p&gt;
&lt;p&gt;with that said, here is my function that initializes the GPIOTE pin&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void configure_imu_int1_gpiote(void)
{
    nrfx_err_t err = NRFX_SUCCESS;

     __ASSERT (!nrfx_gpiote_is_init(),&amp;quot;nrfx_gpiote_is_init Failed&amp;quot;);
    
    static const nrfx_gpiote_input_config_t input_config = {
		.pull = NRF_GPIO_PIN_PULLDOWN,
	};

	const nrfx_gpiote_trigger_config_t trigger_config = {
		.trigger = NRFX_GPIOTE_TRIGGER_LOTOHI,
		.p_in_channel = NULL, //&amp;amp;in_channel,
	};

    err = nrfx_gpiote_input_configure(IMU_INT1_PIN,
					  &amp;amp;input_config,
					  &amp;amp;trigger_config,
					  NULL);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;Failed to nrfx_gpiote_input_configure, error: 0x%08X&amp;quot;, err);
		return;
	}

    //nrfx_gpiote_in_event_enable(IMU_INT1_PIN, false);
    nrfx_gpiote_trigger_enable(IMU_INT1_PIN, false);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I am NOT using IN Event per my configuration. Please note this power issue only happens after all configurations and ONLY after the IMU int pin is triggered. so after power on for approx 8 seconds, the current level is as expected. only after the int trigger this issue happens. again, this issue is driving me crazy and eating lots of my time. any other suggestions please? as always, your help is greatly appreciated.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;here is some of my code&lt;/p&gt;
&lt;p&gt;timers setup&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;
static const nrfx_timer_t m_imu_acq_cnt_timer = NRFX_TIMER_INSTANCE(1);
static const nrfx_timer_t m_fram_hibernate_delay_timer = NRFX_TIMER_INSTANCE(2);
static const nrfx_timer_t m_fram_spim_start_cnt_timer = NRFX_TIMER_INSTANCE(3);
static const nrfx_timer_t m_fram_spim_end_cnt_timer = NRFX_TIMER_INSTANCE(4);


void configure_imu_ppi_timer(void)
{
    nrfx_err_t err = NRFX_SUCCESS;


    // configure imu/ppi timer
    nrfx_timer_config_t timer_cfg_0 = NRFX_TIMER_DEFAULT_CONFIG;
    timer_cfg_0.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
    //IRQ_DIRECT_CONNECT(TIMER1_IRQn, 0, nrfx_timer_1_irq_handler, 0);

    IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer1)), 
		    DT_IRQ(DT_NODELABEL(timer1), priority),
		    nrfx_isr, nrfx_timer_1_irq_handler, 0);

    if(!nrfx_timer_is_enabled(&amp;amp;m_imu_acq_cnt_timer)) {
        err = nrfx_timer_init(&amp;amp;m_imu_acq_cnt_timer,
                                    &amp;amp;timer_cfg_0,
                                    imu_ppi_timer_event_handler);    
        if (err != NRFX_SUCCESS) {
		    LOG_ERR(&amp;quot;nrf_drv_timer_init error: %08x&amp;quot;, err);
		    return;
	    }                              
    }

    nrfx_timer_extended_compare(&amp;amp;m_imu_acq_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   1 /*IMU_SPIM_TRANSFER_COUNT*/,
                                   NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, 
                                   true);

    if(!nrfx_timer_is_enabled(&amp;amp;m_imu_acq_cnt_timer))
        nrfx_timer_enable(&amp;amp;m_imu_acq_cnt_timer);    
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void configure_fram_ppi_timer()
{
    nrfx_err_t err = NRFX_SUCCESS;

    IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer2)), 
		    DT_IRQ(DT_NODELABEL(timer2), priority),
		    nrfx_isr, nrfx_timer_2_irq_handler, 0);

    // the fram hibernate timer ~6ms
    nrfx_timer_config_t timer_cfg_1 = NRFX_TIMER_DEFAULT_CONFIG;
    timer_cfg_1.mode = NRF_TIMER_MODE_TIMER;
    timer_cfg_1.frequency = NRF_TIMER_FREQ_31250Hz;
    //timer_cfg_1.bit_width = NRF_TIMER_BIT_WIDTH_32;

    if(!nrfx_timer_is_enabled(&amp;amp;m_fram_hibernate_delay_timer)) {
        err = nrfx_timer_init(&amp;amp;m_fram_hibernate_delay_timer,
                                    &amp;amp;timer_cfg_1,
                                    fram_ppi_timer_event_handler);    
        if (err != NRFX_SUCCESS) {
		    LOG_ERR(&amp;quot;nrf_drv_timer_init error: %08x&amp;quot;, err);
		    return;
	    }                              
    }
    uint32_t ticks = nrfx_timer_ms_to_ticks(&amp;amp;m_fram_hibernate_delay_timer, 8);
    nrfx_timer_extended_compare(&amp;amp;m_fram_hibernate_delay_timer,
                                   NRF_TIMER_CC_CHANNEL2,
                                   ticks,
                                   (NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE2_STOP_MASK), 
                                   false);    

    nrfx_timer_clear(&amp;amp;m_fram_hibernate_delay_timer);
    //  if(!nrfx_timer_is_enabled(&amp;amp;m_fram_hibernate_delay_timer))
    //  {
    //     nrfx_timer_enable(&amp;amp;m_fram_hibernate_delay_timer);
    //     nrfx_timer_pause(&amp;amp;m_fram_hibernate_delay_timer);
    //     nrfx_timer_clear(&amp;amp;m_fram_hibernate_delay_timer);
    //  }

    IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer3)), 
		    DT_IRQ(DT_NODELABEL(timer3), priority),
		    nrfx_isr, nrfx_timer_3_irq_handler, 0);

    // configure fram spim start count ppi timer
    nrfx_timer_config_t timer_cfg_2 = NRFX_TIMER_DEFAULT_CONFIG;
    timer_cfg_2.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
    if(!nrfx_timer_is_enabled(&amp;amp;m_fram_spim_start_cnt_timer)) {
        err = nrfx_timer_init(&amp;amp;m_fram_spim_start_cnt_timer,
                                    &amp;amp;timer_cfg_2,
                                    fram_spim_start_count_ppi_timer_event_handler);    
        if (err != NRFX_SUCCESS) {
		    LOG_ERR(&amp;quot;nrf_drv_timer_init error: %08x&amp;quot;, err);
		    return;
	    }                              
    }
    nrfx_timer_compare(&amp;amp;m_fram_spim_start_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   1 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                   true);

    nrfx_timer_compare(&amp;amp;m_fram_spim_start_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL1,
                                   2 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                   true);

    nrfx_timer_compare(&amp;amp;m_fram_spim_start_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL2,
                                   3 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                   true);
    nrfx_timer_extended_compare(&amp;amp;m_fram_spim_start_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL3,
                                   4 /*FRAM_SPIM_TRANSFER_COUNT*/, 
                                   NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK,
                                   true);                               

    if(!nrfx_timer_is_enabled(&amp;amp;m_fram_spim_start_cnt_timer))
        nrfx_timer_enable(&amp;amp;m_fram_spim_start_cnt_timer);  

    nrfx_timer_clear(&amp;amp;m_fram_spim_start_cnt_timer);

    IRQ_CONNECT(DT_IRQN(DT_NODELABEL(timer4)), 
		    DT_IRQ(DT_NODELABEL(timer4), priority),
		    nrfx_isr, nrfx_timer_4_irq_handler, 0);

    // configure fram spim end count ppi timer
    nrfx_timer_config_t timer_cfg_3 = NRFX_TIMER_DEFAULT_CONFIG;
    timer_cfg_3.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER; //NRF_TIMER_MODE_COUNTER;
    if(!nrfx_timer_is_enabled(&amp;amp;m_fram_spim_end_cnt_timer)) {
        err = nrfx_timer_init(&amp;amp;m_fram_spim_end_cnt_timer,
                                    &amp;amp;timer_cfg_3,
                                    fram_spim_end_count_ppi_timer_event_handler);    
        if (err != NRFX_SUCCESS) {
		    LOG_ERR(&amp;quot;nrf_drv_timer_init error: %08x&amp;quot;, err);
		    return;
	    }                              
    }
    // we start the 3rd FRAM write
    nrfx_timer_compare(&amp;amp;m_fram_spim_end_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL0,
                                   2 /*SPIM END EVENT COUNT*/,  
                                   false);
    // we start the 4th FRAM write
    nrfx_timer_compare(&amp;amp;m_fram_spim_end_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL1,
                                   3 /*SPIM END EVENT COUNT*/,
                                   false);
    // we want to clear the timer on the end of the 4th spim end 
     nrfx_timer_extended_compare(&amp;amp;m_fram_spim_end_cnt_timer,
                                   NRF_TIMER_CC_CHANNEL2,
                                   4 /*SPIM END EVENT COUNT*/,
                                   NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK,  
                                   false);
                             
    if(!nrfx_timer_is_enabled(&amp;amp;m_fram_spim_end_cnt_timer))
        nrfx_timer_enable(&amp;amp;m_fram_spim_end_cnt_timer);     

    nrfx_timer_clear(&amp;amp;m_fram_spim_end_cnt_timer); 

}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void fram_spim_start_count_ppi_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
{
    uint32_t timer_value = 0;
    uint8_t CMD_WRITE_ENABLE;
    uint8_t CMD_HIBERNATE;

    if(event_type == NRF_TIMER_EVENT_COMPARE0) // for 2nd fram write
    {
        timer_value = nrfx_timer_capture_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL0);
        CMD_WRITE_ENABLE = ENUM_TO_UINT8(FRAM_CMD_WRITE_ENABLE);
        spim1_fram.p_reg-&amp;gt;TXD.PTR = (uint32_t)&amp;amp;CMD_WRITE_ENABLE;
        spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = 1;
        spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 0; 
       // LOG_INF(&amp;quot;Setup for 2nd fram write.........&amp;quot;);

        //nrfx_timer_clear(&amp;amp;m_imu_acq_cnt_timer);
        // LOG_HEXDUMP_INF(IMU_Recv_ArrayList-&amp;gt;buffer,364,&amp;quot;received FIFO Data&amp;quot;);
    }
    else if(event_type == NRF_TIMER_EVENT_COMPARE1) // for 3rd fram write
    {
        timer_value = nrfx_timer_capture_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL1);
        IMU_RX_BUFFER[0] = ENUM_TO_UINT8(FRAM_CMD_WRITE_DATA);
        IMU_RX_BUFFER[1] = (m_current_fram_addr &amp;amp; 0x00FF0000) &amp;gt;&amp;gt; 16;
        IMU_RX_BUFFER[2] = (m_current_fram_addr &amp;amp; 0x0000FF00) &amp;gt;&amp;gt; 8;
        IMU_RX_BUFFER[3] = (m_current_fram_addr &amp;amp; 0x000000FF);

        m_current_fram_addr += ADL_MODE_BUFFER_IMU_RXD_SIZE;

        spim1_fram.p_reg-&amp;gt;TXD.PTR = (uint32_t)&amp;amp;IMU_RX_BUFFER;
        spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = ADL_MODE_BUFFER_IMU_RXD_SIZE + 4;
        spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 0;
       // LOG_INF(&amp;quot;Setup for 3rd fram write.........&amp;quot;);
    }
    else if(event_type == NRF_TIMER_EVENT_COMPARE2) // for 4th fram write
    {
        timer_value = nrfx_timer_capture_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL2);
        CMD_HIBERNATE = ENUM_TO_UINT8(FRAM_CMD_HIBERNATE);
        spim1_fram.p_reg-&amp;gt;TXD.PTR = (uint32_t)&amp;amp;CMD_HIBERNATE;
        spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = 1;
        spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 0; 
       // LOG_INF(&amp;quot;Setup for 4th fram write.........&amp;quot;);
    }
    else if(event_type == NRF_TIMER_EVENT_COMPARE3) // for 1st fram write
    {
        timer_value = nrfx_timer_capture_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL3);
      //  nrfx_timer_clear(&amp;amp;m_fram_spim_start_cnt_timer);
        spim1_fram.p_reg-&amp;gt;TXD.PTR = (uint32_t)&amp;amp;FRAM_ADL_TX_ArrayList;
        spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = 4;
        spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 0; 
        //LOG_INF(&amp;quot;Setup for 1st fram write.........&amp;quot;);
    }
    else
        LOG_INF(&amp;quot;Unknown timer event...............&amp;quot;);
}
void fram_spim_end_count_ppi_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
{
    if(event_type == NRF_TIMER_EVENT_COMPARE0) // the 3rd spim end trigger
    {
        LOG_INF(&amp;quot;2nd spim end trigger.........&amp;quot;);
    }
    else if(event_type == NRF_TIMER_EVENT_COMPARE1) // the 3rd spim end trigger
    {
        //nrfx_timer_clear(&amp;amp;m_fram_spim_end_cnt_timer);
        LOG_INF(&amp;quot;3rd spim end trigger.........&amp;quot;);
    }
    else
        LOG_INF(&amp;quot;Undefind FRAM SPIM End Count Event Type.........&amp;quot;);
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void setup_ADL_mode_imu_ppi_spi_transfer(void)
{
    nrfx_err_t err = NRFX_SUCCESS;
  
    // IMU SPI setup
    spim0_imu.p_reg-&amp;gt;TXD.LIST = SPIM_TXD_LIST_LIST_ArrayList;
    spim0_imu.p_reg-&amp;gt;RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;
    spim0_imu.p_reg-&amp;gt;TXD.MAXCNT = ADL_MODE_BUFFER_IMU_TXD_SIZE;
    spim0_imu.p_reg-&amp;gt;RXD.MAXCNT = ADL_MODE_BUFFER_IMU_RXD_SIZE; 
    nrfx_spim_xfer_desc_t imu_xfer = NRFX_SPIM_XFER_TRX((uint8_t*)IMU_ChannelSwitch_ArrayList,
                                                                        ADL_MODE_BUFFER_IMU_TXD_SIZE,
                                                                        (uint8_t*)&amp;amp;IMU_RX_BUFFER[4],
                                                                        ADL_MODE_BUFFER_IMU_RXD_SIZE);

    uint32_t flags = (NRFX_SPIM_FLAG_HOLD_XFER
                      |NRFX_SPIM_FLAG_TX_POSTINC
                      |NRFX_SPIM_FLAG_RX_POSTINC
                      |NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER
                      |NRFX_SPIM_FLAG_REPEATED_XFER);
                      
    err = nrfx_spim_xfer(&amp;amp;spim0_imu, &amp;amp;imu_xfer, flags);
    if (err != NRFX_SUCCESS) {
        LOG_INF(&amp;quot;nrfx_spim_xfer error: %08x&amp;quot;, err);
		LOG_ERR(&amp;quot;nrfx_spim_xfer error: %08x&amp;quot;, err);
		return;
	}
}

void setup_ADL_mode_fram_ppi_spi_transfer(void)
{
    nrfx_err_t err = NRFX_SUCCESS;
  
    uint32_t flags = (NRFX_SPIM_FLAG_HOLD_XFER
                      |NRFX_SPIM_FLAG_TX_POSTINC
                      |NRFX_SPIM_FLAG_RX_POSTINC
                      |NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER
                      |NRFX_SPIM_FLAG_REPEATED_XFER);
                      
    // FRAM SPI setup
    spim1_fram.p_reg-&amp;gt;TXD.LIST = SPIM_TXD_LIST_LIST_ArrayList;
    spim1_fram.p_reg-&amp;gt;RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;
    spim1_fram.p_reg-&amp;gt;TXD.MAXCNT = 4;
    spim1_fram.p_reg-&amp;gt;RXD.MAXCNT = 0; 
    nrfx_spim_xfer_desc_t fram_xfer = NRFX_SPIM_XFER_TRX((uint8_t*)FRAM_ADL_TX_ArrayList,
                                                                        4,
                                                                        NULL,
                                                                        0);                  
    err = nrfx_spim_xfer(&amp;amp;spim1_fram, &amp;amp;fram_xfer, flags);
    if (err != NRFX_SUCCESS) {
        LOG_INF(&amp;quot;nrfx_spim_xfer error: %08x&amp;quot;, err);
		LOG_ERR(&amp;quot;nrfx_spim_xfer error: %08x&amp;quot;, err);
		return;
	}
}&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="text"&gt;void start_ADL_mode_acq()
{
    //setup_imu_ppi_spi_transfer();
    setup_ADL_mode_imu_ppi_spi_transfer();
    setup_ADL_mode_fram_ppi_spi_transfer();
	nrfx_ppi_group_enable(imu_trigger_group);
    
    // k_timer_stop(&amp;amp;m_start_imu_conv_timer_id);
    // k_timer_start(&amp;amp;m_start_imu_conv_timer_id, K_MSEC(1010), K_NO_WAIT);
    LOG_INF(&amp;quot;started ADL Mode Acquisition...............&amp;quot;);
}

void ADL_mode_ppi_init(void)
{
    nrfx_err_t err = NRFX_SUCCESS;

    nrf_ppi_channel_t imu_int1_trigger_ppi_channel;
    nrf_ppi_channel_t imu_count_ppi_channel;
    nrf_ppi_channel_t imu_trigger_disable_channel;
    nrf_ppi_channel_t fram_spim_end_trigger_ppi_channel;
    nrf_ppi_channel_t fram_spim_start_trigger_ppi_channel;
    nrf_ppi_channel_t fram_hibernate_timer_ppi_channel;
    nrf_ppi_channel_t fram_spim_start_count_ppi_channel;
    nrf_ppi_channel_t fram_spim_end_count_ppi_channel;

    nrf_ppi_channel_t fram_1st_write_ppi_channel;
    nrf_ppi_channel_t fram_2nd_write_ppi_channel;
    nrf_ppi_channel_t fram_3rd_write_ppi_channel;
    nrf_ppi_channel_t fram_4th_write_ppi_channel;

    uint32_t imu_int1_trigger_pin_evt_addr;
    uint32_t imu_spim_start_task_addr;
    uint32_t imu_spim_end_evt_addr;
    uint32_t timer_count_task_addr;
    uint32_t timer_cc_event_addr;
    uint32_t group_imu_disable_task_addr;
    
    uint32_t imu_ss_pin_toggle_task_addr;
    uint32_t fram_timer_spim_start_count_task_addr;
    uint32_t fram_timer_spim_end_count_task_addr;
    uint32_t fram_timer_spim_start_cc1_event_addr;
    uint32_t fram_timer_spim_end_cc2_event_addr;
    uint32_t fram_timer_spim_end_cc3_event_addr;
   
    uint32_t fram_spim_start_task_addr;
    uint32_t fram_spim_end_evt_addr;
    uint32_t fram_spim_started_evt_addr;
    uint32_t fram_ss_pin_toggle_task_addr;
    // uint32_t group_fram_disable_task_addr;

    uint32_t fram_hibernate_timer_start_task_addr;
    uint32_t fram_hibernate_timer_cc_evt_addr;   

    err = nrfx_ppi_channel_alloc(&amp;amp;imu_int1_trigger_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}

    // this ppi channel will toggle the fram spim cs at the end of the transaction to the fram
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_spim_end_trigger_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_spim_start_trigger_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_hibernate_timer_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;imu_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}  
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_spim_start_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_spim_end_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_1st_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_2nd_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_3rd_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;fram_4th_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_alloc(&amp;amp;imu_trigger_disable_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_alloc error: %08x&amp;quot;, err);
		return;
	}

    err = nrfx_ppi_group_alloc(&amp;amp;imu_trigger_group);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_group_alloc error: %08x&amp;quot;, err);
		return;
	}

    imu_int1_trigger_pin_evt_addr   = nrfx_gpiote_in_event_addr_get(IMU_INT1_PIN);
    imu_spim_start_task_addr        = nrf_spim_task_address_get(spim0_imu.p_reg, NRF_SPIM_TASK_START);
    imu_spim_end_evt_addr           = nrf_spim_event_address_get(spim0_imu.p_reg, NRF_SPIM_EVENT_END);
    timer_count_task_addr       = nrfx_timer_task_address_get(&amp;amp;m_imu_acq_cnt_timer, NRF_TIMER_TASK_COUNT);
    timer_cc_event_addr         = nrfx_timer_compare_event_address_get(&amp;amp;m_imu_acq_cnt_timer, NRF_TIMER_CC_CHANNEL0);
    // group_disable_task_addr = (uint32_t) nrf_ppi_task_group_disable_address_get(trigger_group);
    group_imu_disable_task_addr = (uint32_t) nrfx_ppi_task_addr_group_disable_get(imu_trigger_group);
    
    fram_spim_start_task_addr    = nrf_spim_task_address_get(spim1_fram.p_reg, NRF_SPIM_TASK_START); 
    fram_spim_end_evt_addr       = nrf_spim_event_address_get(spim1_fram.p_reg, NRF_SPIM_EVENT_END);
    fram_spim_started_evt_addr   = nrf_spim_event_address_get(spim1_fram.p_reg, NRF_SPIM_EVENT_STARTED);
 //   group_fram_disable_task_addr = (uint32_t) nrfx_ppi_task_addr_group_disable_get(fram_trigger_group);
    
    fram_hibernate_timer_start_task_addr = nrfx_timer_task_address_get(&amp;amp;m_fram_hibernate_delay_timer, NRF_TIMER_TASK_START);
    fram_hibernate_timer_cc_evt_addr     = nrfx_timer_compare_event_address_get(&amp;amp;m_fram_hibernate_delay_timer, NRF_TIMER_CC_CHANNEL2);

    fram_timer_spim_start_count_task_addr = nrfx_timer_task_address_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_TASK_COUNT);
    fram_timer_spim_end_count_task_addr = nrfx_timer_task_address_get(&amp;amp;m_fram_spim_end_cnt_timer, NRF_TIMER_TASK_COUNT);

    //fram_timer_spim_start_cc1_event_addr         = nrfx_timer_compare_event_address_get(&amp;amp;m_fram_spim_start_cnt_timer, NRF_TIMER_CC_CHANNEL0);
    fram_timer_spim_end_cc2_event_addr         = nrfx_timer_compare_event_address_get(&amp;amp;m_fram_spim_end_cnt_timer, NRF_TIMER_CC_CHANNEL0);
    fram_timer_spim_end_cc3_event_addr         = nrfx_timer_compare_event_address_get(&amp;amp;m_fram_spim_end_cnt_timer, NRF_TIMER_CC_CHANNEL1);

    // IMU SS
    // The SS pin will be driven by a GPIOTE task.
    // have the ppi spim start/end event control the slave select       
    nrfx_gpiote_out_config_t imu_ss_pin_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
    err = nrfx_gpiote_out_init(IMU_CS_PIN, &amp;amp;imu_ss_pin_config);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_gpiote_out_init error: %08x&amp;quot;, err);
		return;
	}
    imu_ss_pin_toggle_task_addr = nrfx_gpiote_out_task_addr_get(IMU_CS_PIN);

    // FRAM SS
    // The SS pin will be driven by a GPIOTE task.
    // have the ppi spim start/end event control the slave select   
    nrfx_gpiote_out_config_t fram_ss_pin_config = NRFX_GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
    err = nrfx_gpiote_out_init(FRAM_CS_PIN, &amp;amp;fram_ss_pin_config);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_gpiote_out_init error: %08x&amp;quot;, err);
		return;
	}
    fram_ss_pin_toggle_task_addr = nrfx_gpiote_out_task_addr_get(FRAM_CS_PIN);

    // this channel will trigger the imu spim task off the imu int1 pin event 
    err = nrfx_ppi_channel_assign(imu_int1_trigger_ppi_channel,
                                          imu_int1_trigger_pin_evt_addr,
                                          imu_spim_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}

    // fork the imu ss pin off of the start(to assert) of imu spim channel
    err = nrfx_ppi_channel_fork_assign(imu_int1_trigger_ppi_channel, imu_ss_pin_toggle_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_fork_assign error: %08x&amp;quot;, err);
		return;
	}

    err = nrfx_ppi_channel_assign(imu_count_ppi_channel,
                                          imu_spim_end_evt_addr,
                                          timer_count_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    // fork the imu ss pin off of the end of imu spim channel(to de-assert))
    err = nrfx_ppi_channel_fork_assign(imu_count_ppi_channel, imu_ss_pin_toggle_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_fork_assign error: %08x&amp;quot;, err);
		return;
	}
 ////////   
    // first FRAM write. dummy read instruction. toggle ss pin, start spi, toggle ss pin  
    err = nrfx_ppi_channel_assign(fram_1st_write_ppi_channel,
                                          imu_spim_end_evt_addr,
                                          fram_spim_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_assign(fram_spim_start_trigger_ppi_channel,
                                          fram_spim_started_evt_addr,
                                          fram_ss_pin_toggle_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_assign(fram_spim_end_trigger_ppi_channel,
                                          fram_spim_end_evt_addr,
                                          fram_ss_pin_toggle_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    
    // count the FRAM SPI writes off of the SPI start
    err = nrfx_ppi_channel_assign(fram_spim_start_count_ppi_channel,
                                          fram_spim_started_evt_addr,
                                          fram_timer_spim_start_count_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	} 
    err = nrfx_ppi_channel_assign(fram_spim_end_count_ppi_channel,
                                          fram_spim_end_evt_addr,
                                          fram_timer_spim_end_count_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
   
    // start the FRAM hibernate timer off of the IMU SPI end Event
    err = nrfx_ppi_channel_assign(fram_hibernate_timer_ppi_channel,
                                          imu_spim_end_evt_addr,
                                          fram_hibernate_timer_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    // now we want to start the 2nd, 3rd and 4th FRAM SPI transactions
    // we start the 2nd off of the end of te hibernate timer
    err = nrfx_ppi_channel_assign(fram_2nd_write_ppi_channel,
                                          fram_hibernate_timer_cc_evt_addr,
                                          fram_spim_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_assign(fram_3rd_write_ppi_channel,
                                          fram_timer_spim_end_cc2_event_addr,
                                          fram_spim_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_assign(fram_4th_write_ppi_channel,
                                          fram_timer_spim_end_cc3_event_addr,
                                          fram_spim_start_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}

    err = nrfx_ppi_channel_enable(fram_spim_start_trigger_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_spim_end_trigger_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(imu_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_spim_start_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_spim_end_count_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_1st_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_2nd_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    err = nrfx_ppi_channel_enable(fram_3rd_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
     err = nrfx_ppi_channel_enable(fram_4th_write_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
    
    err = nrfx_ppi_channel_enable(fram_hibernate_timer_ppi_channel);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
		return;
	}
 
    err = nrfx_ppi_channel_assign(imu_trigger_disable_channel,
                                          timer_cc_event_addr,
                                          group_imu_disable_task_addr);
    if (err != NRFX_SUCCESS) {
		LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
		return;
	}
    // err = nrfx_ppi_channel_assign(fram_trigger_disable_channel,
    //                                       timer_fram_cc_event_addr,
    //                                       group_fram_disable_task_addr);
    // if (err != NRFX_SUCCESS) {
	// 	LOG_ERR(&amp;quot;nrfx_ppi_channel_assign error: %08x&amp;quot;, err);
	// 	return;
	// }

  
//    err_code = nrfx_ppi_channel_enable(trigger_ppi_channel);
//    APP_ERROR_CHECK(err_code);
 
//     err = nrfx_ppi_channel_enable(imu_trigger_disable_channel);
//     if (err != NRFX_SUCCESS) {
// 		LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
// 		return;
// 	}
    
    // disable for testing
    // err = nrfx_ppi_channel_enable(fram_trigger_disable_channel);
    // if (err != NRFX_SUCCESS) {
	// 	LOG_ERR(&amp;quot;nrfx_ppi_channel_enable error: %08x&amp;quot;, err);
	// 	return;
	// }

    nrfx_ppi_channel_include_in_group(imu_int1_trigger_ppi_channel, imu_trigger_group);
    // nrfx_ppi_channel_include_in_group(fram_spim_trigger_ppi_channel, fram_trigger_group);
    // nrfx_ppi_channel_include_in_group(fram_spim_end_trigger_ppi_channel, fram_trigger_group);
    
//    nrf_ppi_group_enable(trigger_group);

    nrfx_gpiote_out_task_enable(IMU_CS_PIN);  
    nrfx_gpiote_out_task_enable(FRAM_CS_PIN); 
}&lt;/pre&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407247?ContentTypeID=1</link><pubDate>Tue, 31 Jan 2023 09:09:56 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fa75012e-4868-4914-8d84-ba90412e317e</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
&lt;p&gt;Could you please try to use a GPIOTE PORT event to detect when the IMU&amp;#39;s interrupt line is asserted and trigger the SPI task from your app instead of using PPI? You should see a lower floor current when using GPIOTE PORT event compared to when you have IN events enabled.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://infocenter.nordicsemi.com/topic/errata_nRF5340_Rev1/ERR/nRF5340/Rev1/latest/anomaly_340_153.html?cp=4_0_1_0_1_26"&gt;[153] GPIOTE: GPIOTE with low-power latency setting does not register IN events in System ON IDLE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407199?ContentTypeID=1</link><pubDate>Mon, 30 Jan 2023 23:40:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:b1e32738-ead3-4f4e-afe4-18a82a2ebea5</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;Hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Thank you for your reply. this makes complete sense. I now have another power consumption issue. My app does the following using PPI, SPIM, GPIOTE, and timers&lt;/p&gt;
&lt;p&gt;the PPI configuration is as follow:&lt;/p&gt;
&lt;p&gt;1) Upon receiving a GPIOTE trigger from an IMU(every 8.3 seconds), read its data (this is operating on a dedicated spi bus, SPIM0)&lt;/p&gt;
&lt;p&gt;2)&amp;nbsp;write a dummy read command to an FRAM IC to wake it up from hibernate state (SPIM1 bus)&lt;/p&gt;
&lt;p&gt;3) trigger timer for 8ms from the start of the FRAM SPIM transaction(step 2)(period for FRAM to become stable from hibernate state)&lt;/p&gt;
&lt;p&gt;4) write the WREN(write enable) command to the FRAM upon completion of the 8ms timer&lt;/p&gt;
&lt;p&gt;5) write the (write command, address, data) to the FRAM&lt;/p&gt;
&lt;p&gt;6) write the hibernate command to the FRAM&lt;/p&gt;
&lt;p&gt;the multiple writes(aside from step 5) can NOT be combined as the bus CS pin needs to be toggled for the memory chip to accept the commands.&lt;/p&gt;
&lt;p&gt;to do this, I used 2 spi buses and 4 timers(one timer mode for the 8ms delay and 4 counters)&lt;/p&gt;
&lt;p&gt;In sum, my code works exactly as described and verified using oscilloscope.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;my issue is after the first PPI transaction is triggered, something is consuming power and/or is staying on. has between 650 and 850us periods. please see the first plot below. Note: approx. 200uA of the 600uA is from my external peripherals on the board.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/ppk_2D00_20230130T231015.png" /&gt;&lt;/p&gt;
&lt;p&gt;the 2nd plot shows this issue does not exist prior to the first PPI transaction.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" alt=" " src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/ppk_2D00_20230130T231344.png" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I do not think its a timer issue. I have read that the EasyDMA does consume ~1.5mA but that should only be during transmission. and the frequency of these pulses do not correlate to any SPI transaction. I have not been able to isolate the cause of this and your time and effort would be greatly appreciated.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Wael&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/407018?ContentTypeID=1</link><pubDate>Mon, 30 Jan 2023 08:56:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:595bc9d2-5f41-4bdb-8986-f8b4803f6c51</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hi Wael,&lt;/p&gt;
[quote user="whazin"]1) will an external 32kHz crystal use less power? or[/quote]
&lt;p&gt;The internal RC oscillator will lead to a slightly higher average current for the following reasons:&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. The Bluetooth controller will need to increase its RADIO RX listening windows to compensate for the additional clock drift compared to the LF crystal oscillator.&lt;/p&gt;
&lt;p&gt;2. Requires periodic calibration,&lt;/p&gt;
&lt;p&gt;3. RC oscillator has a higher run current.&lt;/p&gt;
&lt;p&gt;You can estimate how much impact the clock source will have on your application (in terms of average power consumption) by using our online power profiler here:&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="https://devzone.nordicsemi.com/power/w/opp/2/online-power-profiler-for-bluetooth-le"&gt;Online Power Profiler for Bluetooth LE&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
[quote user="whazin"]&lt;div&gt;&lt;span&gt;2) Since we know our device will be operating in a fairly temp controlled&amp;nbsp;environment, what do you think would be wise settings to minimize power consumption but not get some egregious&amp;nbsp;clock drift?&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;for example, do the cal every x number of deg change if possible. what do you think that x should be&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;or do it every x seconds(what do you think that x should be)&lt;/span&gt;&lt;/div&gt;[/quote]
&lt;p&gt;I think you can extend the interval to 8 seconds. From the PS:&lt;/p&gt;
&lt;p&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1675068982009v1.png" alt=" " /&gt;&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/406921?ContentTypeID=1</link><pubDate>Fri, 27 Jan 2023 16:48:07 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:16a0c40d-6f7f-4b3b-b77b-08416cc3a6d0</guid><dc:creator>Wael</dc:creator><description>&lt;p&gt;Hi Vidar,&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;That seems to be it. I set the following&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&lt;span&gt;CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP&lt;/span&gt;&lt;span&gt;=0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD&lt;/span&gt;&lt;span&gt;=2000&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;and period did change accordingly. please see plot.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;img style="max-height:240px;max-width:320px;" src="https://devzone.nordicsemi.com/resized-image/__size/640x480/__key/communityserver-discussions-components-files/4/pastedimage1674837461478v1.png" alt=" " /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;So with that said, I have few questions.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;1) will an external 32kHz crystal use less power? or&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;2) Since we know our device will be operating in a fairly temp controlled&amp;nbsp;environment, what do you think would be wise settings to minimize power consumption but not get some egregious&amp;nbsp;clock drift?&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;for example, do the cal every x number of deg change if possible. what do you think that x should be&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;or do it every x seconds(what do you think that x should be)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;your help is greatly appreciated.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Regards,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;Wael&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: 4 second current spikes during sleep</title><link>https://devzone.nordicsemi.com/thread/406871?ContentTypeID=1</link><pubDate>Fri, 27 Jan 2023 14:04:32 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:5ff89d6f-4dc0-4ecc-9d56-15a01ec87aab</guid><dc:creator>Vidar Berg</dc:creator><description>&lt;p&gt;Hello,&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Please set&amp;nbsp;CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_MAX_SKIP=0 and then try to adjust the&amp;nbsp; CONFIG_CLOCK_CONTROL_NRF_CALIBRATION_PERIOD setting to see if it affects the interval of your current spike. The 2nd screenshot looks&amp;nbsp;could be showing the clock calibration event (The 32K RC oscillator is calibrated periodically against the HF crystal oscillator).&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Best regards,&lt;/p&gt;
&lt;p&gt;Vidar&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>