drv_rs485.c 2.4 KB

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