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-10-24     thread-liu        first version
9  */
10 
11 #include <board.h>
12 #include "drv_rs485.h"
13 
14 #ifdef BSP_USING_RS485
15 
16 #define RS485_OUT       rt_pin_write(BSP_RS485_RTS_PIN, PIN_HIGH)
17 #define RS485_IN        rt_pin_write(BSP_RS485_RTS_PIN, PIN_LOW)
18 
19 static rt_device_t serial = {0};
20 static struct rt_semaphore rx_sem = {0};
21 
22 /* uart send data callback function */
rs485_output(rt_device_t dev,void * buffer)23 static rt_err_t rs485_output(rt_device_t dev, void * buffer)
24 {
25     return RT_EOK;
26 }
27 
28 /* uart receive data callback function */
rs485_input(rt_device_t dev,rt_size_t size)29 static rt_err_t rs485_input(rt_device_t dev, rt_size_t size)
30 {
31     rt_sem_release(&rx_sem);
32 
33     return RT_EOK;
34 }
35 
36 /* send string */
rs485_send_data(char * tbuf,rt_uint16_t t_len)37 int rs485_send_data(char *tbuf, rt_uint16_t t_len)
38 {
39     /* change rs485 mode */
40     RS485_OUT;
41 
42     /* send data */
43     rt_device_write(serial, 0, tbuf, t_len);
44 
45     /* change rs485 mode */
46     RS485_IN;
47 
48     return RT_EOK;
49 }
50 
rs485_thread_entry(void * parameter)51 static void rs485_thread_entry(void *parameter)
52 {
53     char ch;
54 
55     while (1)
56     {
57         /* A byte of data is read from a serial port, and if it is not read, it waits for the received semaphore */
58         while (rt_device_read(serial, -1, &ch, 1) != 1)
59         {
60             rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
61         }
62 
63         /* The data read through the serial port output dislocation */
64         ch = ch + 1;
65 
66         /* send char */
67         rs485_send_data(&ch, 1);
68     }
69 }
70 
71 /* rs485 rts pin init */
rs485_init(void)72 static int rs485_init(void)
73 {
74     /* find uart device */
75     serial = rt_device_find(RS485_UART_DEVICE_NAME);
76     if (!serial)
77     {
78         rt_kprintf("find %s failed!\n", RS485_UART_DEVICE_NAME);
79         return -RT_ERROR;
80     }
81 
82     rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
83 
84     /* set receive data callback function */
85     rt_device_set_rx_indicate(serial, rs485_input);
86 
87     /* set the send completion callback function */
88     rt_device_set_tx_complete(serial, rs485_output);
89 
90     rt_pin_mode(BSP_RS485_RTS_PIN, PIN_MODE_OUTPUT);
91 
92     RS485_IN;
93 
94     rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
95     /* create rs485 thread */
96     rt_thread_t thread = rt_thread_create("rs485", rs485_thread_entry, RT_NULL, 1024, 25, 10);
97 
98     if (thread != RT_NULL)
99     {
100         rt_thread_startup(thread);
101     }
102     else
103     {
104         return -RT_ERROR;
105     }
106 
107     return RT_EOK;
108 }
109 INIT_DEVICE_EXPORT(rs485_init);
110 
111 #endif /* bsp_using_RS485 */
112