<?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>HardFault with GPIOTE &amp;amp; SD</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/25418/hardfault-with-gpiote-sd</link><description>Hi! 
 I am getting a HardFault when I try to read a GATTs value inside a GPIOTE ISR handler. 
 I already tried setting the ISR priority to low as suggested in various posts. 
 Here is my code: 
 #include &amp;quot;app_settings.h&amp;quot;

#include &amp;quot;control.h&amp;quot;
#include</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Mon, 02 Oct 2017 06:39:15 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/25418/hardfault-with-gpiote-sd" /><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100182?ContentTypeID=1</link><pubDate>Mon, 02 Oct 2017 06:39:15 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9c72f418-32cc-4a2e-b432-ff38fb5113cf</guid><dc:creator>MartinBL</dc:creator><description>&lt;p&gt;No worries. It is an interesting topic.&lt;/p&gt;
&lt;p&gt;Good luck with your project!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100178?ContentTypeID=1</link><pubDate>Sun, 01 Oct 2017 21:42:45 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:8bd778ef-30b5-4bf3-849a-ef811b437cd2</guid><dc:creator>Yatekii</dc:creator><description>&lt;p&gt;Yes ofc. you are very velcome to mark this as resolved, even tho I will try out the PPI later on as this seems really great!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100181?ContentTypeID=1</link><pubDate>Sun, 01 Oct 2017 21:41:34 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:4c12eae2-d50b-4ea7-961a-9d184b2870e0</guid><dc:creator>Yatekii</dc:creator><description>&lt;p&gt;Wow you are great and very generous with your time sir! Thank you so much! I will try this out as soon as I have some more urgent matters resolved as the software solution works just fine for the time being.
I will then provide you with some more feedback too, sorry for the late and scarce answer ...
Best, Noah&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100176?ContentTypeID=1</link><pubDate>Tue, 26 Sep 2017 12:11:05 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:db8b8c89-94fb-46b2-96f8-7790add21369</guid><dc:creator>MartinBL</dc:creator><description>&lt;p&gt;Since I couldn&amp;#39;t find any good examples or documentation anywhere, I took the opportunity to write a bit about the PPI in an answer below (it got long). Hopefully it will be useful to others too.&lt;/p&gt;
&lt;p&gt;Since you have found a working solution, can we consider the matter as solved? SD 5 is the one you are supposed to use with SDK 14 so I don&amp;#39;t think that is an issue.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100180?ContentTypeID=1</link><pubDate>Tue, 26 Sep 2017 12:04:38 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:290349f0-9376-4ad9-9a1c-3e5a2e2f50a1</guid><dc:creator>MartinBL</dc:creator><description>&lt;p&gt;The &lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/ppi.html?cp=2_1_0_21#concept_sxf_21l_1s"&gt;Programmable Peripheral Interconnect (PPI)&lt;/a&gt; sounds like the ideal solution to your troubles.&lt;/p&gt;
&lt;p&gt;Unfortunately the scarce documentation in the infocenter doesn&amp;#39;t do the PPI any justice. It is really a powerful tool that can save you a lot of work, code lines, CPU cycles, and power. In your comment you compare it to a messaging system, which is sort of correct I suppose. You can configure one peripheral in your system to send a message on a certain event, and then that message is delivered to a different peripheral in your system which then performs some task based on that. Almost all of the nRF5 series&amp;#39; peripherals (SAADC, TWI, RADIO, GPIOTE, RTC, TIMER, etc. etc.) can process some sort of tasks and events and it is pretty much only your imagination that limits how you connect everything.
For example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;An ADC Result Done Event (&lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/saadc.html?cp=2_1_0_36_10#topic"&gt;SAADC-&amp;gt;EVENT_RESULTDONE&lt;/a&gt;) can trigger a timer Count Task (&lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/timer.html?cp=2_1_0_23_4#topic"&gt;TIMERx-&amp;gt;TASK_COUNT&lt;/a&gt;). This way you can sample a signal e.g. 100 times while the CPU is sleeping, but have the timer count the number of samples performed and wake the CPU up to process the samples at the 100th sample.&lt;/li&gt;
&lt;li&gt;An input GPIO pin pulled high to low (&lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/gpiote.html?cp=2_1_0_20_3#topic"&gt;GPIOTE-&amp;gt;EVENT_IN&lt;/a&gt; can start one or more TWI transfer tasks (&lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52832.ps.v1.1/twim.html?cp=2_1_0_32_7#unique_1822381857"&gt;TWIM-&amp;gt;TASKS_STARTTX&lt;/a&gt;). This is ideal for reading data from a sensor with a Data Ready signal.&lt;/li&gt;
&lt;li&gt;In some (rare) cases it is also useful to use the PPI to &amp;quot;loop&amp;quot; events in a peripheral back into the same peripheral and make it perform a task.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Below I have pasted some basic code that counts the number of times an input signal is pulled high to low (by using BUTTON 3 on the nRF5 DK). The push of the button triggers a GPIOTE event which is counted by TIMER 1. When the counter register in TIMER 1 matches the value in the Capture Compare register #0 (which in this case is 3) the timer generates an event which is routed back to the GPIOTE module which responds by toggling a GPIO pin.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;lt;stdbool.h&amp;gt;
#include &amp;lt;stdint.h&amp;gt;

#include &amp;quot;app_util_platform.h&amp;quot;
#include &amp;quot;boards.h&amp;quot;

void TIMER1_IRQHandler(void)
{
    NRF_TIMER1-&amp;gt;EVENTS_COMPARE[0] = 0;
    nrf_gpio_pin_toggle(LED_2);
    int i = 0;
    while(i&amp;lt;0xFFFFF)
	{
		i++;     
	}
}

void ppi_setup(void)
{
	/***************
	 * GPIOTE Setup
	 **************/
	// Input GPIOTE event triggered on the push of button 3 on dev kit
	nrf_gpio_cfg_input(BUTTON_3, NRF_GPIO_PIN_PULLUP); // Enable pullup on the GPIO
	NRF_GPIOTE-&amp;gt;CONFIG[0] = (GPIOTE_CONFIG_MODE_Event &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos) | 
						(GPIOTE_CONFIG_POLARITY_LoToHi &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos) | 
						(BUTTON_3 &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos);

    // Output GPIOTE task (Toggle a GPIO). 
    NRF_GPIOTE-&amp;gt;CONFIG[1] = (GPIOTE_CONFIG_MODE_Task &amp;lt;&amp;lt; GPIOTE_CONFIG_MODE_Pos) | 
                            (GPIOTE_CONFIG_POLARITY_Toggle &amp;lt;&amp;lt; GPIOTE_CONFIG_POLARITY_Pos) | 
                            (GPIOTE_CONFIG_OUTINIT_High &amp;lt;&amp;lt; GPIOTE_CONFIG_OUTINIT_Pos) | 
                            (LED_1 &amp;lt;&amp;lt; GPIOTE_CONFIG_PSEL_Pos);


    /***************
     * COUNTER Setup
     **************/
    // Clear and disable interrupts before configuring new interrupts
    NVIC_DisableIRQ(TIMER1_IRQn);
    NVIC_ClearPendingIRQ(TIMER1_IRQn);
    /* Conigureing TIMER
     * Set mode to low power counter mode to save power
     * Use 32 bit counter mode. Doesn&amp;#39;t really matter in this example
     * Enable shortcut to clear the Capture Compare register #0 on compare event
     * Set capture compare register #0 to 3 to generate events and interrupts on every third GPIOTE input events
     * Enable Timer capture compare interrupt 
     */
    NRF_TIMER1-&amp;gt;MODE = TIMER_MODE_MODE_LowPowerCounter &amp;lt;&amp;lt; TIMER_MODE_MODE_Pos;
    NRF_TIMER1-&amp;gt;BITMODE = TIMER_BITMODE_BITMODE_32Bit &amp;lt;&amp;lt; TIMER_BITMODE_BITMODE_Pos;
    NRF_TIMER1-&amp;gt;SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled &amp;lt;&amp;lt; TIMER_SHORTS_COMPARE0_CLEAR_Pos;
    NRF_TIMER1-&amp;gt;CC[0] = 3;
    NRF_TIMER1-&amp;gt;INTENSET = TIMER_INTENSET_COMPARE0_Enabled &amp;lt;&amp;lt; TIMER_INTENSET_COMPARE0_Pos;
    NRF_TIMER1-&amp;gt;TASKS_START = 1;

    NVIC_SetPriority(TIMER1_IRQn, _PRIO_APP_LOWEST);
    NVIC_EnableIRQ(TIMER1_IRQn);


    /***************
     * PPI Setup
     **************/
     // Connect the Timer Count task with the GPIOTE input event (To count button pushes)
    NRF_PPI-&amp;gt;CH[0].TEP = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;TASKS_COUNT;
    NRF_PPI-&amp;gt;CH[0].EEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;EVENTS_IN[0];
    NRF_PPI-&amp;gt;CHEN |= PPI_CHEN_CH0_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH0_Pos;

    // Connect the timer Capture compare event to the GPIOTE Out Task (to toggle the LED on every third button push)
    NRF_PPI-&amp;gt;CH[1].TEP = (uint32_t)&amp;amp;NRF_GPIOTE-&amp;gt;TASKS_OUT[1];
    NRF_PPI-&amp;gt;CH[1].EEP = (uint32_t)&amp;amp;NRF_TIMER1-&amp;gt;EVENTS_COMPARE[0];
    NRF_PPI-&amp;gt;CHEN |= PPI_CHEN_CH1_Enabled &amp;lt;&amp;lt; PPI_CHEN_CH1_Pos;
}


/**@brief Function for application main entry.
 */
int main(void)
{
    NRF_POWER-&amp;gt;DCDCEN = 1;
    nrf_gpio_cfg_output(LED_2);
    ppi_setup();

    // Enter main loop.
    for (;;)
    {
        // Do nothing but sleep
      __WFE();
      __SEV();
      __WFE();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below you can see how this code connects the tasks and events to the PPI channels:
&lt;img src="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/PPI.png" alt="adlfjk" /&gt;&lt;/p&gt;
&lt;p&gt;Below you can see a plot of the power consumption. You can see that most of the time the system uses little to no power. When the button is pressed the pull up resistor (~13kOhm) causes a small current of ~200uA. Every third push of the button an interrupt is triggered and the CPU is started. The result is shown as the 4mA spikes.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://devzone.nordicsemi.com/cfs-file/__key/communityserver-discussions-components-files/4/7026.Current.PNG" alt="image description" /&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100177?ContentTypeID=1</link><pubDate>Mon, 25 Sep 2017 16:22:24 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:9cb01d6d-7cbe-496a-af81-f0674d6ed634</guid><dc:creator>Yatekii</dc:creator><description>&lt;ol&gt;
&lt;li&gt;Yes I am saying that :) It can read the attribute during the first call (even tho the value is 0 instead of 1; yes the handles are correct, I checked that) the SD will go to the HardFault handler afterwards. (I am using SDK 14.0 and SD v5.0; maybe that&amp;#39;s bad tho)&lt;/li&gt;
&lt;li&gt;Oh I really should have read better, thanks for the info!&lt;/li&gt;
&lt;li&gt;Ok that sounds very promising! I already have a working solution now, where I wont use the GATT DB but rather store the value myself upon write event. Maybe that solution is bad. Timing is no issue as tests have shown. But I will still try the PPI solution as it sounds great. I read about the PPI already and didn&amp;#39;t quite understand what the purpose really is tbh. I felt like it was a messaging system but then I might have horribly mistaken. Is there a good read you can recommend, as just the bare function docs sometimes are not enough =)&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: HardFault with GPIOTE &amp; SD</title><link>https://devzone.nordicsemi.com/thread/100179?ContentTypeID=1</link><pubDate>Mon, 25 Sep 2017 14:29:20 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:035c7fee-e3d7-47b4-95fb-6b8bb80e0676</guid><dc:creator>MartinBL</dc:creator><description>&lt;ol&gt;
&lt;li&gt;Are you saying that your code above with GPIOTE irq priority APP_IRQ_PRIORITY_LOW doesn&amp;#39;t work?&lt;/li&gt;
&lt;li&gt;Assuming that you are using nRF52 then the softdevice &lt;a href="http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s132.sds/dita/softdevices/s130/processor_avail_interrupt_latency/exception_mgmt_sd.html?cp=2_3_0_0_15_1"&gt;reserves priorities 0, 1, and 4&lt;/a&gt;. You are free to use the other levels for application interrupts.&lt;/li&gt;
&lt;li&gt;If latency is important to you I suggest that you check out the possibility of using PPI and GPIOTE channels, together with a timer. You can make a level change on an input start the timer, and when the timer reaches a certain value it will trigger a level change on a different output pin. By using PPI you can do all this without interrupts at all and completely independent of the CPU.&lt;/li&gt;
&lt;/ol&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>