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