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); } }