Enabling UART on nRF9161 DK for application use?

From what I can see in the documentation, UART0 is used by default for "non-secure" / application logs and UART1 is used for "secure" app logs. I am needing to interface with another MCU using UART, but I'm having a hard time figuring out how to enable my non-secure portion of the app access this peripheral.

To start with, I disabled UART0 for app logging, switching to J-Link RTT:

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

With the above, I am able to use the J-Link RTT Viewer to view my app logs instead of the VCOM0 / UART for logs.

I then added the following to my device tree overlay:

&pinctrl {
	uart0_default: uart0_default {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 27)>,
				<NRF_PSEL(UART_RTS, 0, 14)>;
		};
		group2 {
			psels = <NRF_PSEL(UART_RX, 0, 26)>,
				<NRF_PSEL(UART_CTS, 0, 15)>;
			bias-pull-up;
		};
	};

	uart0_sleep: uart0_sleep {
		group1 {
			psels = <NRF_PSEL(UART_TX, 0, 27)>,
				<NRF_PSEL(UART_RX, 0, 26)>,
				<NRF_PSEL(UART_RTS, 0, 14)>,
				<NRF_PSEL(UART_CTS, 0, 15)>;
			low-power-enable;
		};
	};
};

&uart0 {
	status = "okay";
	current-speed = <115200>;
	pinctrl-0 = <&uart0_default>;
	pinctrl-1 = <&uart0_sleep>;
	pinctrl-names = "default", "sleep";
	hw-flow-control;
};

I am setting it up like so:

#define UART_DEV DEVICE_DT_GET(DT_NODELABEL(uart0))

static void uart_cb(const struct device *dev, struct uart_event *evt, void *user_data) {
    LOG_INF("GOT UART FRAME!");
    switch (evt->type) {
        case UART_RX_RDY:
            // do stuff (truncated)
            break;

        case UART_RX_DISABLED:
            // RX buffer got full or RX stopped, re-enable to continue receiving
            uart_rx_enable(UART_DEV, rx_buf, sizeof(rx_buf), SYS_FOREVER_MS);
            break;

        case UART_RX_STOPPED:
            LOG_ERR("UART RX stopped unexpectedly!");
            uart_rx_enable(UART_DEV, rx_buf, sizeof(rx_buf), SYS_FOREVER_MS);
            break;

        default:
            break;
    }
}

int uart_setup(void) {
    LOG_INF("Setting up UART...");
    if (!device_is_ready(UART_DEV)) {
        LOG_ERR("Device not ready for UART");
        return -1;
    }
    LOG_INF("Setting up UART callback...");
    uart_callback_set(UART_DEV, uart_cb, NULL);

    LOG_INF("Enabling UART transmission...");
    uart_rx_enable(UART_DEV, rx_buf, sizeof(rx_buf), SYS_FOREVER_MS);

    return 0;
}

When that uart_rx_enable() function is called, I get a SECURE FAULT:

[00:00:09.517,822] <inf> testapp: Setting up UART...
[00:00:09.518,188] <inf> testapp: Setting up UART callback...
[00:00:09.518,554] <inf> testapp: Enabling UART transmission...
[00:00:09.521,484] <err> os: ***** SECURE FAULT *****
[00:00:09.521,850] <err> os:   Invalid entry point
[00:00:09.522,216] <err> os: r0/a1:  0x00059638  r1/a2:  0x2001d333  r2/a3:  0x00000320
[00:00:09.522,796] <err> os: r3/a4:  0xffffffff r12/ip:  0x00000000 r14/lr:  0x0001e3d3
[00:00:09.523,315] <err> os:  xpsr:  0x00000000
[00:00:09.523,712] <err> os: s[ 0]:  0x00000000  s[ 1]:  0x2002cc04  s[ 2]:  0x00000000  s[ 3]:  0x0004772b
[00:00:09.524,444] <err> os: s[ 4]:  0x2002cc00  s[ 5]:  0x00000002  s[ 6]:  0x00000001  s[ 7]:  0x0002e0c9
[00:00:09.525,146] <err> os: s[ 8]:  0x00000010  s[ 9]:  0x00000000  s[10]:  0x2001ce90  s[11]:  0x0003fe03
[00:00:09.525,848] <err> os: s[12]:  0x0000002a  s[13]:  0x00000020  s[14]:  0x00000000  s[15]:  0x00000000
[00:00:09.526,519] <err> os: fpscr:  0x00000000
[00:00:09.526,916] <err> os: Faulting instruction address (r15/pc): 0x00000000
[00:00:09.527,374] <err> os: >>> ZEPHYR FATAL ERROR 38: Unknown error on CPU 0
[00:00:09.527,862] <err> os: Current thread: 0x20013088 (unknown)
[00:00:09.528,289] 31m<err> os: Halting system[0m

Any ideas? I am nearly at a point now where I'm about to just switch to I2C or something else between the two MCUs.

Parents Reply Children
No Data
Related