user_mb_app_m.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. /*-----------------------Master mode use these variables----------------------*/
  23. #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
  24. //Master mode:DiscreteInputs variables
  25. USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
  26. #if M_DISCRETE_INPUT_NDISCRETES%8
  27. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
  28. #else
  29. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
  30. #endif
  31. //Master mode:Coils variables
  32. USHORT usMCoilStart = M_COIL_START;
  33. #if M_COIL_NCOILS%8
  34. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
  35. #else
  36. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
  37. #endif
  38. //Master mode:InputRegister variables
  39. USHORT usMRegInStart = M_REG_INPUT_START;
  40. USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
  41. //Master mode:HoldingRegister variables
  42. USHORT usMRegHoldStart = M_REG_HOLDING_START;
  43. USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
  44. /**
  45. * Modbus master input register callback function.
  46. *
  47. * @param pucRegBuffer input register buffer
  48. * @param usAddress input register address
  49. * @param usNRegs input register number
  50. *
  51. * @return result
  52. */
  53. eMBErrorCode eMBMasterRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
  54. {
  55. eMBErrorCode eStatus = MB_ENOERR;
  56. USHORT iRegIndex;
  57. USHORT * pusRegInputBuf;
  58. USHORT REG_INPUT_START;
  59. USHORT REG_INPUT_NREGS;
  60. USHORT usRegInStart;
  61. pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress() - 1];
  62. REG_INPUT_START = M_REG_INPUT_START;
  63. REG_INPUT_NREGS = M_REG_INPUT_NREGS;
  64. usRegInStart = usMRegInStart;
  65. /* it already plus one in modbus function method. */
  66. usAddress--;
  67. if ((usAddress >= REG_INPUT_START)
  68. && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
  69. {
  70. iRegIndex = usAddress - usRegInStart;
  71. while (usNRegs > 0)
  72. {
  73. pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
  74. pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
  75. iRegIndex++;
  76. usNRegs--;
  77. }
  78. }
  79. else
  80. {
  81. eStatus = MB_ENOREG;
  82. }
  83. return eStatus;
  84. }
  85. /**
  86. * Modbus master holding register callback function.
  87. *
  88. * @param pucRegBuffer holding register buffer
  89. * @param usAddress holding register address
  90. * @param usNRegs holding register number
  91. * @param eMode read or write
  92. *
  93. * @return result
  94. */
  95. eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
  96. USHORT usNRegs, eMBRegisterMode eMode)
  97. {
  98. eMBErrorCode eStatus = MB_ENOERR;
  99. USHORT iRegIndex;
  100. USHORT * pusRegHoldingBuf;
  101. USHORT REG_HOLDING_START;
  102. USHORT REG_HOLDING_NREGS;
  103. USHORT usRegHoldStart;
  104. pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress() - 1];
  105. REG_HOLDING_START = M_REG_HOLDING_START;
  106. REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
  107. usRegHoldStart = usMRegHoldStart;
  108. /* if mode is read, the master will write the received date to buffer. */
  109. eMode = MB_REG_WRITE;
  110. /* it already plus one in modbus function method. */
  111. usAddress--;
  112. if ((usAddress >= REG_HOLDING_START)
  113. && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
  114. {
  115. iRegIndex = usAddress - usRegHoldStart;
  116. switch (eMode)
  117. {
  118. /* read current register values from the protocol stack. */
  119. case MB_REG_READ:
  120. while (usNRegs > 0)
  121. {
  122. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
  123. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
  124. iRegIndex++;
  125. usNRegs--;
  126. }
  127. break;
  128. /* write current register values with new values from the protocol stack. */
  129. case MB_REG_WRITE:
  130. while (usNRegs > 0)
  131. {
  132. pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
  133. pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
  134. iRegIndex++;
  135. usNRegs--;
  136. }
  137. break;
  138. }
  139. }
  140. else
  141. {
  142. eStatus = MB_ENOREG;
  143. }
  144. return eStatus;
  145. }
  146. /**
  147. * Modbus master coils callback function.
  148. *
  149. * @param pucRegBuffer coils buffer
  150. * @param usAddress coils address
  151. * @param usNCoils coils number
  152. * @param eMode read or write
  153. *
  154. * @return result
  155. */
  156. eMBErrorCode eMBMasterRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
  157. USHORT usNCoils, eMBRegisterMode eMode)
  158. {
  159. eMBErrorCode eStatus = MB_ENOERR;
  160. USHORT iRegIndex , iRegBitIndex , iNReg;
  161. UCHAR * pucCoilBuf;
  162. USHORT COIL_START;
  163. USHORT COIL_NCOILS;
  164. USHORT usCoilStart;
  165. iNReg = usNCoils / 8 + 1;
  166. pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress() - 1];
  167. COIL_START = M_COIL_START;
  168. COIL_NCOILS = M_COIL_NCOILS;
  169. usCoilStart = usMCoilStart;
  170. /* if mode is read,the master will write the received date to buffer. */
  171. eMode = MB_REG_WRITE;
  172. /* it already plus one in modbus function method. */
  173. usAddress--;
  174. if ((usAddress >= COIL_START)
  175. && (usAddress + usNCoils <= COIL_START + COIL_NCOILS))
  176. {
  177. iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
  178. iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
  179. switch (eMode)
  180. {
  181. /* read current coil values from the protocol stack. */
  182. case MB_REG_READ:
  183. while (iNReg > 0)
  184. {
  185. *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
  186. iRegBitIndex, 8);
  187. iNReg--;
  188. }
  189. pucRegBuffer--;
  190. /* last coils */
  191. usNCoils = usNCoils % 8;
  192. /* filling zero to high bit */
  193. *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
  194. *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
  195. break;
  196. /* write current coil values with new values from the protocol stack. */
  197. case MB_REG_WRITE:
  198. while (iNReg > 1)
  199. {
  200. xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
  201. *pucRegBuffer++);
  202. iNReg--;
  203. }
  204. /* last coils */
  205. usNCoils = usNCoils % 8;
  206. /* xMBUtilSetBits has bug when ucNBits is zero */
  207. if (usNCoils != 0)
  208. {
  209. xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
  210. *pucRegBuffer++);
  211. }
  212. break;
  213. }
  214. }
  215. else
  216. {
  217. eStatus = MB_ENOREG;
  218. }
  219. return eStatus;
  220. }
  221. /**
  222. * Modbus master discrete callback function.
  223. *
  224. * @param pucRegBuffer discrete buffer
  225. * @param usAddress discrete address
  226. * @param usNDiscrete discrete number
  227. *
  228. * @return result
  229. */
  230. eMBErrorCode eMBMasterRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
  231. {
  232. eMBErrorCode eStatus = MB_ENOERR;
  233. USHORT iRegIndex , iRegBitIndex , iNReg;
  234. UCHAR * pucDiscreteInputBuf;
  235. USHORT DISCRETE_INPUT_START;
  236. USHORT DISCRETE_INPUT_NDISCRETES;
  237. USHORT usDiscreteInputStart;
  238. iNReg = usNDiscrete / 8 + 1;
  239. pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress() - 1];
  240. DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
  241. DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
  242. usDiscreteInputStart = usMDiscInStart;
  243. /* it already plus one in modbus function method. */
  244. usAddress--;
  245. if ((usAddress >= DISCRETE_INPUT_START)
  246. && (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
  247. {
  248. iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
  249. iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
  250. /* write current discrete values with new values from the protocol stack. */
  251. while (iNReg > 1)
  252. {
  253. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex, 8,
  254. *pucRegBuffer++);
  255. iNReg--;
  256. }
  257. /* last discrete */
  258. usNDiscrete = usNDiscrete % 8;
  259. /* xMBUtilSetBits has bug when ucNBits is zero */
  260. if (usNDiscrete != 0)
  261. {
  262. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
  263. usNDiscrete, *pucRegBuffer++);
  264. }
  265. }
  266. else
  267. {
  268. eStatus = MB_ENOREG;
  269. }
  270. return eStatus;
  271. }
  272. #endif