1 /*
2  * Copyright (c) 2006-2021, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2020-12-10     thread-liu   first version
9  */
10 
11 #include <board.h>
12 
13 #if defined(BSP_UART3_RX_USING_DMA) || defined(BSP_USING_UART3)
14 
15 #include <rtthread.h>
16 
17 #define SAMPLE_UART_NAME       "uart3"      /* serial device name */
18 
19 struct rx_msg
20 {
21     rt_device_t dev;
22     rt_size_t size;
23 };
24 static rt_device_t serial;
25 static struct rt_messagequeue rx_mq;
26 
uart_input(rt_device_t dev,rt_size_t size)27 static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
28 {
29     struct rx_msg msg;
30     rt_err_t result;
31     msg.dev = dev;
32     msg.size = size;
33 
34     result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
35     if ( result == -RT_EFULL)
36     {
37         rt_kprintf("message queue full!\n");
38     }
39     return result;
40 }
41 
serial_thread_entry(void * parameter)42 static void serial_thread_entry(void *parameter)
43 {
44     struct rx_msg msg;
45     rt_err_t result;
46     rt_uint32_t rx_length;
47     static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1];
48 
49     while (1)
50     {
51         rt_memset(&msg, 0, sizeof(msg));
52         result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
53         if (result >= 0)
54         {
55             rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
56             rx_buffer[rx_length] = '\0';
57             rt_device_write(serial, 0, rx_buffer, rx_length);
58         }
59     }
60 }
61 
uart_dma_sample(int argc,char * argv[])62 static int uart_dma_sample(int argc, char *argv[])
63 {
64     rt_err_t ret = RT_EOK;
65     char uart_name[RT_NAME_MAX];
66     static char msg_pool[256];
67     char str[] = "hello RT-Thread!\r\n";
68 
69     if (argc == 2)
70     {
71         rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
72     }
73     else
74     {
75         rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
76     }
77 
78     serial = rt_device_find(uart_name);
79     if (!serial)
80     {
81         rt_kprintf("find %s failed!\n", uart_name);
82         return -RT_ERROR;
83     }
84 
85     rt_mq_init(&rx_mq, "rx_mq",
86                msg_pool,
87                sizeof(struct rx_msg),
88                sizeof(msg_pool),
89                RT_IPC_FLAG_FIFO);
90 
91     ret = rt_device_open(serial, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
92     if (ret != RT_EOK)
93     {
94         rt_kprintf("serial device open fail!.\n");
95         return -RT_ERROR;
96     }
97 
98     ret = rt_device_set_rx_indicate(serial, uart_input);
99     if (ret != RT_EOK)
100     {
101         rt_kprintf("set rx indicate fail!.\n");
102         return -RT_ERROR;
103     }
104 
105     rt_device_write(serial, 0, str, (sizeof(str) - 1));
106 
107     rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
108     if (thread != RT_NULL)
109     {
110         rt_thread_startup(thread);
111     }
112     else
113     {
114         ret = -RT_ERROR;
115     }
116 
117     return ret;
118 }
119 MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
120 
121 #endif /* BSP_USING_DMA */
122