2024-10-24 04:11 AM - edited 2024-10-24 06:40 AM
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!
Solved! Go to Solution.
2024-10-28 01:05 AM
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.
2024-10-28 01:05 AM
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.