#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!