This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF51 UART Confusion

I am completely confused by the nRF51 UART. I'm trying to port code originally written for an STM32 (another cortex chip). There, I define an interrupt, enable the RXRDY or TXEMPTY interrupts, and if a character comes in, I get an interrupt, or if I send a character, I get an interrupt as soon as it leaves the TX register and enters the shift register. Simple, and it just works.

I'm trying to do the same here, but can't get the IRQ routine to fire at all. I'm using the PCA10028 dev kit, pins 9 and 11 as RX and TX, don't need flow control, and soft device 110 and SDK 7.

I assume my problem has something to do with the PPI interface, but can't wrap my head around things like STARTTX, STARTRX or events. Can you use the UART without these, and just use INTENSET and INTENCLR? Or are these required?

I looked at the uart examples, but none of these looked, to me, suited for the kind of serial I/O I need to perform. The uart example doesn't use IRQ, so it doesn't look suitable as a starting point. Neither does the experimental_ble_app_uart example, as it too uses simple, non interrupt uart code.

Plus, despite having "uart" in their project names, almost none of the examples actually send or receive anything over the UART, unless it is debug data via printf, which is certainly not what I'm looking to do.

Any hints on how to take control of the UART?

Thanks, Jeff.

Parents
  • Hi Jeff

    I agree with you that the uart example does not show how to use those events that you mention (data_ready and data_sent), but what SDK version are you using? I suspect that you are using older than SDK 8 at least since you mention experimental_ble_app_uart which is no longer experimental in SDK 8.

    I refer to SDK 8.1.0. The example \examples\peripheral\uart uses the app_uart library which uses two FIFO buffers in the background to queue data.

    • When data arrives on the UART it is put into the RX FIFO buffer and then the registered app_uart handler is called (the uart_error_handle in the example) with event APP_UART_DATA_READY. In the app_uart handler you could call app_uart_get to extract data from the RX FIFO buffer instead of polling it as done in the uart example.

    • When you want to send data to the UART, you call app_uart_put in order to put data into the TX FIFO, which will be sent over the UART if the UART is not currently busy. If the UART TX is currently busy sending data, an additional byte will be sent from the TX FIFO when the UART TX becomes available (when TXDRDY event is received, handled internally in app_uart library) or when CTS line goes low (indicating that the peer device is ready to receive data). When the TX FIFO is empty, i.e. all data has been sent, the app_uart event handler is called with the event type APP_UART_TX_EMPTY.

    So, in the \examples\peripheral\uart example, capture the APP_UART_TX_EMPTY and APP_UART_DATA_READY events (in uart_error_handle) instead of polling in the main loop. When you capture APP_UART_DATA_READY, call app_uart_get to extract data from the RX FIFO.

  • Hi Jeff

    Of course you can skip using the app_uart and use the UART directly without any FIFOs. The UART has 1 byte TXD register and 6 byte RXD registers. You have the RXDRDY and TXDRDY events to indicate you of data_received and data_sent respectively. You can get code reference for how to do that by looking into the app_uart_fifo.c. In that file you can see how the UART0_IRQHandler captures the NRF_UART0->EVENTS_RXDRDY and NRF_UART0->EVENTS_TXDRDY events and what action is taken in each case. Also take a look at the app_uart_init to see how the UART is manually initialized.

Reply
  • Hi Jeff

    Of course you can skip using the app_uart and use the UART directly without any FIFOs. The UART has 1 byte TXD register and 6 byte RXD registers. You have the RXDRDY and TXDRDY events to indicate you of data_received and data_sent respectively. You can get code reference for how to do that by looking into the app_uart_fifo.c. In that file you can see how the UART0_IRQHandler captures the NRF_UART0->EVENTS_RXDRDY and NRF_UART0->EVENTS_TXDRDY events and what action is taken in each case. Also take a look at the app_uart_init to see how the UART is manually initialized.

Children
No Data
Related