Topics

How to setup an UART with flow control (RTS&CTS )? #stm32 #uart #flowcontrol


Stefan Jaritz
 

Hey,

I am playing around with Zephyr OS and a STM32F412 on my own board. Now I like to use uart3 to connect to a other SOC. As far as I have seen, is no simple uart example in the sample section. So it is difficult for me to figure out how to take the initial steps.

I am struggling to configure my UART to do the RTS CTS flow control in hardware and are not sure if my current steps are right.

Maybe someone can give me some advice or hint how to solve that problem. Merci :D


What I figured out so far:

1.) I activated the uart in my dts board file:

&usart3 {
    current-speed = <57600>;
    pinctrl-0 = <&usart3_pins_c>;
    pinctrl-names = "default";
    status = "ok";
};

2.) I activated the UART3 through the board defconfig file

CONFIG_SERIAL=y
CONFIG_UART_STM32_PORT_1=y
CONFIG_UART_STM32_PORT_3=y

3.) I activated UART ISR driven in my prj.conf

CONFIG_UART_INTERRUPT_DRIVEN=y

4.) I wrote some code in my main:

static void myuart_uart_isr(struct device *uart)
{
    int rx;
    char buffer[255];

    while (uart_irq_update(uart) &&
           uart_irq_is_pending(uart)) {

        if (!uart_irq_rx_ready(uart)) {
            if (uart_irq_tx_ready(uart)) {
                printk("transmit ready");
            } else {
                printk("spurious interrupt");
            }
            /* Only the UART RX path is interrupt-enabled */
            break;
        }
        rx = uart_fifo_read(uart, buffer, sizeof(buffer)-1);
        buffer[rx] = 0;
        printk("rx: %s\n", buffer);
    }
}

static int myuart_send(struct device *uart, char * szStr) {
    size_t i;
    unsigned char temp;
    for (i = 0; i < strlen(szStr); i++) {
        temp = szStr[i];
        temp = uart_poll_out(uart, temp);
    }
}

#define myuart_ONOF_GPIO "GPIOC"
#define myuart_ONOF_PC10 (10)
#define myuart_UART "UART_3"

static void myuartThread(void) {
    struct device * uart;
    struct device * onoffGPIO;


    onoffGPIO = device_get_binding(myuart_ONOF_GPIO);
    if (!onoffGPIO) {
        printk("Cannot find %s!\n", myuart_ONOF_GPIO);
        return;
    }
    printk("start myuart thread\n");

    if (gpio_pin_configure(onoffGPIO, myuart_ONOF_PC10, GPIO_DIR_OUT)) {
        printk("Error configuring " myuart_ONOF_GPIO "%d!\n", myuart_ONOF_PC10);
    }

    // uart setup
    uart = device_get_binding(myuart_UART);
    if (!uart) {
        printk("Cannot find myuart uart(%s)!\n", myuart_UART);
        return;
    }

    uart_irq_rx_disable(uart);
    uart_irq_tx_disable(uart);

    uart_irq_callback_set(uart, myuart_uart_isr);

    uart_irq_rx_enable(uart);


    printk("myuart rst HIGH -> myuart is on now\n");
    gpio_pin_write(onoffGPIO, myuart_ONOF_PC10, 1);
    k_sleep(MSEC_PER_SEC * 1);
    myuart_send(uart,"version\r");


    printk("myuart thread finished");
}


K_THREAD_DEFINE(myuartThread_id, STACKSIZE, myuartThread, NULL, NULL, NULL, PRIORITY, 0, K_NO_WAIT);


Erwan Gouriou
 

Hi Stefan

There is a PR opened on this exact topic: https://github.com/zephyrproject-rtos/zephyr/pull/8306
I suggest you have a look.

Hih
Cheers
Erwan


On Thu, 28 Jun 2018 at 20:56, Stefan Jaritz <stefan@...> wrote:
Hey,

I am playing around with Zephyr OS and a STM32F412 on my own board. Now
I like to use uart3 to connect to a other SOC. As far as I have seen, is
no simple uart example in the sample section. So it is difficult for me
to figure out how to take the initial steps.

I am struggling to configure my UART to do the RTS CTS flow control in
hardware and are not sure if my current steps are right.

Maybe someone can give me some advice or hint how to solve that problem.
Merci :D


What I figured out so far:

1.) I activated the uart in my dts board file:

&usart3 {
     current-speed = <57600>;
     pinctrl-0 = <&usart3_pins_c>;
     pinctrl-names = "default";
     status = "ok";
};

2.) I activated the UART3 through the board defconfig file

CONFIG_SERIAL=y
CONFIG_UART_STM32_PORT_1=y
CONFIG_UART_STM32_PORT_3=y

3.) I activated UART ISR driven in my prj.conf

CONFIG_UART_INTERRUPT_DRIVEN=y

4.) I wrote some code in my main:

static void myuart_uart_isr(struct device *uart)
{
     int rx;
     char buffer[255];

     while (uart_irq_update(uart) &&
            uart_irq_is_pending(uart)) {

         if (!uart_irq_rx_ready(uart)) {
             if (uart_irq_tx_ready(uart)) {
                 printk("transmit ready");
             } else {
                 printk("spurious interrupt");
             }
             /* Only the UART RX path is interrupt-enabled */
             break;
         }
         rx = uart_fifo_read(uart, buffer, sizeof(buffer)-1);
         buffer[rx] = 0;
         printk("rx: %s\n", buffer);
     }
}

static int myuart_send(struct device *uart, char * szStr) {
     size_t i;
     unsigned char temp;
     for (i = 0; i < strlen(szStr); i++) {
         temp = szStr[i];
         temp = uart_poll_out(uart, temp);
     }
}

#define myuart_ONOF_GPIO "GPIOC"
#define myuart_ONOF_PC10 (10)
#define myuart_UART "UART_3"

static void myuartThread(void) {
     struct device * uart;
     struct device * onoffGPIO;


     onoffGPIO = device_get_binding(myuart_ONOF_GPIO);
     if (!onoffGPIO) {
         printk("Cannot find %s!\n", myuart_ONOF_GPIO);
         return;
     }
     printk("start myuart thread\n");

     if (gpio_pin_configure(onoffGPIO, myuart_ONOF_PC10, GPIO_DIR_OUT)) {
         printk("Error configuring " myuart_ONOF_GPIO "%d!\n",
myuart_ONOF_PC10);
     }

     // uart setup
     uart = device_get_binding(myuart_UART);
     if (!uart) {
         printk("Cannot find myuart uart(%s)!\n", myuart_UART);
         return;
     }

     uart_irq_rx_disable(uart);
     uart_irq_tx_disable(uart);

     uart_irq_callback_set(uart, myuart_uart_isr);

     uart_irq_rx_enable(uart);


     printk("myuart rst HIGH -> myuart is on now\n");
     gpio_pin_write(onoffGPIO, myuart_ONOF_PC10, 1);
     k_sleep(MSEC_PER_SEC * 1);
     myuart_send(uart,"version\r");


     printk("myuart thread finished");
}


K_THREAD_DEFINE(myuartThread_id, STACKSIZE, myuartThread, NULL, NULL,
NULL, PRIORITY, 0, K_NO_WAIT);