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!

  • You're trying to receive analog signal on digital input. It shouldn't be done such way. GPIO expects digital signal in range 0...VDD. For analog signal, configure pin as analog input and use COMP instead of GPIO. In any case input level should be in range 0...VDD, otherwise you need external schematic to ensure that.

    Try to connect your pin to GND then VDD, if there's no change in read value, your chip rather didn't withstand 6.6v input.

Related