The encoders I am using generating about 500 pulses per second, and I need to read 3 of them at the same time. I assume a good approach for that is to use the hardware timer to count the pulses and then using a separate timer to read the pulses. I am new to PPI and Timers, and I wrote some code that should I think be capturing the counter value of one of the encoders, but when the event comes in my nRF is crashing. Code attached below.
My approach would be to use 3 separate timer instances (1,2,3) for counting the pulses and another time (4) to periodically read the counter values. A few questions I have:
1) Could I just use a single timer instance to capture all 3 counts separately (maybe using a different channel?)
2) Could I use the app_timer to generate the software interrupt to read the hardware counters (for instance, app_timer would run every 250ms).
nrfx_err_t err_code;
const size_t err_code_str_len = 60;
char err_code_str[err_code_str_len] = { 0 };
uint32_t encoder1_nrfPin = digitalPinToPinName(GC_PIN_MOTOR1_ENCODER_A); // grab the nRF pin/port
nrfx_timer_config_t timer_cfg = NRFX_TIMER_DEFAULT_CONFIG;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
timer_cfg.mode = NRF_TIMER_MODE_LOW_POWER_COUNTER;
err_code = nrfx_timer_init(&_timer_counter_encoder1, &timer_cfg, NULL);
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
nrfx_timer_extended_compare(&_timer_counter_encoder1, NRF_TIMER_CC_CHANNEL0, 3, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
if (!nrfx_gpiote_is_init()) {
err_code = nrfx_gpiote_init(7); // lowest priority
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
}
nrfx_gpiote_in_config_t gpiote_config = NRFX_GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
gpiote_config.pull = NRF_GPIO_PIN_PULLUP;
err_code = nrfx_gpiote_in_init(encoder1_nrfPin, &gpiote_config, GPIOTE_handler);
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
err_code = nrfx_ppi_channel_alloc(&_ppi_encoder1_gpio_count);
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
err_code = nrfx_ppi_channel_assign(_ppi_encoder1_gpio_count,
nrfx_gpiote_in_event_addr_get(encoder1_nrfPin),
nrfx_timer_task_address_get(&_timer_counter_encoder1, NRF_TIMER_TASK_COUNT));
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
err_code = nrfx_ppi_channel_enable(_ppi_encoder1_gpio_count);
if (err_code != NRFX_SUCCESS) {
// todo: print string
Serial.print("Error "); Serial.println(err_code);
return;
}
nrfx_gpiote_in_event_enable(encoder1_nrfPin, true);
Serial.println("encoders_begin(): <<");