xref: /nrf52832-nimble/rt-thread/components/net/freemodbus/port/user_mb_app.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * FreeModbus Libary: user callback functions and buffer define in slave mode
3  * Copyright (C) 2013 Armink <[email protected]>
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.c,v 1.60 2013/11/23 11:49:05 Armink $
20  */
21 #include "user_mb_app.h"
22 
23 /*------------------------Slave mode use these variables----------------------*/
24 //Slave mode:DiscreteInputs variables
25 USHORT   usSDiscInStart                               = S_DISCRETE_INPUT_START;
26 #if S_DISCRETE_INPUT_NDISCRETES%8
27 UCHAR    ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1];
28 #else
29 UCHAR    ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8]  ;
30 #endif
31 //Slave mode:Coils variables
32 USHORT   usSCoilStart                                 = S_COIL_START;
33 #if S_COIL_NCOILS%8
34 UCHAR    ucSCoilBuf[S_COIL_NCOILS/8+1]                ;
35 #else
36 UCHAR    ucSCoilBuf[S_COIL_NCOILS/8]                  ;
37 #endif
38 //Slave mode:InputRegister variables
39 USHORT   usSRegInStart                                = S_REG_INPUT_START;
40 USHORT   usSRegInBuf[S_REG_INPUT_NREGS]               ;
41 //Slave mode:HoldingRegister variables
42 USHORT   usSRegHoldStart                              = S_REG_HOLDING_START;
43 USHORT   usSRegHoldBuf[S_REG_HOLDING_NREGS]           ;
44 
45 /**
46  * Modbus slave 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  */
eMBRegInputCB(UCHAR * pucRegBuffer,USHORT usAddress,USHORT usNRegs)54 eMBErrorCode eMBRegInputCB(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 
63     pusRegInputBuf = usSRegInBuf;
64     REG_INPUT_START = S_REG_INPUT_START;
65     REG_INPUT_NREGS = S_REG_INPUT_NREGS;
66     usRegInStart = usSRegInStart;
67 
68     /* it already plus one in modbus function method. */
69     usAddress--;
70 
71     if ((usAddress >= REG_INPUT_START)
72             && (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
73     {
74         iRegIndex = usAddress - usRegInStart;
75         while (usNRegs > 0)
76         {
77             *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);
78             *pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);
79             iRegIndex++;
80             usNRegs--;
81         }
82     }
83     else
84     {
85         eStatus = MB_ENOREG;
86     }
87 
88     return eStatus;
89 }
90 
91 /**
92  * Modbus slave holding register callback function.
93  *
94  * @param pucRegBuffer holding register buffer
95  * @param usAddress holding register address
96  * @param usNRegs holding register number
97  * @param eMode read or write
98  *
99  * @return result
100  */
eMBRegHoldingCB(UCHAR * pucRegBuffer,USHORT usAddress,USHORT usNRegs,eMBRegisterMode eMode)101 eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
102         USHORT usNRegs, eMBRegisterMode eMode)
103 {
104     eMBErrorCode    eStatus = MB_ENOERR;
105     USHORT          iRegIndex;
106     USHORT *        pusRegHoldingBuf;
107     USHORT          REG_HOLDING_START;
108     USHORT          REG_HOLDING_NREGS;
109     USHORT          usRegHoldStart;
110 
111     pusRegHoldingBuf = usSRegHoldBuf;
112     REG_HOLDING_START = S_REG_HOLDING_START;
113     REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
114     usRegHoldStart = usSRegHoldStart;
115 
116     /* it already plus one in modbus function method. */
117     usAddress--;
118 
119     if ((usAddress >= REG_HOLDING_START)
120             && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
121     {
122         iRegIndex = usAddress - usRegHoldStart;
123         switch (eMode)
124         {
125         /* read current register values from the protocol stack. */
126         case MB_REG_READ:
127             while (usNRegs > 0)
128             {
129                 *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
130                 *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
131                 iRegIndex++;
132                 usNRegs--;
133             }
134             break;
135 
136         /* write current register values with new values from the protocol stack. */
137         case MB_REG_WRITE:
138             while (usNRegs > 0)
139             {
140                 pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
141                 pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
142                 iRegIndex++;
143                 usNRegs--;
144             }
145             break;
146         }
147     }
148     else
149     {
150         eStatus = MB_ENOREG;
151     }
152     return eStatus;
153 }
154 
155 /**
156  * Modbus slave coils callback function.
157  *
158  * @param pucRegBuffer coils buffer
159  * @param usAddress coils address
160  * @param usNCoils coils number
161  * @param eMode read or write
162  *
163  * @return result
164  */
eMBRegCoilsCB(UCHAR * pucRegBuffer,USHORT usAddress,USHORT usNCoils,eMBRegisterMode eMode)165 eMBErrorCode eMBRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
166         USHORT usNCoils, eMBRegisterMode eMode)
167 {
168     eMBErrorCode    eStatus = MB_ENOERR;
169     USHORT          iRegIndex , iRegBitIndex , iNReg;
170     UCHAR *         pucCoilBuf;
171     USHORT          COIL_START;
172     USHORT          COIL_NCOILS;
173     USHORT          usCoilStart;
174     iNReg =  usNCoils / 8 + 1;
175 
176     pucCoilBuf = ucSCoilBuf;
177     COIL_START = S_COIL_START;
178     COIL_NCOILS = S_COIL_NCOILS;
179     usCoilStart = usSCoilStart;
180 
181     /* it already plus one in modbus function method. */
182     usAddress--;
183 
184     if( ( usAddress >= COIL_START ) &&
185         ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
186     {
187         iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
188         iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
189         switch ( eMode )
190         {
191         /* read current coil values from the protocol stack. */
192         case MB_REG_READ:
193             while (iNReg > 0)
194             {
195                 *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
196                         iRegBitIndex, 8);
197                 iNReg--;
198             }
199             pucRegBuffer--;
200             /* last coils */
201             usNCoils = usNCoils % 8;
202             /* filling zero to high bit */
203             *pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
204             *pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
205             break;
206 
207             /* write current coil values with new values from the protocol stack. */
208         case MB_REG_WRITE:
209             while (iNReg > 1)
210             {
211                 xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
212                         *pucRegBuffer++);
213                 iNReg--;
214             }
215             /* last coils */
216             usNCoils = usNCoils % 8;
217             /* xMBUtilSetBits has bug when ucNBits is zero */
218             if (usNCoils != 0)
219             {
220                 xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
221                         *pucRegBuffer++);
222             }
223             break;
224         }
225     }
226     else
227     {
228         eStatus = MB_ENOREG;
229     }
230     return eStatus;
231 }
232 
233 /**
234  * Modbus slave discrete callback function.
235  *
236  * @param pucRegBuffer discrete buffer
237  * @param usAddress discrete address
238  * @param usNDiscrete discrete number
239  *
240  * @return result
241  */
eMBRegDiscreteCB(UCHAR * pucRegBuffer,USHORT usAddress,USHORT usNDiscrete)242 eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
243 {
244     eMBErrorCode    eStatus = MB_ENOERR;
245     USHORT          iRegIndex , iRegBitIndex , iNReg;
246     UCHAR *         pucDiscreteInputBuf;
247     USHORT          DISCRETE_INPUT_START;
248     USHORT          DISCRETE_INPUT_NDISCRETES;
249     USHORT          usDiscreteInputStart;
250     iNReg =  usNDiscrete / 8 + 1;
251 
252     pucDiscreteInputBuf = ucSDiscInBuf;
253     DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
254     DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
255     usDiscreteInputStart = usSDiscInStart;
256 
257     /* it already plus one in modbus function method. */
258     usAddress--;
259 
260     if ((usAddress >= DISCRETE_INPUT_START)
261             && (usAddress + usNDiscrete    <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
262     {
263         iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8;
264         iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8;
265 
266         while (iNReg > 0)
267         {
268             *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],
269                     iRegBitIndex, 8);
270             iNReg--;
271         }
272         pucRegBuffer--;
273         /* last discrete */
274         usNDiscrete = usNDiscrete % 8;
275         /* filling zero to high bit */
276         *pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);
277         *pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);
278     }
279     else
280     {
281         eStatus = MB_ENOREG;
282     }
283 
284     return eStatus;
285 }
286 
287