2015-02-05 19:27:24 +08:00
|
|
|
|
/*
|
|
|
|
|
* FreeModbus Libary: user callback functions and buffer define in slave mode
|
|
|
|
|
* Copyright (C) 2013 Armink <armink.ztl@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
*
|
|
|
|
|
* File: $Id: user_mb_app.c,v 1.60 2013/11/23 11:49:05 Armink $
|
|
|
|
|
*/
|
2013-11-06 21:47:49 +08:00
|
|
|
|
#include "user_mb_app.h"
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|
2013-11-06 21:47:49 +08:00
|
|
|
|
/*------------------------Slave mode use these variables----------------------*/
|
|
|
|
|
//Slave mode:DiscreteInputs variables
|
|
|
|
|
USHORT usSDiscInStart = S_DISCRETE_INPUT_START;
|
|
|
|
|
#if S_DISCRETE_INPUT_NDISCRETES%8
|
|
|
|
|
UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1];
|
|
|
|
|
#else
|
|
|
|
|
UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ;
|
|
|
|
|
#endif
|
|
|
|
|
//Slave mode:Coils variables
|
|
|
|
|
USHORT usSCoilStart = S_COIL_START;
|
|
|
|
|
#if S_COIL_NCOILS%8
|
|
|
|
|
UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ;
|
|
|
|
|
#else
|
|
|
|
|
UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ;
|
|
|
|
|
#endif
|
|
|
|
|
//Slave mode:InputRegister variables
|
|
|
|
|
USHORT usSRegInStart = S_REG_INPUT_START;
|
|
|
|
|
USHORT usSRegInBuf[S_REG_INPUT_NREGS] ;
|
|
|
|
|
//Slave mode:HoldingRegister variables
|
|
|
|
|
USHORT usSRegHoldStart = S_REG_HOLDING_START;
|
|
|
|
|
USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Modbus slave input register callback function.
|
|
|
|
|
*
|
|
|
|
|
* @param pucRegBuffer input register buffer
|
|
|
|
|
* @param usAddress input register address
|
|
|
|
|
* @param usNRegs input register number
|
|
|
|
|
*
|
|
|
|
|
* @return result
|
|
|
|
|
*/
|
|
|
|
|
eMBErrorCode eMBRegInputCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
|
|
|
|
eMBErrorCode eStatus = MB_ENOERR;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT iRegIndex;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
USHORT * pusRegInputBuf;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT REG_INPUT_START;
|
|
|
|
|
USHORT REG_INPUT_NREGS;
|
|
|
|
|
USHORT usRegInStart;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
pusRegInputBuf = usSRegInBuf;
|
|
|
|
|
REG_INPUT_START = S_REG_INPUT_START;
|
|
|
|
|
REG_INPUT_NREGS = S_REG_INPUT_NREGS;
|
|
|
|
|
usRegInStart = usSRegInStart;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* it already plus one in modbus function method. */
|
|
|
|
|
usAddress--;
|
|
|
|
|
|
|
|
|
|
if ((usAddress >= REG_INPUT_START)
|
|
|
|
|
&& (usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS))
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
iRegIndex = usAddress - usRegInStart;
|
|
|
|
|
while (usNRegs > 0)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] >> 8);
|
|
|
|
|
*pucRegBuffer++ = (UCHAR) (pusRegInputBuf[iRegIndex] & 0xFF);
|
2013-11-06 21:47:49 +08:00
|
|
|
|
iRegIndex++;
|
|
|
|
|
usNRegs--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
eStatus = MB_ENOREG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return eStatus;
|
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Modbus slave holding register callback function.
|
|
|
|
|
*
|
|
|
|
|
* @param pucRegBuffer holding register buffer
|
|
|
|
|
* @param usAddress holding register address
|
|
|
|
|
* @param usNRegs holding register number
|
|
|
|
|
* @param eMode read or write
|
|
|
|
|
*
|
|
|
|
|
* @return result
|
|
|
|
|
*/
|
|
|
|
|
eMBErrorCode eMBRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress,
|
|
|
|
|
USHORT usNRegs, eMBRegisterMode eMode)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
|
|
|
|
eMBErrorCode eStatus = MB_ENOERR;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT iRegIndex;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
USHORT * pusRegHoldingBuf;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT REG_HOLDING_START;
|
|
|
|
|
USHORT REG_HOLDING_NREGS;
|
|
|
|
|
USHORT usRegHoldStart;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
pusRegHoldingBuf = usSRegHoldBuf;
|
|
|
|
|
REG_HOLDING_START = S_REG_HOLDING_START;
|
|
|
|
|
REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
|
|
|
|
|
usRegHoldStart = usSRegHoldStart;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* it already plus one in modbus function method. */
|
|
|
|
|
usAddress--;
|
|
|
|
|
|
|
|
|
|
if ((usAddress >= REG_HOLDING_START)
|
|
|
|
|
&& (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
iRegIndex = usAddress - usRegHoldStart;
|
|
|
|
|
switch (eMode)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* read current register values from the protocol stack. */
|
2013-11-06 21:47:49 +08:00
|
|
|
|
case MB_REG_READ:
|
2015-02-05 19:27:24 +08:00
|
|
|
|
while (usNRegs > 0)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
|
|
|
|
|
*pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
|
2013-11-06 21:47:49 +08:00
|
|
|
|
iRegIndex++;
|
|
|
|
|
usNRegs--;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* write current register values with new values from the protocol stack. */
|
2013-11-06 21:47:49 +08:00
|
|
|
|
case MB_REG_WRITE:
|
2015-02-05 19:27:24 +08:00
|
|
|
|
while (usNRegs > 0)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
|
|
|
|
pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
|
|
|
|
|
pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
|
|
|
|
|
iRegIndex++;
|
|
|
|
|
usNRegs--;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
eStatus = MB_ENOREG;
|
|
|
|
|
}
|
|
|
|
|
return eStatus;
|
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Modbus slave coils callback function.
|
|
|
|
|
*
|
|
|
|
|
* @param pucRegBuffer coils buffer
|
|
|
|
|
* @param usAddress coils address
|
|
|
|
|
* @param usNCoils coils number
|
|
|
|
|
* @param eMode read or write
|
|
|
|
|
*
|
|
|
|
|
* @return result
|
|
|
|
|
*/
|
|
|
|
|
eMBErrorCode eMBRegCoilsCB(UCHAR * pucRegBuffer, USHORT usAddress,
|
|
|
|
|
USHORT usNCoils, eMBRegisterMode eMode)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
|
|
|
|
eMBErrorCode eStatus = MB_ENOERR;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT iRegIndex , iRegBitIndex , iNReg;
|
|
|
|
|
UCHAR * pucCoilBuf;
|
|
|
|
|
USHORT COIL_START;
|
|
|
|
|
USHORT COIL_NCOILS;
|
|
|
|
|
USHORT usCoilStart;
|
|
|
|
|
iNReg = usNCoils / 8 + 1;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
pucCoilBuf = ucSCoilBuf;
|
|
|
|
|
COIL_START = S_COIL_START;
|
|
|
|
|
COIL_NCOILS = S_COIL_NCOILS;
|
|
|
|
|
usCoilStart = usSCoilStart;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* it already plus one in modbus function method. */
|
|
|
|
|
usAddress--;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
|
|
|
|
if( ( usAddress >= COIL_START ) &&
|
|
|
|
|
( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
|
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
iRegIndex = (USHORT) (usAddress - usCoilStart) / 8;
|
|
|
|
|
iRegBitIndex = (USHORT) (usAddress - usCoilStart) % 8;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
switch ( eMode )
|
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* read current coil values from the protocol stack. */
|
2013-11-06 21:47:49 +08:00
|
|
|
|
case MB_REG_READ:
|
2015-02-05 19:27:24 +08:00
|
|
|
|
while (iNReg > 0)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
*pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++],
|
|
|
|
|
iRegBitIndex, 8);
|
|
|
|
|
iNReg--;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
pucRegBuffer--;
|
|
|
|
|
/* last coils */
|
|
|
|
|
usNCoils = usNCoils % 8;
|
|
|
|
|
/* filling zero to high bit */
|
|
|
|
|
*pucRegBuffer = *pucRegBuffer << (8 - usNCoils);
|
|
|
|
|
*pucRegBuffer = *pucRegBuffer >> (8 - usNCoils);
|
2013-11-06 21:47:49 +08:00
|
|
|
|
break;
|
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* write current coil values with new values from the protocol stack. */
|
2013-11-06 21:47:49 +08:00
|
|
|
|
case MB_REG_WRITE:
|
2015-02-05 19:27:24 +08:00
|
|
|
|
while (iNReg > 1)
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, 8,
|
|
|
|
|
*pucRegBuffer++);
|
2013-11-06 21:47:49 +08:00
|
|
|
|
iNReg--;
|
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
/* last coils */
|
|
|
|
|
usNCoils = usNCoils % 8;
|
|
|
|
|
/* xMBUtilSetBits has bug when ucNBits is zero */
|
|
|
|
|
if (usNCoils != 0)
|
|
|
|
|
{
|
|
|
|
|
xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
|
|
|
|
|
*pucRegBuffer++);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
eStatus = MB_ENOREG;
|
|
|
|
|
}
|
|
|
|
|
return eStatus;
|
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Modbus slave discrete callback function.
|
|
|
|
|
*
|
|
|
|
|
* @param pucRegBuffer discrete buffer
|
|
|
|
|
* @param usAddress discrete address
|
|
|
|
|
* @param usNDiscrete discrete number
|
|
|
|
|
*
|
|
|
|
|
* @return result
|
|
|
|
|
*/
|
|
|
|
|
eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
|
|
|
|
eMBErrorCode eStatus = MB_ENOERR;
|
2015-02-05 19:27:24 +08:00
|
|
|
|
USHORT iRegIndex , iRegBitIndex , iNReg;
|
|
|
|
|
UCHAR * pucDiscreteInputBuf;
|
|
|
|
|
USHORT DISCRETE_INPUT_START;
|
|
|
|
|
USHORT DISCRETE_INPUT_NDISCRETES;
|
|
|
|
|
USHORT usDiscreteInputStart;
|
|
|
|
|
iNReg = usNDiscrete / 8 + 1;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
pucDiscreteInputBuf = ucSDiscInBuf;
|
|
|
|
|
DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
|
|
|
|
|
DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
|
|
|
|
|
usDiscreteInputStart = usSDiscInStart;
|
|
|
|
|
|
|
|
|
|
/* it already plus one in modbus function method. */
|
|
|
|
|
usAddress--;
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
if ((usAddress >= DISCRETE_INPUT_START)
|
|
|
|
|
&& (usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES))
|
2013-11-06 21:47:49 +08:00
|
|
|
|
{
|
2015-02-05 19:27:24 +08:00
|
|
|
|
iRegIndex = (USHORT) (usAddress - usDiscreteInputStart) / 8; //ÿ<><C3BF><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>
|
|
|
|
|
iRegBitIndex = (USHORT) (usAddress - usDiscreteInputStart) % 8; //<2F><><EFBFBD><EFBFBD><EFBFBD>ڼĴ<DABC><C4B4><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>λ<EFBFBD><CEBB>ַ
|
2013-11-06 21:47:49 +08:00
|
|
|
|
|
2015-02-05 19:27:24 +08:00
|
|
|
|
while (iNReg > 0)
|
|
|
|
|
{
|
|
|
|
|
*pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++],
|
|
|
|
|
iRegBitIndex, 8);
|
|
|
|
|
iNReg--;
|
|
|
|
|
}
|
|
|
|
|
pucRegBuffer--;
|
|
|
|
|
/* last discrete */
|
|
|
|
|
usNDiscrete = usNDiscrete % 8;
|
|
|
|
|
/* filling zero to high bit */
|
|
|
|
|
*pucRegBuffer = *pucRegBuffer << (8 - usNDiscrete);
|
|
|
|
|
*pucRegBuffer = *pucRegBuffer >> (8 - usNDiscrete);
|
2013-11-06 21:47:49 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
eStatus = MB_ENOREG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return eStatus;
|
|
|
|
|
}
|
2015-02-05 19:27:24 +08:00
|
|
|
|
|