mbmstapp.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5. #include <stdbool.h>
  6. #include <limits.h>
  7. #include <gfambrtumst.h>
  8. #include "mbmstapp.h"
  9. #include "inc/hw_memmap.h"
  10. #include "inc/hw_gpio.h"
  11. #include "inc/hw_uart.h"
  12. #include "inc/hw_ints.h"
  13. #include "driverlib/gpio.h"
  14. #include "driverlib/uart.h"
  15. #include "driverlib/sysctl.h"
  16. #include "driverlib/pin_map.h"
  17. #if HW_PLATFORM == HW_PLATFORM_OLS1V
  18. #include "ols1v.h"
  19. #elif HW_PLATFORM == HW_PLATFORM_EAV1V
  20. #include "eav1v.h"
  21. #else
  22. #error Unknown hardware platform!
  23. #endif // HW_PLATFORM
  24. /////////////////////////////////////////////////////////////////////////////
  25. #define _REQ_DELAY 10
  26. #define _METRONIK_SENSOR_SLAVE_ID 0x40
  27. #define _NEDAP_SLAVE_ID_1 1
  28. #define _NEDAP_SLAVE_ID_2 2
  29. #define TID_METRONIC_ILM_READ_UV 0x0101
  30. #define TID_METRONIC_ILM_READ_TEMP 0x0102
  31. #define TID_METRONIC_ILM_READ_SERIAL 0x0103
  32. #define TID_METRONIC_ILM_READ_RANGE 0x0104
  33. #define TID_NEDAP_CLEAR_CTRS_AND_DIAGNOSTIC_REG 0x0201
  34. #define TID_NEDAP_REPORT_SLAVE_ID 0x0202
  35. #define TID_NEDAP_PRESET_SINGLE_REGISTER_7 0x0203
  36. #define TID_NEDAP_WRITE_MULTIPLE_REGISTERS_7_2 0x0204
  37. #define TID_NEDAP_RETURN_BUS_EXCEPTION_ERROR_COUNT 0x0205
  38. #define TID_NEDAP_READ_REGISTERS_0_50 0x0206
  39. /////////////////////////////////////////////////////////////////////////////
  40. static HMBRTUMST g_hMbMst = NULL;
  41. static uint64_t g_nSendTick = 0;
  42. static bool g_bCTS = false;
  43. static uint16_t g_nRegs[MODBUS_MAX_READ_REGISTERS] = {0};
  44. /////////////////////////////////////////////////////////////////////////////
  45. static void _OnMasterStateChanged(GFA_MODBUS_RTU_MST_STATES newState, GFA_MODBUS_RTU_MST_STATES oldState)
  46. {
  47. switch(newState)
  48. {
  49. case MB_RTU_MST_Idle:
  50. // OlsClearLeds(OLS_LED_MASK);
  51. break;
  52. case MB_RTU_MST_TxStart:
  53. // OlsSetLeds(OLS_LED_GREEN_RIGHT);
  54. break;
  55. case MB_RTU_MST_TxDone:
  56. // OlsClearLeds(OLS_LED_GREEN_RIGHT);
  57. break;
  58. case MB_RTU_MST_RxSlvID:
  59. // OlsSetLeds(OLS_LED_GREEN_LEFT);
  60. break;
  61. case MB_RTU_MST_RxError:
  62. // OlsClearSetLeds(OLS_LED_MASK, OLS_LED_RED_TOP);
  63. break;
  64. case MB_RTU_MST_ReportError:
  65. // OlsClearSetLeds(OLS_LED_MASK, OLS_LED_RED_BOTTOM);
  66. break;
  67. }
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. static void _RetriggerRequestTimer(void)
  71. {
  72. g_nSendTick = GfaSystickGetCount() + _REQ_DELAY;
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. static bool _RequestTimerElapsed(void)
  76. {
  77. return g_nSendTick < GfaSystickGetCount();
  78. }
  79. /////////////////////////////////////////////////////////////////////////////
  80. static void _ReportError(uint16_t errcode)
  81. {
  82. // Report error. See gfambrtumst.h for error codes
  83. }
  84. /////////////////////////////////////////////////////////////////////////////
  85. static void _FinishRequest(void)
  86. {
  87. _RetriggerRequestTimer();
  88. g_bCTS = true;
  89. }
  90. /////////////////////////////////////////////////////////////////////////////
  91. /////////////////////////////////////////////////////////////////////////////
  92. /////////////////////////////////////////////////////////////////////////////
  93. static void _OnReadRegistersComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, const uint16_t *pRegs, size_t nRegCount)
  94. {
  95. if(err)
  96. {
  97. _ReportError(err);
  98. }
  99. else
  100. {
  101. // Success! Do whatever needs to be done ...
  102. if(nTID == TID_NEDAP_READ_REGISTERS_0_50)
  103. {
  104. // ...
  105. }
  106. }
  107. _FinishRequest();
  108. }
  109. /////////////////////////////////////////////////////////////////////////////
  110. static void _OnWriteRegistersComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, uint16_t nRegStart, uint16_t nRegsWritten)
  111. {
  112. if(err)
  113. {
  114. _ReportError(err);
  115. }
  116. else
  117. {
  118. // Success! Do whatever needs to be done ...
  119. }
  120. _FinishRequest();
  121. }
  122. /////////////////////////////////////////////////////////////////////////////
  123. static void _OnPresetRegisterComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err)
  124. {
  125. if(err)
  126. {
  127. _ReportError(err);
  128. }
  129. else
  130. {
  131. // Success! Do whatever needs to be done ...
  132. }
  133. _FinishRequest();
  134. }
  135. /////////////////////////////////////////////////////////////////////////////
  136. static void _OnDiagnosisComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, uint16_t nSubFunc, uint16_t nData)
  137. {
  138. if(err)
  139. {
  140. _ReportError(err);
  141. }
  142. else
  143. {
  144. switch(nSubFunc)
  145. {
  146. case MB_SUBFUNC_CLEAR_CTRS_AND_DIAGNOSTIC_REG:
  147. // Success! Do whatever needs to be done ...
  148. break;
  149. case MB_SUBFUNC_RETURN_BUS_EXCEPTION_ERROR_COUNT:
  150. // Success! Do whatever needs to be done ...
  151. break;
  152. }
  153. }
  154. _FinishRequest();
  155. }
  156. /////////////////////////////////////////////////////////////////////////////
  157. static void _OnReportSlaveIDComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, const void *pData, size_t nCbData)
  158. {
  159. if(err)
  160. {
  161. _ReportError(err);
  162. }
  163. else
  164. {
  165. // Success! Do whatever needs to be done ...
  166. }
  167. _FinishRequest();
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. static void _OnReadUVComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, uint16_t nVal)
  171. {
  172. if(err)
  173. {
  174. _ReportError(err);
  175. }
  176. else
  177. {
  178. // Success! Do whatever needs to be done ...
  179. }
  180. _FinishRequest();
  181. }
  182. /////////////////////////////////////////////////////////////////////////////
  183. static void _OnReadTempComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, uint8_t nVal)
  184. {
  185. if(err)
  186. {
  187. _ReportError(err);
  188. }
  189. else
  190. {
  191. // Success! Do whatever needs to be done ...
  192. }
  193. _FinishRequest();
  194. }
  195. /////////////////////////////////////////////////////////////////////////////
  196. static void _OnReadRangeComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, uint16_t nVal)
  197. {
  198. if(err)
  199. {
  200. _ReportError(err);
  201. }
  202. else
  203. {
  204. // Success! Do whatever needs to be done ...
  205. }
  206. _FinishRequest();
  207. }
  208. /////////////////////////////////////////////////////////////////////////////
  209. static void _OnReadSerialComplete(uint32_t nTID, uint8_t nSlvID, uint16_t err, const uint8_t *pVal, size_t nCbVal)
  210. {
  211. if(err)
  212. {
  213. _ReportError(err);
  214. }
  215. else
  216. {
  217. // Success! Do whatever needs to be done ...
  218. }
  219. _FinishRequest();
  220. }
  221. /////////////////////////////////////////////////////////////////////////////
  222. static bool _DoMetronik(uint8_t nSlaveID)
  223. {
  224. static uint32_t nState = 0;
  225. bool bRet = false;
  226. switch(nState++ % 4)
  227. {
  228. case 0:
  229. bRet = GfaModbusRTUMstILMReadUV(g_hMbMst, TID_METRONIC_ILM_READ_UV, nSlaveID, _OnReadUVComplete);
  230. break;
  231. case 1:
  232. bRet = GfaModbusRTUMstILMReadTemp(g_hMbMst, TID_METRONIC_ILM_READ_TEMP, nSlaveID, _OnReadTempComplete);
  233. break;
  234. case 2:
  235. bRet = GfaModbusRTUMstILMReadSerial(g_hMbMst, TID_METRONIC_ILM_READ_SERIAL, nSlaveID, _OnReadSerialComplete);
  236. break;
  237. case 3:
  238. bRet = GfaModbusRTUMstILMReadRange(g_hMbMst, TID_METRONIC_ILM_READ_RANGE, nSlaveID, _OnReadRangeComplete);
  239. break;
  240. }
  241. return bRet;
  242. }
  243. /////////////////////////////////////////////////////////////////////////////
  244. static bool _DoNedap(uint8_t nSlaveID, uint32_t *pnState)
  245. {
  246. bool bRet = false;
  247. switch((*pnState)++)
  248. {
  249. case 0:
  250. bRet = GfaModbusRTUMstDiagnosis(g_hMbMst, TID_NEDAP_CLEAR_CTRS_AND_DIAGNOSTIC_REG, nSlaveID, MB_SUBFUNC_CLEAR_CTRS_AND_DIAGNOSTIC_REG, 0, _OnDiagnosisComplete);
  251. break;
  252. case 1:
  253. bRet = GfaModbusRTUMstReportSlaveID(g_hMbMst, TID_NEDAP_REPORT_SLAVE_ID, nSlaveID, 4, _OnReportSlaveIDComplete);
  254. break;
  255. case 10:
  256. bRet = GfaModbusRTUMstPresetSingleRegister(g_hMbMst, TID_NEDAP_PRESET_SINGLE_REGISTER_7, nSlaveID, 7, 0x801E, _OnPresetRegisterComplete);
  257. break;
  258. case 50:
  259. g_nRegs[0] = 0x801E;
  260. g_nRegs[1] = 0x0015;
  261. bRet = GfaModbusRTUMstWriteMultipleRegisters(g_hMbMst, TID_NEDAP_WRITE_MULTIPLE_REGISTERS_7_2, nSlaveID, 7, 2, g_nRegs, _OnWriteRegistersComplete);
  262. break;
  263. case 100:
  264. bRet = GfaModbusRTUMstDiagnosis(g_hMbMst, TID_NEDAP_RETURN_BUS_EXCEPTION_ERROR_COUNT, nSlaveID, MB_SUBFUNC_RETURN_BUS_EXCEPTION_ERROR_COUNT, 0, _OnDiagnosisComplete);
  265. *pnState = 1;
  266. break;
  267. default:
  268. bRet = GfaModbusRTUMstReadHoldingRegisters(g_hMbMst, TID_NEDAP_READ_REGISTERS_0_50, nSlaveID, 0, 50, _OnReadRegistersComplete);
  269. break;
  270. }
  271. return bRet;
  272. }
  273. /////////////////////////////////////////////////////////////////////////////
  274. static void _InitUARTConfig(LPGFA_UART_CONFIG puc)
  275. {
  276. memset(puc, 0, sizeof(LPGFA_UART_CONFIG));
  277. puc->P_UART_BASE = UART_BASE;
  278. puc->P_UART_BASE_SYSCTL = UART_BASE_SYSCTL;
  279. puc->P_UART_PORT = UART_PORT;
  280. puc->P_UART_PORT_SYSCTL = UART_PORT_SYSCTL;
  281. puc->P_UART_RX_PIN = UART_RX_PIN;
  282. puc->P_UART_RX_PIN_MUX = UART_RX_PIN_MUX;
  283. puc->P_UART_TX_PIN = UART_TX_PIN;
  284. puc->P_UART_TX_PIN_MUX = UART_TX_PIN_MUX;
  285. puc->P_UART_INT = UART_INT;
  286. puc->P_UART_INT_PRIORITY = MODBUS_RTU_UART_INT_PRIORITY;
  287. puc->P_EN_485_PORT_SYSCTL = EN_485_PORT_SYSCTL;
  288. puc->P_EN_485_PORT = EN_485_PORT;
  289. puc->P_EN_485_PIN = EN_485_PIN;
  290. puc->nBaud = MODBUS_RTU_BAUDRATE;
  291. puc->nDatabits = MODBUS_RTU_DATABITS;
  292. puc->nStopbits = MODBUS_RTU_STOPBITS;
  293. puc->parity = MODBUS_RTU_PARITY;
  294. puc->nFifoIndexRx = 0;
  295. puc->nFifoIndexTx = 1;
  296. }
  297. /////////////////////////////////////////////////////////////////////////////
  298. /////////////////////////////////////////////////////////////////////////////
  299. /////////////////////////////////////////////////////////////////////////////
  300. bool GfaInitModbusMasterApp(void)
  301. {
  302. GFA_UART_CONFIG uartParams;
  303. g_hMbMst = NULL;
  304. _InitUARTConfig(&uartParams);
  305. if(GfaMbUartInit(&uartParams))
  306. {
  307. GFA_MODBUS_RTU_MASTER_PARAMETERS mstParams;
  308. memset(&mstParams, 0, sizeof(mstParams));
  309. mstParams.hFifoRX = GfaMbUartGetRxFifo();
  310. mstParams.hFifoTX = GfaMbUartGetTxFifo();
  311. mstParams.nRxTimeoutUs = MODBUS_RTU_MASTER_RX_TIMEOUT_US;
  312. GfaMbUartGetProtocolTimeouts(&mstParams.mpt);
  313. mstParams.appItf.pfnStateChanged = _OnMasterStateChanged;
  314. if(!(g_hMbMst = GfaModbusRTUMstCreate(&mstParams)))
  315. GfaMbUartRelease();
  316. else
  317. g_bCTS = true;
  318. }
  319. return !!g_hMbMst;
  320. }
  321. /////////////////////////////////////////////////////////////////////////////
  322. void GfaDoModbusMasterApp(void)
  323. {
  324. static uint32_t nLoop = 0, nStateN1 = 0, nStateN2 = 0;
  325. bool bRet = false;
  326. if(g_bCTS && _RequestTimerElapsed())
  327. {
  328. g_bCTS = false;
  329. switch(nLoop++ % 3)
  330. {
  331. case 0:
  332. bRet = _DoMetronik(_METRONIK_SENSOR_SLAVE_ID);
  333. break;
  334. case 1:
  335. bRet = _DoNedap(_NEDAP_SLAVE_ID_1, &nStateN1);
  336. break;
  337. case 2:
  338. bRet = _DoNedap(_NEDAP_SLAVE_ID_2, &nStateN2);
  339. break;
  340. }
  341. if(!bRet)
  342. {
  343. _ReportError(GFA_MB_MST_ERROR_UNEXPECTED);
  344. _FinishRequest();
  345. }
  346. }
  347. GfaModbusRTUMstStateMachine(g_hMbMst);
  348. }
  349. /////////////////////////////////////////////////////////////////////////////