This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to use single GPIOTE interrupt handler to handle two different events?

We are using two GPIOTE inputs and there is only 1 GPIOTE interrupt handler. One of the GPIOTE input is from a power line chip that toggles @ 50 Hz rate. This GPIOTE input is used for AC zero cross detection on every rising edge, While the other GPIOTE input is used by ON/OFF switch. The ON/OFF switch gives a GPIOTE interrupt when there is any change in switch state. This GPIOTE interrupt is detected on every rising and falling edge. We are using Zero crossing for dimming purpose.

Currently since we have a single handler for all GPIOTE events, nRF is unable to detect the GPIOTE event when both Zero cross detection and ON/OFF Switch both GPIOTE events come on rising edge at the same time to trigger this single GPIOTE interrupt handler. This causes the nRF to miss the GPIOTE interrupt handler at all times after such an occurrence.

Please find the source code for testing the issue that we are having.

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "app_util.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf51.h"
#include "nrf_delay.h" 
#include "app_gpiote.h"

#define ZERO_CROSSING_PIN 0x4000  // 10ms pulse with 50% duty cycle  
#define ZERO_CROSS_IP (14)

#define BUTTON_1 0x20000         //External Button Press interrupt
#define BUTTON_IP (17)

#define LED_0 18

bool isZeroCrossed;
/*************************************************************************************************/
/*!
 * \fn  	void zeroCrossingEvent(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
 * \param   uint32_t event_pins_low_to_high 	[IN]
 * \param   uint32_t event_pins_high_to_low		[IN]
 * \brief	This event Occur After every 10 ms we got zero crossing. this Zero Crossing is used for 
 * 			start timer peripheral which drive Dimmed Device. 
 */
/***************************************************************************************************/

void zeroCrossingEvent(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)				// for dimming purpose
{
	if(isZeroCrossed == 0)
	{
		isZeroCrossed = 1;
		NRF_TIMER0->TASKS_START = 1;
	}
	
}

/*************************************************************************************************/
/*!
 * \fn  	void buttonPressEvent(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
 * \param   uint32_t event_pins_low_to_high 	[IN]
 * \param   uint32_t event_pins_high_to_low		[IN]
 * \Brief	Every time button is pressed This event fires and LED_0 toggle
 */
/*************************************************************************************************/

void buttonPressEvent(uint32_t event_pins_low_to_high, uint32_t event_pins_high_to_low)
{
	nrf_gpio_pin_toggle(LED_0);
}
/*************************************************************************************************/
 main function
/*************************************************************************************************/

int main(void)
{
	app_gpiote_user_id_t zeroCrossingId;
	app_gpiote_user_id_t buttonPressedId;
	isZeroCrossed = 0;

	nrf_gpio_cfg_input(ZCD, NRF_GPIO_PIN_NOPULL);
	nrf_gpio_cfg_input(BUTTON_1,NRF_GPIO_PIN_NOPULL);
	nrf_gpio_cfg_output(LED_0);
		
	APP_GPIOTE_INIT(2);	
	app_gpiote_user_register(&zeroCrossingId, ZERO_CROSSING_PIN, 0, zeroCrossingEvent);
	app_gpiote_user_register(&buttonPressedId, BUTTON_1, BUTTON_1, buttonPressEvent);
	app_gpiote_user_enable(zeroCrossingId);
	app_gpiote_user_enable(buttonPressedId);

	timer1_init();

	NVIC_EnableIRQ(TIMER0_IRQn);
	__enable_irq();

	while(1)
	{
	}		
}
Parents
  • I would guess that the zero crossing is the highest priority here, so why not add some code in the zero crossing servic routine(after the dimming has been taken care of) to read the on/off switch in a pedestrian polling manner? You could then handle this directly or by scheduling an event.

Reply
  • I would guess that the zero crossing is the highest priority here, so why not add some code in the zero crossing servic routine(after the dimming has been taken care of) to read the on/off switch in a pedestrian polling manner? You could then handle this directly or by scheduling an event.

Children
No Data
Related