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