I must be doing something obviously wrong but I just can't see it.
I'm trying to create a PPI linkage between the UART RXDRDY event and a timer working in counter mode so that I can count received characters. However my counter never moves from zero. I can see that the DMA has received and transferred the expected number of characters when the ENDRX event is handled if I call nrf_uarte_rx_amount_get() but my counter never increases. My initialisation code is below, can anyone spot what I'm doing wrong? I am reading the counter with nrfx_timer_capture_get(&gTimer, 0).
static nrfx_timer_t gTimer = NRFX_TIMER_INSTANCE(2);
static nrf_ppi_channel_t gPpiChannel;
static NRF_UARTE_Type *gpReg = NRF_UARTE0;
static void counterEventHandler(nrf_timer_event_t eventType,
void *pContext)
{
(void) eventType;
(void) pContext;
}
// Set up UART and counter.
int32_t init(int32_t pinTx, int32_t pinRx,
int32_t baudRateNrf)
{
int32_t errorCode = 0;
nrfx_timer_config_t timerConfig = NRFX_TIMER_DEFAULT_CONFIG;
timerConfig.mode = NRF_TIMER_MODE_COUNTER;
timerConfig.bit_width = NRF_TIMER_BIT_WIDTH_32;
if (nrfx_timer_init(&gTimer,
&timerConfig, counterEventHandler) == NRFX_SUCCESS) {
if (nrfx_ppi_channel_alloc(&gPpiChannel)) == NRFX_SUCCESS) {
if ((nrfx_ppi_channel_assign(gPpiChannel,
nrf_uarte_event_address_get(gpReg,
NRF_UARTE_EVENT_RXDRDY),
nrfx_timer_task_address_get(&gTimer,
NRF_TIMER_TASK_COUNT)) != NRFX_SUCCESS) ||
(nrfx_ppi_channel_enable(gPpiChannel) != NRFX_SUCCESS)) {
nrfx_ppi_channel_disable(gPpiChannel);
nrfx_ppi_channel_free(gPpiChannel);
errorCode = -1;
}
} else {
errorCode = -1;
}
} else {
errorCode = -1;
}
if (errorCode == 0) {
// [ I create UART buffers, "pRxBufferWriteNext" and the like, etc. here]
nrf_uarte_baudrate_set(gpReg, baudRateNrf);
nrf_gpio_pin_set(pinTx);
nrf_gpio_cfg_output(pinTx);
nrf_uarte_txrx_pins_set(gpReg, pinTx, pinRx);
nrf_uarte_configure(gpReg, NRF_UARTE_PARITY_EXCLUDED, NRF_UARTE_HWFC_DISABLED);
nrf_uarte_enable(gpReg);
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_ENDRX);
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_ENDTX);
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_ERROR);
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_RXSTARTED);
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_TXSTOPPED);
nrf_uarte_shorts_enable(gpReg, NRF_UARTE_SHORT_ENDRX_STARTRX);
nrf_uarte_rx_buffer_set(gpReg,
(uint8_t *) (pRxBufferWriteNext->pStart),
256);
pRxBufferWriteNext = pRxBufferWriteNext->pNext;
nrf_uarte_task_trigger(gpReg, NRF_UARTE_TASK_STARTRX);
nrf_uarte_int_enable(gpReg, NRF_UARTE_INT_ENDRX_MASK |
NRF_UARTE_INT_ERROR_MASK |
NRF_UARTE_INT_RXSTARTED_MASK);
NRFX_IRQ_PRIORITY_SET(getIrqNumber((void *) gpReg),
NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY);
NRFX_IRQ_ENABLE(getIrqNumber((void *) (gpReg)));
nrfx_timer_enable(&gTimer);
nrfx_timer_clear(&gTimer);
}
return errorCode;
}
void nrfx_uarte_0_irq_handler(void)
{
if (nrf_uarte_event_check(gpReg, NRF_UARTE_EVENT_ENDRX)) {
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_ENDRX);
} else if (nrf_uarte_event_check(gpReg, NRF_UARTE_EVENT_RXSTARTED)) {
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_RXSTARTED);
nrf_uarte_rx_buffer_set(gpReg,
(uint8_t *) (pRxBufferWriteNext->pStart),
256);
pRxBufferWriteNext = pRxBufferWriteNext->pNext;
} else if (nrf_uarte_event_check(gpReg, NRF_UARTE_EVENT_ERROR)) {
nrf_uarte_event_clear(gpReg, NRF_UARTE_EVENT_ERROR);
nrf_uarte_errorsrc_get_and_clear(gpReg);
}
}