mb_bsp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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-11-21 Meco Man the first verion
  9. */
  10. /*
  11. *********************************************************************************************************
  12. * uC/Modbus
  13. * The Embedded Modbus Stack
  14. *
  15. * Copyright 2003-2020 Silicon Laboratories Inc. www.silabs.com
  16. *
  17. * SPDX-License-Identifier: APACHE-2.0
  18. *
  19. * This software is subject to an open source license and is distributed by
  20. * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
  21. * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
  22. *
  23. *********************************************************************************************************
  24. */
  25. /*
  26. *********************************************************************************************************
  27. *
  28. * uC/Modbus
  29. *
  30. * MODBUS BOARD SUPPORT PACKAGE
  31. * RT-Thread UART Device
  32. *
  33. *
  34. * Filename : mb_bsp.c
  35. * Version : V2.14.00
  36. *********************************************************************************************************
  37. */
  38. /*
  39. *********************************************************************************************************
  40. * INCLUDE FILES
  41. *********************************************************************************************************
  42. */
  43. #include "mb.h"
  44. #include <os.h>
  45. #include <rtdevice.h>
  46. #include <stdlib.h>
  47. /*
  48. *********************************************************************************************************
  49. * GLOBALS
  50. *********************************************************************************************************
  51. */
  52. /*
  53. *********************************************************************************************************
  54. * MB_CommExit()
  55. *
  56. * Description : This function is called to terminate Modbus communications. All Modbus channels are close.
  57. *
  58. * Argument(s) : none
  59. *
  60. * Return(s) : none.
  61. *
  62. * Caller(s) : MB_Exit()
  63. *
  64. * Note(s) : none.
  65. *********************************************************************************************************
  66. */
  67. CPU_VOID MB_CommExit (CPU_VOID)
  68. {
  69. CPU_INT08U ch;
  70. MODBUS_CH *pch;
  71. char uart_dev_name[RT_NAME_MAX]={0};
  72. rt_device_t uart_dev;
  73. pch = &MB_ChTbl[0];
  74. for (ch = 0; ch < MODBUS_CFG_MAX_CH; ch++) {
  75. if(pch == RT_NULL){
  76. pch++;
  77. continue;
  78. }
  79. rt_snprintf(uart_dev_name, RT_NAME_MAX, "uart%d", pch->PortNbr);
  80. uart_dev = rt_device_find(uart_dev_name);
  81. if(uart_dev == (rt_device_t)0){
  82. pch++;
  83. continue;
  84. }
  85. rt_device_set_rx_indicate(uart_dev, RT_NULL);
  86. rt_device_close(uart_dev);
  87. pch++;
  88. }
  89. }
  90. static rt_err_t mb_rx_handler(rt_device_t dev, rt_size_t size)
  91. {
  92. CPU_INT08U byte;
  93. CPU_INT08U ch;
  94. MODBUS_CH *pch;
  95. char dev_id_name[RT_NAME_MAX] = {0};
  96. CPU_INT08U id;
  97. rt_strncpy(dev_id_name, &dev->parent.name[4], 2); /* "uart1" -> "1"*/
  98. id = atoi(dev_id_name); /* "1" -> 1 */
  99. pch = &MB_ChTbl[0];
  100. for (ch = 0; ch < MODBUS_CFG_MAX_CH; ch++) {
  101. if(pch->PortNbr == id){
  102. break;
  103. }
  104. pch++;
  105. }
  106. for(ch=size; ch>0; ch--)
  107. {
  108. if(rt_device_read(dev, -1, &byte, 1) == 1) /* read one byte from uart */
  109. {
  110. MB_RxByte(pch, byte); /* invoke MB_RxByte() */
  111. }
  112. }
  113. return RT_EOK;
  114. }
  115. /*
  116. *********************************************************************************************************
  117. * MB_CommPortCfg()
  118. *
  119. * Description : This function initializes the serial port to the desired baud rate and the UART will be
  120. * configured for N, 8, 1 (No parity, 8 bits, 1 stop).
  121. *
  122. * Argument(s) : pch is a pointer to the Modbus channel
  123. * port_nbr is the desired serial port number. This argument allows you to assign a
  124. * specific serial port to a sepcific Modbus channel.
  125. * baud is the desired baud rate for the serial port.
  126. * parity is the desired parity and can be either:
  127. *
  128. * MODBUS_PARITY_NONE
  129. * MODBUS_PARITY_ODD
  130. * MODBUS_PARITY_EVEN
  131. *
  132. * bits specifies the number of bit and can be either 7 or 8.
  133. * stops specifies the number of stop bits and can either be 1 or 2
  134. *
  135. * Return(s) : none.
  136. *
  137. * Caller(s) : MB_CfgCh()
  138. *
  139. * Note(s) : none.
  140. *********************************************************************************************************
  141. */
  142. CPU_VOID MB_CommPortCfg (MODBUS_CH *pch,
  143. CPU_INT08U port_nbr,
  144. CPU_INT32U baud,
  145. CPU_INT08U bits,
  146. CPU_INT08U parity,
  147. CPU_INT08U stops)
  148. {
  149. char uart_dev_name[RT_NAME_MAX]={0};
  150. rt_device_t uart_dev; /* uart device handler */
  151. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  152. if (pch == (MODBUS_CH *)0){
  153. return;
  154. }
  155. pch->PortNbr = port_nbr; /* Store configuration in channel */
  156. pch->BaudRate = baud;
  157. pch->Parity = parity;
  158. pch->Bits = bits;
  159. pch->Stops = stops;
  160. rt_snprintf(uart_dev_name, RT_NAME_MAX, "uart%d", port_nbr);
  161. uart_dev = rt_device_find(uart_dev_name);
  162. if(uart_dev == (rt_device_t)0){
  163. return;
  164. }
  165. switch(baud)
  166. {
  167. case 2400:
  168. config.baud_rate = BAUD_RATE_2400; break;
  169. case 4800:
  170. config.baud_rate = BAUD_RATE_4800; break;
  171. case 9600:
  172. config.baud_rate = BAUD_RATE_9600; break;
  173. case 19200:
  174. config.baud_rate = BAUD_RATE_19200; break;
  175. case 38400:
  176. config.baud_rate = BAUD_RATE_38400; break;
  177. case 57600:
  178. config.baud_rate = BAUD_RATE_57600; break;
  179. case 115200:
  180. config.baud_rate = BAUD_RATE_115200; break;
  181. case 230400:
  182. config.baud_rate = BAUD_RATE_230400; break;
  183. case 460800:
  184. config.baud_rate = BAUD_RATE_460800; break;
  185. case 921600:
  186. config.baud_rate = BAUD_RATE_921600; break;
  187. case 2000000:
  188. config.baud_rate = BAUD_RATE_2000000; break;
  189. case 3000000:
  190. config.baud_rate = BAUD_RATE_3000000; break;
  191. default:
  192. config.baud_rate = BAUD_RATE_115200; break;
  193. }
  194. switch(bits)
  195. {
  196. case 7:
  197. config.data_bits = DATA_BITS_7; break;
  198. case 8:
  199. default:
  200. config.data_bits = DATA_BITS_8; break;
  201. }
  202. switch(stops)
  203. {
  204. case 2:
  205. config.stop_bits = STOP_BITS_2; break;
  206. case 1:
  207. default:
  208. config.stop_bits = STOP_BITS_1; break;
  209. }
  210. switch(parity)
  211. {
  212. case MODBUS_PARITY_ODD:
  213. config.parity = PARITY_ODD; break;
  214. case MODBUS_PARITY_EVEN:
  215. config.parity = PARITY_EVEN; break;
  216. case MODBUS_PARITY_NONE:
  217. default:
  218. config.parity = PARITY_NONE; break;
  219. }
  220. config.bufsz = 128;
  221. rt_device_control(uart_dev, RT_DEVICE_CTRL_CONFIG, &config);
  222. if(rt_device_open(uart_dev, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX) == RT_EOK)
  223. {
  224. rt_device_set_rx_indicate(uart_dev, mb_rx_handler);
  225. }
  226. }
  227. /*
  228. *********************************************************************************************************
  229. * MB_Tx()
  230. *
  231. * Description : This function is called to start transmitting a packet to a modbus channel.
  232. *
  233. * Argument(s) : pch Is a pointer to the Modbus channel's data structure.
  234. *
  235. * Return(s) : none.
  236. *
  237. * Caller(s) : MB_ASCII_Tx(),
  238. * MB_RTU_Tx().
  239. *
  240. * Note(s) : none.
  241. *********************************************************************************************************
  242. */
  243. /* combine MB_Tx() and MB_TxByte() */
  244. void MB_Tx (MODBUS_CH *pch)
  245. {
  246. char uart_dev_name[RT_NAME_MAX]={0};
  247. rt_device_t uart_dev;
  248. pch->TxBufPtr = &pch->TxBuf[0];
  249. if (pch->TxBufByteCtr > 0) {
  250. #if (MODBUS_CFG_MASTER_EN == DEF_ENABLED)
  251. if (pch->MasterSlave == MODBUS_MASTER) {
  252. #if (MODBUS_CFG_RTU_EN == DEF_ENABLED)
  253. pch->RTU_TimeoutEn = MODBUS_FALSE; /* Disable RTU timeout timer until we start receiving */
  254. #endif
  255. pch->RxBufByteCtr = 0; /* Flush Rx buffer */
  256. }
  257. #endif
  258. rt_snprintf(uart_dev_name, RT_NAME_MAX, "uart%d", pch->PortNbr);
  259. uart_dev = rt_device_find(uart_dev_name);
  260. if(uart_dev == (rt_device_t)0){
  261. return;
  262. }
  263. rt_device_write(uart_dev,0,pch->TxBufPtr,pch->TxBufByteCtr); /* send a message */
  264. /* end of transmission */
  265. pch->TxCtr = pch->TxBufByteCtr;
  266. pch->TxBufByteCtr = 0;
  267. }
  268. }
  269. /*
  270. *********************************************************************************************************
  271. * MB_RTU_TmrInit()
  272. *
  273. * Description : This function is called to initialize the RTU timeout timer.
  274. *
  275. * Argument(s) : freq Is the frequency of the modbus RTU timer interrupt.
  276. *
  277. * Return(s) : none.
  278. *
  279. * Caller(s) : MB_Init().
  280. *
  281. * Note(s) : none.
  282. *********************************************************************************************************
  283. */
  284. #if (MODBUS_CFG_RTU_EN == DEF_ENABLED)
  285. CPU_VOID MB_RTU_TmrInit (void)
  286. {
  287. }
  288. #endif
  289. /*
  290. *********************************************************************************************************
  291. * MB_RTU_TmrExit()
  292. *
  293. * Description : This function is called to disable the RTU timeout timer.
  294. *
  295. * Argument(s) : none.
  296. *
  297. * Return(s) : none.
  298. *
  299. * Caller(s) : MB_Exit()
  300. *
  301. * Note(s) : none.
  302. *********************************************************************************************************
  303. */
  304. #if (MODBUS_CFG_RTU_EN == DEF_ENABLED)
  305. CPU_VOID MB_RTU_TmrExit (CPU_VOID)
  306. {
  307. }
  308. #endif
  309. /*
  310. *********************************************************************************************************
  311. * MB_RTU_TmrISR_Handler()
  312. *
  313. * Description : This function handles the case when the RTU timeout timer expires.
  314. *
  315. * Arguments : none.
  316. *
  317. * Returns : none.
  318. *
  319. * Caller(s) : This is a ISR.
  320. *
  321. * Note(s) : none.
  322. *********************************************************************************************************
  323. */
  324. #if (MODBUS_CFG_RTU_EN == DEF_ENABLED)
  325. CPU_VOID MB_RTU_Tmr_Timeout (CPU_VOID)
  326. {
  327. }
  328. #endif