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

Enabling UARTs on PO Lines to Connect Peripheral

Hello and Thank you In Advance for Your Assistance.  I have been working several days just to get a UART running for interface to a peripheral.

I am trying to connect a UART peripheral to my nRF9160DK board on the PO lines.  I have followed Case ID 226331.to get the UART0 and UART1 connected.  

My overall project requires an HTTP connection to GET data from a server over the modem and pass it to 2 UART based peripherals.  I downloaded the http sample from GitHub and have succeeded in integrating it to download 2 sets of data from a server as text strings.  I need to pass them out the UARTs to the peripherals.  Following the instructions on Case ID 226331, I have modified the prj.conf file and created the nrf9160_pca10090.overlay file.

If I just enable the UART0, It appears that I am sending out data on the TX but I do not get any signal changes on the PO.28 pin (it remains a low level).

Here is the prj.conf file:

CONFIG_BSD_LIBRARY=y
CONFIG_GPIO=n
CONFIG_SERIAL=y
CONFIG_STDOUT_CONSOLE=y
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_BOARD_PCA10090_UART0_ARDUINO=y
CONFIG_BOARD_PCA10090_UART1_ARDUINO=y
CONFIG_UART_0_NRF_UARTE=y
CONFIG_UART_1_NRF_UARTE=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_NETWORKING=y
CONFIG_NET_BUF_USER_DATA_SIZE=1
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_NET_RAW_MODE=y
CONFIG_TRUSTED_EXECUTION_NONSECURE=y
CONFIG_LOG=n
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_HEAP_MEM_POOL_SIZE=1024
# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_MAIN_STACK_SIZE=4096

Here is the nrf9160_pca10090.overlay file:

/*Uart 0*/
&uart0 {
	current-speed = <115200>;
	status = "ok";
	tx-pin = <10>;
	rx-pin = <11>;
	rts-pin = <12>;
	cts-pin = <13>;
};
/*end of code added by Johnny Lienau on March 4*/

/* Uart 1 */
&uart1 {
	current-speed = <115200>;
	status = "ok";
	tx-pin = <25>; 
	rx-pin = <26>; 
	rts-pin = <27>;
	cts-pin = <28>;
};

Here is the code to init the UARTS:

        //////////UART setup
	struct device *uart0 = device_get_binding("UART_0");
	uart_irq_callback_set(uart0, uart_cb0);
	uart_irq_rx_enable(uart0);
        printk("uart0 ready\n");

	struct device *uart1 = device_get_binding("UART_1");
	uart_irq_callback_set(uart1, uart_cb1);
	uart_irq_rx_enable(uart1);
        printk("uart1 ready\n");

Here are the call backs and transmit function:

static u8_t uart_buf[1024];
static char *command0 = "This Is A Test of UART0\r\n";
static char *command1 = "This Is A Test of UART1\r\n";
u8_t i = 0;

void uart_cb0(struct device *x)
{
	uart_irq_update(x); //start processing interrupts in the ISR
	int data_length = 0;
        printk("Callback!\r\n");
	if (uart_irq_rx_ready(x)) { //check if UART RX buffer has a received char
		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf)); //read ata from FIFO
		uart_buf[data_length] = 0;
	}
	printk("%s", uart_buf);
}

void uart_cb1(struct device *x)
{
	uart_irq_update(x);
	int data_length = 0;
        printk("Callback!\r\n");
	if (uart_irq_rx_ready(x)) {
		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
		uart_buf[data_length] = 0;
	}
	printk("%s", uart_buf);
}


void uart_send_str(struct device *uart, char *str){
    printk("Transmit!\r\n");
    u32_t len = strlen(str);
    while (len--) {
        uart_poll_out(uart, *str++);
    }
}

Here is the code to send data out of the UARTs (only UART0 is being tested first)

        uart_send_str(uart0, command0);
        //uart_send_str(uart1, command1);

	while (1) {
                uart_send_str(uart1, command0);
                //uart_send_str(uart0, command1);
		k_cpu_idle();
	}

MY PROBLEMS:

1. If I try to init uart1 it compiles fine but I get the following error during run debug time:

2.  If I comment out the UART1 init, the program runs and it appears that UART0  is transmitting the test data but there is no output on PO.28 (it is not even high during idle);

My objective is to be able to set UART1 to 9600 baud for my peripheral and leave UART0 at 115200. 

Below is my entire main.c (except I have changed the server to a false name so I do not get any hits on it).  The GET functions work fine and my data is collected over the modem in about 6 seconds from a cold start.  For testing of the UARTs, I have also commented out the HTTP calls in the main loop to allow for initial testing of the UARTs.

I would greatly appreciate any help you can provide.  I have gone through several posts but they all are specific to other issues and do not provide enough basic information on how to simply set up a UART on the nRF9160 board.

I will also need several GPIO pins, ADCs, and PWMs going out through the PO connectors from the nRF9160.  I would also appreciate any guidance and basic overview of this process.

.

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include <zephyr.h>
#include <net/socket.h>
#include <stdio.h>
#include <uart.h>
#include <string.h>

//#define HTTP_HOST "google.com"
//#define HTTP_PORT 80
//#define RECV_BUF_SIZE 8192

/********************
static u8_t uart_buf[1024];

void uart_cb(struct device *x)
{
	uart_irq_update(x);
	int data_length = 0;

	if (uart_irq_rx_ready(x)) {
		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
		uart_buf[data_length] = 0;
	}
	printk("%s", uart_buf);
}
******************/
static u8_t uart_buf[1024];
static char *command0 = "This Is A Test of UART0\r\n";
static char *command1 = "This Is A Test of UART1\r\n";
u8_t i = 0;

void uart_cb0(struct device *x)
{
	uart_irq_update(x); //start processing interrupts in the ISR
	int data_length = 0;
        printk("Callback!\r\n");
	if (uart_irq_rx_ready(x)) { //check if UART RX buffer has a received char
		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf)); //read ata from FIFO
		uart_buf[data_length] = 0;
	}
	printk("%s", uart_buf);
}

void uart_cb1(struct device *x)
{
	uart_irq_update(x);
	int data_length = 0;
        printk("Callback!\r\n");
	if (uart_irq_rx_ready(x)) {
		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
		uart_buf[data_length] = 0;
	}
	printk("%s", uart_buf);
}


void uart_send_str(struct device *uart, char *str){
    printk("Transmit!\r\n");
    u32_t len = strlen(str);
    while (len--) {
        uart_poll_out(uart, *str++);
    }
}



#define HTTP_HOST "dev1.otp.myserver.info"
#define HTTP_PORT 80
#define RECV_BUF_SIZE 8192
char recv_buf[RECV_BUF_SIZE + 1];
char header_store[RECV_BUF_SIZE + 1];

int blocking_recv(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;

	do {
		err = recv(fd, buf, size, flags);
	} while (err < 0 && errno == EAGAIN);

	return err;
}

int blocking_send(int fd, u8_t *buf, u32_t size, u32_t flags)
{
	int err;

	do {
		err = send(fd, buf, size, flags);
	} while (err < 0 && errno == EAGAIN);

	return err;
}

int blocking_connect(int fd, struct sockaddr *local_addr, socklen_t len)
{
	int err;

	do {
		err = connect(fd, local_addr, len);
	} while (err < 0 && errno == EAGAIN);

	return err;
}

void app_http_get_header(void)
{
	struct sockaddr_in local_addr;
	struct addrinfo *res;

	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(0);
	local_addr.sin_addr.s_addr = 0;

	printk("HTTP example\n\r");

	int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);

	printk("getaddrinfo err: %d\n\r", err);
	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);

        //http://dev1.otp.myserver.info/rt/dev_test_falcon_20190722/sample_body?k=falcon_key&format=text  
	char send_buf[] =
                "GET /rt/dev_test_falcon_20190722/sample_header?k=falcon_key&format=text HTTP/1.1\r\nHost:dev1.otp.myserver.info:80\r\nConnection: close\r\n\r\n";
        //char send_buf[] =
        //        "GET /rt/dev_test_falcon_20190722/sample_body?k=falcon_key&format=text HTTP/1.1\r\nHost:dev1.otp.myserver.info:80\r\nConnection: close\r\n\r\n";
	//char send_buf[] =
	//	"GET / HTTP/1.1\r\nHost: www.google.com:80\r\nConnection: close\r\n\r\n";
	int send_data_len = strlen(send_buf);

	int client_fd = socket(AF_INET, SOCK_STREAM, 0);

	printk("client_fd: %d\n\r", client_fd);
	err = bind(client_fd, (struct sockaddr *)&local_addr,
		   sizeof(local_addr));
	printk("bind err: %d\n\r", err);
	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
			       sizeof(struct sockaddr_in));
	printk("connect err: %d\n\r", err);
        printk("COMMAND USED: %s\r\n",send_buf); 

	int num_bytes = send(client_fd, send_buf, send_data_len, 0);

	printk("send err: %d\n\r", num_bytes);

	//int tot_num_bytes = 0;
        //bool buf_rcvd = false;

	//do {
		/* TODO: make a proper timeout *
		 * Current solution will just hang 
		 * until remote side closes connection */
		num_bytes =
			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
		//tot_num_bytes += num_bytes;
                printk("\r\nnum_bytes = %i\r\n",num_bytes);
		//if (num_bytes <= 0) {
		//	break;
		//}
		printk("%s\r\n", recv_buf);
                //header_store = recv_buf;
                printk("Got Here!\r\n");
                printk("Finished. Closing socket\r\n");
                freeaddrinfo(res);
                err = close(client_fd);
}

void app_http_get_body(void)
{
	struct sockaddr_in local_addr;
	struct addrinfo *res;

	local_addr.sin_family = AF_INET;
	local_addr.sin_port = htons(0);
	local_addr.sin_addr.s_addr = 0;

	printk("HTTP example\n\r");


	int err = getaddrinfo(HTTP_HOST, NULL, NULL, &res);

	printk("getaddrinfo err: %d\n\r", err);
	((struct sockaddr_in *)res->ai_addr)->sin_port = htons(HTTP_PORT);

        //http://dev1.otp.myserver.info/rt/dev_test_falcon_20190722/sample_body?k=falcon_key&format=text  
	//char send_buf[] =
        //        "GET /rt/dev_test_falcon_20190722/sample_header?k=falcon_key&format=text HTTP/1.1\r\nHost:dev1.otp.mmyserverytransit.info:80\r\nConnection: close\r\n\r\n";
        char send_buf[] =
                "GET /rt/dev_test_falcon_20190722/sample_body?k=falcon_key&format=text HTTP/1.1\r\nHost:dev1.otp.myserver.info:80\r\nConnection: close\r\n\r\n";
	//char send_buf[] =
	//	"GET / HTTP/1.1\r\nHost: www.google.com:80\r\nConnection: close\r\n\r\n";
	int send_data_len = strlen(send_buf);

	int client_fd = socket(AF_INET, SOCK_STREAM, 0);

	printk("client_fd: %d\n\r", client_fd);
	err = bind(client_fd, (struct sockaddr *)&local_addr,
		   sizeof(local_addr));
	printk("bind err: %d\n\r", err);
	err = blocking_connect(client_fd, (struct sockaddr *)res->ai_addr,
			       sizeof(struct sockaddr_in));
	printk("connect err: %d\n\r", err);
        printk("COMMAND USED: %s\r\n",send_buf); 

	int num_bytes = send(client_fd, send_buf, send_data_len, 0);

	printk("send err: %d\n\r", num_bytes);

	//int tot_num_bytes = 0;
        //bool buf_rcvd = false;

	//do {
		num_bytes =
			blocking_recv(client_fd, recv_buf, RECV_BUF_SIZE, 0);
		//tot_num_bytes += num_bytes;
                printk("\r\nnum_bytes = %i\r\n",num_bytes);
		//if (num_bytes <= 0) {
		//	break;
		//}
		printk("%s\r\n", recv_buf);
                printk("Got Here!\r\n");
                printk("Finished. Closing socket\r\n");
                freeaddrinfo(res);
                err = close(client_fd);
}

int main(void)
{
	//app_http_get_header();
	//app_http_get_body();

        //////////UART setup
	struct device *uart0 = device_get_binding("UART_0");
	uart_irq_callback_set(uart0, uart_cb0);
	uart_irq_rx_enable(uart0);
        printk("uart0 ready\n");

	struct device *uart1 = device_get_binding("UART_1");
	uart_irq_callback_set(uart1, uart_cb1);
	uart_irq_rx_enable(uart1);
        printk("uart1 ready\n");

        //struct device *uart = device_get_binding("UART_0");
	//uart_irq_callback_set(uart, uart_cb);
	//uart_irq_rx_enable(uart);
	//printk("UART loopback start!\n");
        ////////////

        uart_send_str(uart0, command0);
        //uart_send_str(uart1, command1);

	while (1) {
                uart_send_str(uart1, command0);
                //uart_send_str(uart0, command1);
		k_cpu_idle();
	}
}

Parents
  • Hello,

    I realize you are busy and I know an engineer was assigned several days ago - however, I have not received any assistance yet.

    I am short on time so I decided to go ahead and use a SPI connection instead of UART and have encountered the same error break as follows.  I simply copied the SPI sample code main.c into the http main.c code, added the SPI3 info into the from the spi sample into the http prj.conf, and copied the .overlay files from the spi sample to the http sample main directory.

    If I continue the execution in debug, the COM23 nRFConnect LTE Link Monitor trace indicates the following.  There must be another setting somewhere to allow the SPI ISR to operate in the non-secure state.  Can someone point me to where this can be resolved.  A similar correction may be in order for the UART issue.  It is probably something simple.

    Could not get SPI_3 device
    Exception occurred in Secure State
    ***** HARD FAULT *****
      Fault escalation (see below)
    ***** BUS FAULT *****
      Precise data bus error
      BFAR Address: 0x50008120
    ***** Hardware exception *****
    Current thread ID = 0x20020134
    Faulting instruction address = 0x9300
    Fatal fault in ISR! Spinning...

    The LTE Link Monitor Trace shows the SPIM3 to be OK and non-secure as peripheral 12.

    Peripheral		Domain		Status
    00 NRF_P0		Non-Secure	OK
    01 NRF_CLOCK		Non-Secure	OK
    02 NRF_RTC1		Non-Secure	OK
    03 NRF_NVMC		Non-Secure	OK
    04 NRF_UARTE1		Non-Secure	OK
    05 NRF_UARTE2		Secure		SKIP
    06 NRF_IPC		Non-Secure	OK
    07 NRF_VMC		Non-Secure	OK
    08 NRF_FPU		Non-Secure	OK
    09 NRF_EGU1		Non-Secure	OK
    10 NRF_EGU2		Non-Secure	OK
    11 NRF_TWIM2		Non-Secure	OK
    12 NRF_SPIM3		Non-Secure	OK
    13 NRF_TIMER0		Non-Secure	OK
    14 NRF_TIMER1		Non-Secure	OK
    15 NRF_TIMER2		Non-Secure	OK
    16 NRF_SAADC		Non-Secure	OK
    17 NRF_GPIOTE1		Non-Secure	OK
    
    

    If anyone can suggest a solution, please reply.

  • Hi,

    I am sorry for the late reply.

    I am not sure what the problem is here. Which SPI example have you used? Can you try using/looking at this SPI example, which we know is functional? If yous till have problems after that, perhaps you can upload a completed project demonstrating the issue that I can test on my side?

  • Hi Gary,

    GaryD said:

    I removed the following line that was duplicated in the SPI sample - is that OK?

    CONFIG_MAIN_STACK_SIZE=4096

    Yes, that there is no point in duplicating it.

    GaryD said:
    I reading older DevZone issues relating to similar spinning ISR issues, there had been some overlaying into the softdevice firmware through errant flash pointers.  Could that be a similar issue?  If so, how would that be fixed?

    I am not sure which posts you refer to, but if it mentioned the SoftDevice it is probably not relevant. (The SoftDevice is the proprietary BLE stack we provide for the nRF51 and nRF52 devices.)

    GaryD said:
    I can upload the project to you but do not want that project public since it points to my servers and do not want to have a bunch of hits from users trying my solution for their needs.  Is that possible?

    Absolutely. You can make a private support case and upload your code there along with a description of how to test it. Please refer to this thread.

    Einar

  • Hi Einar,

    Instead of "softdevice firmware" above, I meant to say RTOS or modem firmware. 

    It appears to me that this is probably related to a Zephyr RTOS issue in that it cannot handle multiple user thread ISRs properly.

    I will open up a private thread and provide you with the code using my servers - please change servers if you need to pass this to someone else or need to to extensive testing.

    I assume I just need to zip the http sample directory that I am using - correct?

    What I need to work in the project I send you is to have the HTTP operations, SPI loopback, and a second UART operation all working within the http sample code project.  The code I will send you will not have the correct overlays for the UART to be moved to different pins.  I do not care where the UART pins are - the debug UART, a second UART, and SPI have to work concurrently with ISRs along with HTTP (modem) operations.

    Thanks a lot for your support.

    Gary

  • Hi Gary,

    Sounds good.

    GaryD said:
    I assume I just need to zip the http sample directory that I am using - correct?

    Yes. But if you have made any other changes elsewhere, then please include those as well. Also please specify which version of nRF Connect SDK you are using (I am assuming the v1.0.0 tag?).

    Einar

  • Einar,

    I have not made changes elsewhere.  The source for my project has been submitted under a private ticket.

    I loaded the SDK about 3 weeks ago - would that be 1.0.0?  How do I tell?  Here is the tag list from my nrf directory:

  • Hi,

     

    You can update to the latest tag by running the lines in the top of this blog post:

    https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/how-to-get-production-version-v1-0-0-to-nrf9160

     

    Once that is done, you should be on v1.0.0 and the other repo's should also be checked out accordingly.

     

    Kind regards,

    Håkon

Reply Children
No Data
Related