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