cancel
Showing results for 
Search instead for 
Did you mean: 

Not receiving UART messages with Zephyr on STM32L496

Liem
Associate

Hi everyone,


I am using Zephyr RTOS as a test on a custom board. I have been trying to communicate with a modem and hoping to receive an OK message whenever I send AT. With an oscilloscope or by connecting it to a USB-Serial cable, I can see that OK is being sent after receiving AT, but in my code, I couldn't manage to read this message.

I used the polling and interrupt examples that could be found in the Zephyr repos.

Polling:

 

 

void send_str(const struct device *uart, char *str)
{
	int msg_len = strlen(str);

	for (int i = 0; i < msg_len; i++) {
		uart_poll_out(uart, str[i]);
	}

	// printk("Device %s sent: \"%s\"\n", uart->name, str);
}

void recv_str(const struct device *uart, char *str)
{
	char *head = str;
	char c;

	while (!uart_poll_in(uart, &c)) {
		*head++ = c;
	}
	*head = '\0';

	printk("Device %s received: \"%s\"\n", uart->name, str);
}


int main(void)
{
	char* send_buf = "AT\r\n";
	char recv_buf[64];

    while(1)
    {
        send_str(uart_dev, send_buf);
		/* Wait some time for the messages to arrive to the second uart. */
		k_msleep(100);
		recv_str(uart_dev, recv_buf);

        k_msleep(500);
    }
}

 

 

 
Interrupt:

 

 

void serial_cb(const struct device *dev, void *user_data)
{
	uint8_t c;

	if (!uart_irq_update(uart_dev)) {
		return;
	}

	if (!uart_irq_rx_ready(uart_dev)) {
		return;
	}

	/* read until FIFO empty */
	while (uart_fifo_read(uart_dev, &c, 1) == 1) {
		if ((c == '\n' || c == '\r') && rx_buf_pos > 0) {
			/* terminate string */
			rx_buf[rx_buf_pos] = '\0';

			/* if queue is full, message is silently dropped */
			k_msgq_put(&uart_msgq, &rx_buf, K_NO_WAIT);

			/* reset the buffer (it was copied to the msgq) */
			rx_buf_pos = 0;
		} else if (rx_buf_pos < (sizeof(rx_buf) - 1)) {
			rx_buf[rx_buf_pos++] = c;
		}
		/* else: characters beyond buffer size are dropped */
	}
    printk("Value is: %s\n", rx_buf);
}

void print_uart(char *buf)
{
	int msg_len = strlen(buf);

	for (int i = 0; i < msg_len; i++) {
		uart_poll_out(uart_dev, buf[i]);
	}
    printk("Sending: %s\n", buf);
}

int main(void)
{
       int ret = uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);
    if (ret < 0) {
		if (ret == -ENOTSUP) {
			printk("Interrupt-driven UART API support not enabled\n");
		} else if (ret == -ENOSYS) {
			printk("UART device does not support interrupt-driven API\n");
		} else {
			printk("Error setting UART callback: %d\n", ret);
		}
		return 0;
	}
    uart_irq_rx_enable(uart_dev);
    while(1)
    {
        print_uart("AT\r\n");
        k_msleep(500);
    }
}

 

 

I appreciate any insights you might have thanks!

 

1 ACCEPTED SOLUTION

Accepted Solutions
Liem
Associate

I was able to fix the issue. After looking at the devicetree for a long time, I realized that my UART Rx pin was already assigned to another device. In my overlay, I just added it again without that specific pin, so my Rx is working as expected now.

View solution in original post

1 REPLY 1
Liem
Associate

I was able to fix the issue. After looking at the devicetree for a long time, I realized that my UART Rx pin was already assigned to another device. In my overlay, I just added it again without that specific pin, so my Rx is working as expected now.