<?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>Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/f/nordic-q-a/43114/simultaneous-gpiote-interrupt-event-not-being-generated</link><description>I&amp;#39;m running FreeRTOS with SDK version 15.0 on nrf52 custom board. 
 I have two sensors, say A and B, on two separate SPIM bus instances. Sensor B utilizes PPI to trigger data transfer on Low-to-High transition of its interrupt pin. The PPI is also forked</description><dc:language>en-US</dc:language><generator>Telligent Community 13</generator><lastBuildDate>Wed, 13 Feb 2019 11:49:02 GMT</lastBuildDate><atom:link rel="self" type="application/rss+xml" href="https://devzone.nordicsemi.com/f/nordic-q-a/43114/simultaneous-gpiote-interrupt-event-not-being-generated" /><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/170850?ContentTypeID=1</link><pubDate>Wed, 13 Feb 2019 11:49:02 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ff7aca4b-f504-4e09-bbb5-037ff3856a77</guid><dc:creator>AGJ</dc:creator><description>&lt;p&gt;OK. Thanks...&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/170768?ContentTypeID=1</link><pubDate>Wed, 13 Feb 2019 08:00:50 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:7249c117-3679-4bc6-b1af-93166021fd85</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;I thought i replied to this message, but somehow my reply seems to have been sent to void. sorry about that.&lt;/p&gt;
&lt;p&gt;The PPI task is configured to work purely in the hardware once the channel is enabled and has no dependency on the availability on the CPU. The PPI will trigger the task in time no matter which context CPU is executing. That is the whole purpose of PPI/GPIOTE combo&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/170112?ContentTypeID=1</link><pubDate>Fri, 08 Feb 2019 12:06:19 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:e1b2014e-55a5-4ea0-ad75-9ec9d2a0a838</guid><dc:creator>AGJ</dc:creator><description>&lt;p&gt;OK, thanks.&lt;/p&gt;
[quote userid="75319" url="~/f/nordic-q-a/43114/simultaneous-gpiote-interrupt-event-not-being-generated/169909"]And will the execution of &amp;#39;IntHandler&amp;#39; affect the PPI task execution in any way provided that the contents of&amp;nbsp; &amp;#39;IntHandler&amp;#39; will not conflict with the PPI task?[/quote]
&lt;p&gt;And this?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/170070?ContentTypeID=1</link><pubDate>Fri, 08 Feb 2019 09:20:18 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:44443d1b-c4d0-40cf-b395-c21ed9bd0105</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;The IntHandler will not be executed fast enough. On ARM cortex, it takes&amp;nbsp;atleast 12 cpu cycles run the interrupt handler (after the interrupt is triggered). The IntHandler in your code will take way more CPU cycles as this is a callback from the GPIOTE ISR. The PPI task will take atmost 2 HFCLK cycles to be triggered. So for sure the PPI task will be triggered first in this case.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/169909?ContentTypeID=1</link><pubDate>Thu, 07 Feb 2019 12:22:58 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ae1b84c7-72f6-4c59-8df8-a95defa4db20</guid><dc:creator>AGJ</dc:creator><description>&lt;p&gt;Thanks for your time.&lt;/p&gt;
&lt;p&gt;I was not able to find any conflict in any kind of resource used by Sensors A and B...&lt;/p&gt;
&lt;p&gt;I have another question,&lt;/p&gt;
&lt;p&gt;During initialization of a GPIO, to be used as an event for PPI, instead of&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;nrfx_gpiote_in_init( SENSOR_B_DRDY_PIN, &amp;amp;SensorBIntPinConfig, NULL );&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;if I use&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;nrfx_gpiote_in_init( SENSOR_B_DRDY_PIN, &amp;amp;SensorBIntPinConfig, IntHandler );&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;and when there is a transition in SENSOR_B_DRDY_PIN, what will be executed first, the &amp;#39;IntHandler&amp;#39; or the PPI task that was configured?&lt;/p&gt;
&lt;p&gt;And will the execution of &amp;#39;IntHandler&amp;#39; affect the PPI task execution in any way provided that the contents of&amp;nbsp; &amp;#39;IntHandler&amp;#39; will not conflict with the PPI task?&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/169897?ContentTypeID=1</link><pubDate>Thu, 07 Feb 2019 11:42:10 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:ef5cb2e7-6c95-457a-81e8-cfafc0d12920</guid><dc:creator>Susheel Nuguru</dc:creator><description>[quote user="AGJ"]What would the dependency be???[/quote]
&lt;p&gt;&amp;nbsp;I cannot say it from your code snippet.&lt;/p&gt;
&lt;p&gt;Make sure that you are using two different SPI instances. Also make sure that in Sensor A GPIOTE handler, you are not conflicting with any of the hardware resource used in Sensor B configuration (PPI, GPIOTE, timer channels)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/169490?ContentTypeID=1</link><pubDate>Tue, 05 Feb 2019 12:06:46 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:fa4cfb37-8ebe-45b1-8461-e79dfeca986a</guid><dc:creator>AGJ</dc:creator><description>&lt;p&gt;Hi Susheel,&lt;/p&gt;
&lt;p&gt;These are my initialization and data transfer functions.&lt;/p&gt;
&lt;p&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;
/*   Sensor A FIFO data fetch complete callback. */
static void SensorA_SPIXferCallback( nrf_drv_spi_evt_t const * p_event, void * p_context )
{
    // Updating the remaining samples&amp;#39; count
    totSamples = totSamples - rxDataCount; 

    // If all samples are received,
    if( !totSamples )
    {
        xferComplete = true;

        nrfx_gpiote_in_event_disable( SENSOR_A_INT1_PIN );
        nrfx_gpiote_in_uninit( SENSOR_A_INT1_PIN ); 
    }
    else
    {
        // Calculating watermark level
        watermark = ( totSamples &amp;lt;= MAX_WATERMARK_LEVEL ) ? totSamples : MID_WATERMARK_LEVEL; 

        // Setting the calculated watermark level if it is different from the previous value
        if( prevWatermark != watermark )
        {
            if( WordWrite( FIFO_CTRL, watermark ))     
            {
                return ; 
            }
            
            // Saving the new watermark
            prevWatermark = watermark; 
        }
    }

    xferPending = false; // No transfer is pending at this point
}




/*   Sensor A FIFO data fetch initiate. Non-blocking   */
static int32_t FIFODataFetchStart( void )
{
    uint16_t unreadDataCount = watermark; 

    // Reading contents of FIFO Status Reg
    if( WordRead( FIFO_STATUS, &amp;amp;unreadDataCount ))    
    {
        return -ERR_IO; 
    }
    
    // Extracting unread data count from the contents in FIFO status register
    unreadDataCount = unreadDataCount &amp;amp; FIFO_UNREAD_COUNT_MASK; 
       
      
    // If the calculated number of samples to read is greater than number of samples left,
    // read only the remaining number of samples
    if( rxDataCount &amp;gt; totSamples )
    {
        rxDataCount = totSamples; 
    }
    
    // Start SPI read
    if( MultiReadStart( FIFO_OUTPUT_ADR, ( uint8_t * )outDataBuf, rxDataCount ))
    {
        return -ERR_IO; 
    }

    xferPending = true;            // A new data transfer is pending

    return 0; 
}

/*   Sensor A Data Ready Int Callback    */
static void SensorA_IntHandler( nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action )
{       
    // Trigger a new transfer only if there is no other transfer pending.
    if( !xferPending )
    {
        FIFODataFetchStart(); 
    }
}

static int32_t SensorB_DRIntConfig( IntTransition_t transition, IntCallback_t intCallback )
{
    int32_t ret;

    if( transition == LOW_TO_HI )
    {
        SensorAPinConfig.sense = NRF_GPIOTE_POLARITY_LOTOHI; 
    }
    else if( transition == HI_TO_LOW )
    {
        SensorAPinConfig.sense = NRF_GPIOTE_POLARITY_HITOLO; 
    }
    else if( transition == TOGGLE )
    {
        SensorAPinConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE; 
    }

    
    SensorA_IntCallback = intCallback; 

    ret = nrfx_gpiote_in_init( SENSOR_A_INT1_PIN, &amp;amp;SensorAPinConfig, SensorA_IntHandler );
    APP_ERROR_CHECK( ret ); 
    if ( ret )
    {
        return ret;
    }

    nrfx_gpiote_in_event_enable( SENSOR_A_INT1_PIN, true );
    

    return 0; 
}


/*   Sensor B Data Ready Int Callback    */
static void SensorB_IntHandler( nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action )
{
    if( SensorB_IntCallback )
    {
        SensorB_IntCallback(( void * )action ); 
    }
}

/*   Function to configure Data Ready Pin for Sensor B     */
static int32_t SensorB_DRIntConfig( IntTransition_t transition, IntCallback_t intCallback )
{
    int32_t ret;

    if( transition == LOW_TO_HI )
    {
        SensorBIntPinConfig.sense = NRF_GPIOTE_POLARITY_LOTOHI; 
    }
    else if( transition == HI_TO_LOW )
    {
        SensorBIntPinConfig.sense = NRF_GPIOTE_POLARITY_HITOLO; 
    }
    else if( transition == TOGGLE )
    {
        SensorBIntPinConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE; 
    }

    SensorB_IntCallback = intCallback; 
    
	
	ret = nrfx_gpiote_in_init( SENSOR_B_DRDY_PIN, &amp;amp;SensorBIntPinConfig, IntHandler );
    if ( ret )
    {
        return ret;
    }

    nrfx_gpiote_in_event_enable( SENSOR_B_DRDY_PIN, true );

    return 0; 
}

/*   Function to configure PPI for Sensor B     */
static int32_t SensorB_TransferInit( uint32_t sampleCount, callback_t callback )
{
    int32_t err_code; 

    // Finding available Transfer module
    XferInst_t * tempXferInst = FindAvailXferInst();
    if( !tempXferInst )
    {
        return -ERR_NXIO; 
    }

    // Configuring the Transfer module
    tempXferInst-&amp;gt;avail    = false; 
    tempXferInst-&amp;gt;name     = device.name; 
    tempXferInst-&amp;gt;trigPin  = SENSOR_B_DRDY_PIN; 
    tempXferInst-&amp;gt;callback = callback;

    // Configurations for the timer instance
    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; 
    timer_cfg.interrupt_priority     = 7; 
    
    // Initialising timer (as counter -&amp;gt; sdk_config -&amp;gt; NRFX_TIMER_DEFAULT_CONFIG_MODE)
    err_code = nrf_drv_timer_init( &amp;amp;tempXferInst-&amp;gt;timerInst, &amp;amp;timer_cfg, tempXferInst-&amp;gt;event_handler );
    APP_ERROR_CHECK( err_code );
    
    // Allocating PPI channel
    err_code = nrf_drv_ppi_channel_alloc( &amp;amp;tempXferInst-&amp;gt;ppiChannel );
    APP_ERROR_CHECK( err_code );
       
    // Set up PPI Channel for triggering of SPIM start when an event occurs on the provided pin.
    err_code = nrf_drv_ppi_channel_assign( tempXferInst-&amp;gt;ppiChannel,
                                           nrf_drv_gpiote_in_event_addr_get( tempXferInst-&amp;gt;trigPin ),
                                           nrf_spim_task_address_get( busIdentifier.u.spim.p_reg, NRF_SPIM_TASK_START ) );
    APP_ERROR_CHECK( err_code );

    // Fork PPI to also trigger count on timer to keep track of number of samples.
    err_code = nrf_drv_ppi_channel_fork_assign( tempXferInst-&amp;gt;ppiChannel,
                                                nrf_drv_timer_task_address_get( &amp;amp;tempXferInst-&amp;gt;timerInst, NRF_TIMER_TASK_COUNT ));
    APP_ERROR_CHECK( err_code );

    // Setting counter compare event
    nrf_drv_timer_extended_compare( &amp;amp;tempXferInst-&amp;gt;timerInst, NRF_TIMER_CC_CHANNEL1, sampleCount, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true );
       
    // Enabling allocated PPI channel
    err_code = nrf_drv_ppi_channel_enable( tempXferInst-&amp;gt;ppiChannel );
    APP_ERROR_CHECK( err_code );

    // Enabling counter compare interrupt and counter
    nrf_drv_timer_enable( &amp;amp;tempXferInst-&amp;gt;timerInst );

    return 0;
}
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;I tried commenting out the Sensor A GPIOTE handler contents and sensor B didn&amp;#39;t hang.&lt;/p&gt;
&lt;p&gt;What would the dependency be???&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: Simultaneous GPIOTE interrupt event not being generated</title><link>https://devzone.nordicsemi.com/thread/169016?ContentTypeID=1</link><pubDate>Fri, 01 Feb 2019 10:04:09 GMT</pubDate><guid isPermaLink="false">137ad170-7792-4731-bb38-c0d22fbe4515:88fa97a4-e06a-4b44-a071-e64ae67fe0ed</guid><dc:creator>Susheel Nuguru</dc:creator><description>&lt;p&gt;Hi AGJ,&lt;/p&gt;
&lt;p&gt;Since you have a GPIOTE handler to start data transfer for sensor A, it is possible that this handler is taking too much time in itself at high frequencies.&lt;/p&gt;
&lt;p&gt;Nevertheless, if the new interrupt from Sensor B, is connected to PPI and which starts the transfer as well as increments the timer in counter mode, then it seems to be done purely in hardware and the software latencies should not have affected it.&lt;/p&gt;
&lt;p&gt;Just as an experiment, can comment the contents in the GPIOTE handler that is triggered by sensor A to see if this is the culprit. If this effects the sensor B data transfer, then something is wrong with the configuration of Sensor B as it somehow depends on CPU availability.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;It is hard to say more than this without looking into your initialization functions&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>