This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 DK improper GPIOTE --> PPI configuration (no interrupts being raised on input toggle)

#define PIN_IN 1
struct queue* q;

void start_timer(void)
{		
    NRF_LOG_INFO("initializing NRF_TIMER1...");
    NRF_TIMER1->MODE = TIMER_MODE_MODE_Timer;              // Set the timer in Counter Mode
    NRF_TIMER1->TASKS_CLEAR = 1;                             // clear the task first to be usable for later
	NRF_TIMER1->PRESCALER = 4;                              //us granularity
	NRF_TIMER1->BITMODE = TIMER_BITMODE_BITMODE_32Bit;		   //Set counter to 32 bit resolution
		
	NRF_TIMER1->TASKS_START = 1;               // Start TIMER1
}

static void gpio_init(void)
{
        sd_nvic_DisableIRQ(GPIOTE_IRQn);
		sd_nvic_ClearPendingIRQ(GPIOTE_IRQn);
		NRF_LOG_INFO("initializing gpio...");
		
		NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Disabled << GPIOTE_INTENSET_IN1_Pos);
		
		nrf_gpio_cfg_input(PIN_IN, NRF_GPIO_PIN_PULLDOWN);
	
		NRF_GPIOTE->CONFIG[1] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos)
			| (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos)
			| (PIN_IN << GPIOTE_CONFIG_PSEL_Pos); // IN event
    
		NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos);
		
		//sd_nvic_SetPriority(GPIOTE_IRQn, 1);
		sd_nvic_EnableIRQ(GPIOTE_IRQn);
}


// ppi linkage
static void ppi_init(void)
{
	NRF_LOG_INFO("initializing ppi linkage...");
	// disable PPI channel 1
	NRF_PPI->CHEN = (PPI_CHEN_CH1_Disabled << PPI_CHEN_CH1_Pos);
	
	//on every GPIO polarity toggle encounter/interupts
	NRF_PPI->CH[1].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[1];
	// put time in us into CC[1] register
	NRF_PPI->CH[1].TEP = (uint32_t)&NRF_TIMER1->TASKS_CAPTURE[1];
    // Enable PPI channel 1
    NRF_PPI->CHEN = (PPI_CHEN_CH1_Enabled << PPI_CHEN_CH1_Pos);
}

// I assume this is called every time there is an interupt (polarity toggle on input pin)
void GPIOTE_IRQHandler(void)
{
    NRF_LOG_INFO("in GPIOTE_IRQHandler...");
	if(NRF_GPIOTE->EVENTS_IN[1] != 0)
    {
        NRF_GPIOTE->EVENTS_IN[1] = 0;
		
		//NRF_LOG_INFO("GPIOTE handler: %i", NRF_TIMER1->CC[1]);
		//NRF_LOG_FLUSH();
		
		//restart timer		
		NRF_TIMER1->TASKS_CLEAR = 1;
		
		// queue microsecond data
		enQueue(q, NRF_TIMER1->CC[1]);
				
    }
}

int main{
        q = (struct queue*)malloc(sizeof(struct queue)); 
		q->stack1 = NULL; 
		q->stack2 = NULL;
		q->size = 0;
		
		start_timer();
		
		NRF_LOG_INFO("waiting to initialize GPIO IRQ...")
		NRF_LOG_FLUSH();
		
		nrf_delay_ms(1000);
		
		gpio_init();
		
		NRF_LOG_INFO("GPIO IRQ initialized")
		NRF_LOG_INFO("waiting to initialize ppi link...")
		NRF_LOG_FLUSH();
		nrf_delay_ms(1000);
		
		ppi_init();
		
		NRF_LOG_INFO("ppi link initialized")
		NRF_LOG_FLUSH();
		
		for (;;)
        {
            //GPIOTE_IRQHandler();
			idle_state_handle();
			NRF_LOG_INFO("GPIOTE EVENTS IN: %i", NRF_GPIOTE->EVENTS_IN[1])
        }
}

Above is my code. I am using Keil uVision5 IDE on Windows 10. I am flashing s132 and then application hex to device using nRFGo.

My goal is to take a square wave as input to the nRF52 DK and measure the duration of each high and low in the signal (in microseconds) storing them into a queue for later processing.

Input signal is around 980 Hz. 

My code currently seems configured incorrectly.

NRF_GPIOTE->EVENTS[1] is always 0 according to the RTT logs. Even when multitudes of different input signals have been tried. 

I feel my lack of experience in working with the nRF52 is the root cause. 

I would appreciate anyone with GPIOTE and PPI experience taking time to review my short code snippet and diagnose my issues. 

Cheers!

Parents Reply Children
No Data
Related