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 */ 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 */ 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 */ 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 */ 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