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  * 2023-05-05     yuanjie           add test method
10  */
11 
12 #include <rtdevice.h>
13 #include <board.h>
14 #include <drv_gpio.h>
15 #include "drv_rs485.h"
16 
17 #ifdef BSP_USING_RS485
18 
19 #define RS485_OUT       rt_pin_write(BSP_RS485_RTS_PIN, PIN_HIGH)
20 #define RS485_IN        rt_pin_write(BSP_RS485_RTS_PIN, PIN_LOW)
21 
22 rt_device_t rs485_serial = {0};
23 struct rt_semaphore rs485_rx_sem = {0};
24 
25 /* uart send data callback function */
rs485_output(rt_device_t dev,void * buffer)26 static rt_err_t rs485_output(rt_device_t dev, void * buffer)
27 {
28     return RT_EOK;
29 }
30 
31 /* uart receive data callback function */
rs485_input(rt_device_t dev,rt_size_t size)32 static rt_err_t rs485_input(rt_device_t dev, rt_size_t size)
33 {
34     rt_sem_release(&rs485_rx_sem);
35 
36     return RT_EOK;
37 }
38 
39 /* send string */
rs485_send_data(char * tbuf,rt_uint16_t t_len)40 int rs485_send_data(char *tbuf, rt_uint16_t t_len)
41 {
42     /* change rs485 mode */
43     RS485_OUT;
44 
45     /* send data */
46     rt_device_write(rs485_serial, 0, tbuf, t_len);
47 
48     /* change rs485 mode */
49     RS485_IN;
50 
51     rt_kprintf("\nsend:");
52     for(int i =0;i<t_len;i++)
53     {
54         rt_kprintf("%d:%x ",i,tbuf[i]);
55     }
56     return RT_EOK;
57 }
58 
59 #ifndef BSP_USING_LED_MATRIX_RS485_DEMO
rs485_thread_entry(void * parameter)60 static void rs485_thread_entry(void *parameter)
61 {
62     char ch;
63 
64     while (1)
65     {
66         /* A byte of data is read from a rs485_serial port, and if it is not read, it waits for the received semaphore */
67         while (rt_device_read(rs485_serial, -1, &ch, 1) != 1)
68         {
69             rt_sem_take(&rs485_rx_sem, RT_WAITING_FOREVER);
70         }
71         // rt_kprintf("%c",ch);
72     }
73 }
74 #endif
75 
76 /* rs485 rts pin init */
rs485_init(void)77 int rs485_init(void)
78 {
79     /* find uart device */
80     rs485_serial = rt_device_find(RS485_UART_DEVICE_NAME);
81     if (!rs485_serial)
82     {
83         rt_kprintf("find %s failed!\n", RS485_UART_DEVICE_NAME);
84         return -RT_ERROR;
85     }
86 
87     rt_device_open(rs485_serial, RT_DEVICE_FLAG_INT_RX);
88 
89     /* set receive data callback function */
90     rt_device_set_rx_indicate(rs485_serial, rs485_input);
91 
92     /* set the send completion callback function */
93     rt_device_set_tx_complete(rs485_serial, rs485_output);
94 
95     rt_pin_mode(BSP_RS485_RTS_PIN, PIN_MODE_OUTPUT);
96 
97     RS485_IN;
98 
99     rt_sem_init(&rs485_rx_sem, "rs485_rx_sem", 0, RT_IPC_FLAG_FIFO);
100 #ifndef BSP_USING_LED_MATRIX_RS485_DEMO
101     /* create rs485 receive thread */
102      rt_thread_t thread = rt_thread_create("rs485", rs485_thread_entry, RT_NULL, 1024, 25, 10);
103 #else
104     extern void led_matrix_receieve_task(void *parameter);
105     rt_thread_t thread = rt_thread_create("rs485", led_matrix_receieve_task, RT_NULL, 1024, 20, 10);
106 #endif
107 
108     if (thread != RT_NULL)
109     {
110         rt_thread_startup(thread);
111     }
112     else
113     {
114         return -RT_ERROR;
115     }
116 
117     return RT_EOK;
118 }
119 // INIT_DEVICE_EXPORT(rs485_init);
120 
rs485_test(int argc,void ** argv)121 void rs485_test(int argc, void **argv)
122 {
123     char *str;
124     if (argc == 1)
125     {
126         rt_kprintf("-t  --Enter any keys to send.\n");
127     }
128     else if (argc == 3)
129     {
130         if (rt_strcmp(argv[1], "-t") == 0)
131         {
132             str = argv[2];
133             rs485_send_data(str, rt_strnlen(str, 32));
134         }
135     }
136 }
137 MSH_CMD_EXPORT(rs485_test, test rs485 transmission);
138 
139 #endif /* BSP_USING_RS485 */
140