user_mb_app_m.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * FreeModbus Libary: user callback functions and buffer define in master mode
  3. * Copyright (C) 2013 Armink <armink.ztl@gmail.com>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. * File: $Id: user_mb_app_m.c,v 1.60 2013/11/23 11:49:05 Armink $
  20. */
  21. #include "user_mb_app.h"
  22. #include "mbconfig.h"
  23. /*-----------------------Master mode use these variables----------------------*/
  24. #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
  25. //Master mode:DiscreteInputs variables
  26. USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
  27. #if M_DISCRETE_INPUT_NDISCRETES%8
  28. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
  29. #else
  30. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
  31. #endif
  32. //Master mode:Coils variables
  33. USHORT usMCoilStart = M_COIL_START;
  34. #if M_COIL_NCOILS%8
  35. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
  36. #else
  37. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
  38. #endif
  39. //Master mode:InputRegister variables
  40. USHORT usMRegInStart = M_REG_INPUT_START;
  41. USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
  42. //Master mode:HoldingRegister variables
  43. USHORT usMRegHoldStart = M_REG_HOLDING_START;
  44. USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
  45. /**
  46. * Modbus master input register callback function.
  47. *
  48. * @param pucRegBuffer input register buffer
  49. * @param usAddress input register address
  50. * @param usNRegs input register number
  51. *
  52. * @return result
  53. */
  54. eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
  55. {
  56. eMBErrorCode eStatus = MB_ENOERR;
  57. USHORT iRegIndex;
  58. USHORT * pusRegInputBuf;
  59. USHORT REG_INPUT_START;
  60. USHORT REG_INPUT_NREGS;
  61. USHORT usRegInStart;
  62. pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress() - 1];
  63. REG_INPUT_START = M_REG_INPUT_START;
  64. REG_INPUT_NREGS = M_REG_INPUT_NREGS;
  65. usRegInStart = usMRegInStart;
  66. /* it already plus one in modbus function method. */
  67. usAddress--;
  68. if ((usAddress >= REG_INPUT_START)
  69. && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
  70. {
  71. iRegIndex = usAddress - usRegInStart;
  72. while (usNRegs > 0)
  73. {
  74. pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
  75. pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
  76. iRegIndex++;
  77. usNRegs--;
  78. }
  79. }
  80. else
  81. {
  82. eStatus = MB_ENOREG;
  83. }
  84. return eStatus;
  85. }
  86. /**
  87. * Modbus master holding register callback function.
  88. *
  89. * @param pucRegBuffer holding register buffer
  90. * @param usAddress holding register address
  91. * @param usNRegs holding register number
  92. * @param eMode read or write
  93. *
  94. * @return result
  95. */
  96. eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
  97. USHORT usNRegs, eMBRegisterMode eMode)
  98. {
  99. eMBErrorCode eStatus = MB_ENOERR;
  100. USHORT iRegIndex;
  101. USHORT * pusRegHoldingBuf;
  102. USHORT REG_HOLDING_START;
  103. USHORT REG_HOLDING_NREGS;
  104. USHORT usRegHoldStart;
  105. pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress() - 1];
  106. REG_HOLDING_START = M_REG_HOLDING_START;
  107. REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
  108. usRegHoldStart = usMRegHoldStart;
  109. /* if mode is read, the master will write the received date to buffer. */
  110. eMode = MB_REG_WRITE;
  111. /* it already plus one in modbus function method. */
  112. usAddress--;
  113. if ((usAddress >= REG_HOLDING_START)
  114. && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
  115. {
  116. iRegIndex = usAddress - usRegHoldStart;
  117. switch (eMode)
  118. {
  119. /* read current register values from the protocol stack. */
  120. case MB_REG_READ:
  121. while (usNRegs > 0)
  122. {
  123. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
  124. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
  125. iRegIndex++;
  126. usNRegs--;
  127. }
  128. break;
  129. /* write current register values with new values from the protocol stack. */
  130. case MB_REG_WRITE:
  131. while (usNRegs > 0)
  132. {
  133. pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
  134. pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
  135. iRegIndex++;
  136. usNRegs--;
  137. }
  138. break;
  139. }
  140. }
  141. else
  142. {
  143. eStatus = MB_ENOREG;
  144. }
  145. return eStatus;
  146. }
  147. /**
  148. * Modbus master coils callback function.
  149. *
  150. * @param pucRegBuffer coils buffer
  151. * @param usAddress coils address
  152. * @param usNCoils coils number
  153. * @param eMode read or write
  154. *
  155. * @return result
  156. */
  157. eMBErrorCode eMBMasterRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
  158. USHORT usNCoils, eMBRegisterMode eMode)
  159. {
  160. eMBErrorCode eStatus = MB_ENOERR;
  161. USHORT iRegIndex , iRegBitIndex , iNReg;
  162. UCHAR * pucCoilBuf;
  163. USHORT COIL_START;
  164. USHORT COIL_NCOILS;
  165. USHORT usCoilStart;
  166. iNReg = usNCoils / 8 + 1;
  167. pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress() - 1];
  168. COIL_START = M_COIL_START;
  169. COIL_NCOILS = M_COIL_NCOILS;
  170. usCoilStart = usMCoilStart;
  171. /* if mode is read,the master will write the received date to buffer. */
  172. eMode = MB_REG_WRITE;
  173. /* it already plus one in modbus function method. */
  174. usAddress--;
  175. if ((usAddress >= COIL_START)
  176. && (usAddress + usNCoils <= COIL_START + COIL_NCOILS))
  177. {
  178. iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
  179. iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
  180. switch (eMode)
  181. {
  182. /* read current coil values from the protocol stack. */
  183. case MB_REG_READ:
  184. while (iNReg > 0)
  185. {
  186. *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
  187. iRegBitIndex, 8);
  188. iNReg--;
  189. }
  190. pucRegBuffer--;
  191. /* last coils */
  192. usNCoils = usNCoils % 8;
  193. /* filling zero to high bit */
  194. *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
  195. *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
  196. break;
  197. /* write current coil values with new values from the protocol stack. */
  198. case MB_REG_WRITE:
  199. while (iNReg > 1)
  200. {
  201. xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
  202. *pucRegBuffer++);
  203. iNReg--;
  204. }
  205. /* last coils */
  206. usNCoils = usNCoils % 8;
  207. /* xMBUtilSetBits has bug when ucNBits is zero */
  208. if (usNCoils != 0)
  209. {
  210. xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
  211. *pucRegBuffer++);
  212. }
  213. break;
  214. }
  215. }
  216. else
  217. {
  218. eStatus = MB_ENOREG;
  219. }
  220. return eStatus;
  221. }
  222. /**
  223. * Modbus master discrete callback function.
  224. *
  225. * @param pucRegBuffer discrete buffer
  226. * @param usAddress discrete address
  227. * @param usNDiscrete discrete number
  228. *
  229. * @return result
  230. */
  231. eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
  232. {
  233. eMBErrorCode eStatus = MB_ENOERR;
  234. USHORT iRegIndex , iRegBitIndex , iNReg;
  235. UCHAR * pucDiscreteInputBuf;
  236. USHORT DISCRETE_INPUT_START;
  237. USHORT DISCRETE_INPUT_NDISCRETES;
  238. USHORT usDiscreteInputStart;
  239. iNReg = usNDiscrete / 8 + 1;
  240. pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress() - 1];
  241. DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
  242. DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
  243. usDiscreteInputStart = usMDiscInStart;
  244. /* it already plus one in modbus function method. */
  245. usAddress--;
  246. if ((usAddress >= DISCRETE_INPUT_START)
  247. && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
  248. {
  249. iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
  250. iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
  251. /* write current discrete values with new values from the protocol stack. */
  252. while (iNReg > 1)
  253. {
  254. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex, 8,
  255. *pucRegBuffer++);
  256. iNReg--;
  257. }
  258. /* last discrete */
  259. usNDiscrete = usNDiscrete % 8;
  260. /* xMBUtilSetBits has bug when ucNBits is zero */
  261. if (usNDiscrete != 0)
  262. {
  263. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
  264. usNDiscrete, *pucRegBuffer++);
  265. }
  266. }
  267. else
  268. {
  269. eStatus = MB_ENOREG;
  270. }
  271. return eStatus;
  272. }
  273. #endif