I am trying to get the UARTE0 on the nRF9160 DK to transmit some bytes through the Virtual COM port. I am not sure why it does not work. I have included my source code below.
I have done some debugging with an oscilloscope on the TXD pin (P0.29) and the Ozone Debugger. So far, I can observe that the TXD pin goes low as soon as I enable the UART (line 47), even though I have set it high at line 16.
Basically, the UART never transmits anything and the TXD pin stays low after enabling the UART. It goes into an infinite loop while waiting for EVENTS_ENDTX to get set (line 58).
I have tried to implement the workaround for errata 23 as well. However, using the debugger, I can see that the registers in question (addresses 0x50008564 and 0x50008568) are both zero at startup, so maybe this is not applicable to my revision of the nRF9160? The program never enters the "if" statements at line 33 and 36.
What I have not tried are the PUBLISH and SUBSCRIBE registers. Do I need to use DPPI channels for my single-threaded application?
By the way, I have tried UARTE1 as well. And different GPIOs for TXD. Same results. I also tried to use SPIM. Same story. As soon as the peripheral is enabled, the GPIOs go low, even though they should be high. And tasks and events appear to be not working.
I am using the linker script, startup code and system code from the nrfx library found at github.com/.../nrfx:
mdk/nrf9160_xxaa.ld
mdk/gcc_startup_nrf9160.S
mdk/system_nrf9160.c
Any ideas on what could be wrong are highly appreciated. Thanks in advance :-)
#include "nrfx.h"
int main()
{
// Use the HFXO as the high frequency clock
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while (! NRF_CLOCK->EVENTS_HFCLKSTARTED); // Wait for the clock to start
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
// The primary virtual COM port on nRF9160 DK is using the following pins:
// P0.26 CTS, P0.27 RTS, P0.28 RXD and P0.29 TXD
// Configure the GPIOs
NRF_P0->DIRCLR = (1<<28) | (1<<26); // Set RXD and CTS pins as inputs
NRF_P0->DIRSET = (1<<29) | (1<<27); // Set TXD and RTS pins as outputs
NRF_P0->OUTSET = (1<<29) | (1<<29); // Set TXD and RTS pins high
// Route the UARTE0 pins to the above GPIOs
NRF_UARTE0->PSEL.CTS = 26;
NRF_UARTE0->PSEL.RTS = 27;
NRF_UARTE0->PSEL.RXD = 28;
NRF_UARTE0->PSEL.TXD = 29;
// Configure the UART with no hardware flow control, no parity bit, one
// stop bit and a baud rate of 115200.
NRF_UARTE0->CONFIG = 0;
NRF_UARTE0->BAUDRATE = 0x01D60000ul;
// -------- Errata [23] UART: TASKS_RESUME impacts UARTE ------------------
volatile uint32_t* RXENABLE = (volatile uint32_t*)0x50008564ul;
volatile uint32_t* TXENABLE = (volatile uint32_t*)0x50008568ul;
if (*TXENABLE == 1)
NRF_UARTE0->TASKS_STOPTX = 1; // Trigger TASKS_STOPTX
if (*RXENABLE == 1)
{
NRF_UARTE0->ENABLE = 1; // Enable UARTE
NRF_UARTE0->TASKS_STOPRX = 1; // Trigger TASKS_STOPRX
while (*RXENABLE != 0); // Wait until RXENABLE reads '0'
NRF_UARTE0->ERRORSRC = 0; // Clear ERRORSRC register
}
// -----------------------------------------------------------------------
// Enable the UART
NRF_UARTE0->ENABLE = 1;
// Set up the UART to transmit these bytes
const uint8_t data[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
NRF_UARTE0->TXD.MAXCNT = 4;
NRF_UARTE0->TXD.PTR = (uint32_t)data;
// Main loop that repeatedly transmits the above data
while (1)
{
NRF_UARTE0->TASKS_STARTTX = 1; // Start the transmission
while (! NRF_UARTE0->EVENTS_ENDTX); // Wait for transmission to finish
NRF_UARTE0->EVENTS_ENDTX = 0; // Clear the ENDTX event
}
}
