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)
{
}
}