1.original from Cam Marshall 2.use for F446RE Test 3.use the interrupt method of uart 4.not change to RTOS yet

Dependents:   RoboticArm Modbus_Gripper_Test

Committer:
stanley1228
Date:
Fri Mar 31 01:47:35 2017 +0000
Revision:
0:aefcdfe9ca2f
1.change the file in "port" folder to F446RE use

Who changed what in which revision?

UserRevisionLine numberNew contents of line
stanley1228 0:aefcdfe9ca2f 1 /*
stanley1228 0:aefcdfe9ca2f 2 * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
stanley1228 0:aefcdfe9ca2f 3 * Copyright (c) 2006 Christian Walter <wolti@sil.at>
stanley1228 0:aefcdfe9ca2f 4 * All rights reserved.
stanley1228 0:aefcdfe9ca2f 5 *
stanley1228 0:aefcdfe9ca2f 6 * Redistribution and use in source and binary forms, with or without
stanley1228 0:aefcdfe9ca2f 7 * modification, are permitted provided that the following conditions
stanley1228 0:aefcdfe9ca2f 8 * are met:
stanley1228 0:aefcdfe9ca2f 9 * 1. Redistributions of source code must retain the above copyright
stanley1228 0:aefcdfe9ca2f 10 * notice, this list of conditions and the following disclaimer.
stanley1228 0:aefcdfe9ca2f 11 * 2. Redistributions in binary form must reproduce the above copyright
stanley1228 0:aefcdfe9ca2f 12 * notice, this list of conditions and the following disclaimer in the
stanley1228 0:aefcdfe9ca2f 13 * documentation and/or other materials provided with the distribution.
stanley1228 0:aefcdfe9ca2f 14 * 3. The name of the author may not be used to endorse or promote products
stanley1228 0:aefcdfe9ca2f 15 * derived from this software without specific prior written permission.
stanley1228 0:aefcdfe9ca2f 16 *
stanley1228 0:aefcdfe9ca2f 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
stanley1228 0:aefcdfe9ca2f 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
stanley1228 0:aefcdfe9ca2f 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
stanley1228 0:aefcdfe9ca2f 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
stanley1228 0:aefcdfe9ca2f 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
stanley1228 0:aefcdfe9ca2f 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
stanley1228 0:aefcdfe9ca2f 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
stanley1228 0:aefcdfe9ca2f 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
stanley1228 0:aefcdfe9ca2f 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
stanley1228 0:aefcdfe9ca2f 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
stanley1228 0:aefcdfe9ca2f 27 *
stanley1228 0:aefcdfe9ca2f 28 * File: $Id: mb.c,v 1.27 2007/02/18 23:45:41 wolti Exp $
stanley1228 0:aefcdfe9ca2f 29 */
stanley1228 0:aefcdfe9ca2f 30
stanley1228 0:aefcdfe9ca2f 31 /* ----------------------- System includes ----------------------------------*/
stanley1228 0:aefcdfe9ca2f 32 #include "stdlib.h"
stanley1228 0:aefcdfe9ca2f 33 #include "string.h"
stanley1228 0:aefcdfe9ca2f 34
stanley1228 0:aefcdfe9ca2f 35 /* ----------------------- Platform includes --------------------------------*/
stanley1228 0:aefcdfe9ca2f 36 #include "port.h"
stanley1228 0:aefcdfe9ca2f 37
stanley1228 0:aefcdfe9ca2f 38 /* ----------------------- Modbus includes ----------------------------------*/
stanley1228 0:aefcdfe9ca2f 39 #include "mb.h"
stanley1228 0:aefcdfe9ca2f 40 #include "mbconfig.h"
stanley1228 0:aefcdfe9ca2f 41 #include "mbframe.h"
stanley1228 0:aefcdfe9ca2f 42 #include "mbproto.h"
stanley1228 0:aefcdfe9ca2f 43 #include "mbfunc.h"
stanley1228 0:aefcdfe9ca2f 44 #include "mbport.h"
stanley1228 0:aefcdfe9ca2f 45 #if MB_RTU_ENABLED == 1
stanley1228 0:aefcdfe9ca2f 46 #include "mbrtu.h"
stanley1228 0:aefcdfe9ca2f 47 #endif
stanley1228 0:aefcdfe9ca2f 48 #if MB_ASCII_ENABLED == 1
stanley1228 0:aefcdfe9ca2f 49 #include "mbascii.h"
stanley1228 0:aefcdfe9ca2f 50 #endif
stanley1228 0:aefcdfe9ca2f 51 #if MB_TCP_ENABLED == 1
stanley1228 0:aefcdfe9ca2f 52 #include "mbtcp.h"
stanley1228 0:aefcdfe9ca2f 53 #endif
stanley1228 0:aefcdfe9ca2f 54
stanley1228 0:aefcdfe9ca2f 55 #ifndef MB_PORT_HAS_CLOSE
stanley1228 0:aefcdfe9ca2f 56 #define MB_PORT_HAS_CLOSE 0
stanley1228 0:aefcdfe9ca2f 57 #endif
stanley1228 0:aefcdfe9ca2f 58
stanley1228 0:aefcdfe9ca2f 59 /* ----------------------- Static variables ---------------------------------*/
stanley1228 0:aefcdfe9ca2f 60
stanley1228 0:aefcdfe9ca2f 61
stanley1228 0:aefcdfe9ca2f 62 static UCHAR ucMBAddress;
stanley1228 0:aefcdfe9ca2f 63 static eMBMode eMBCurrentMode;
stanley1228 0:aefcdfe9ca2f 64
stanley1228 0:aefcdfe9ca2f 65 static enum {
stanley1228 0:aefcdfe9ca2f 66 STATE_ENABLED,
stanley1228 0:aefcdfe9ca2f 67 STATE_DISABLED,
stanley1228 0:aefcdfe9ca2f 68 STATE_NOT_INITIALIZED
stanley1228 0:aefcdfe9ca2f 69 } eMBState = STATE_NOT_INITIALIZED;
stanley1228 0:aefcdfe9ca2f 70
stanley1228 0:aefcdfe9ca2f 71 /* Functions pointer which are initialized in eMBInit( ). Depending on the
stanley1228 0:aefcdfe9ca2f 72 * mode (RTU or ASCII) the are set to the correct implementations.
stanley1228 0:aefcdfe9ca2f 73 */
stanley1228 0:aefcdfe9ca2f 74 static peMBFrameSend peMBFrameSendCur;
stanley1228 0:aefcdfe9ca2f 75 static pvMBFrameStart pvMBFrameStartCur;
stanley1228 0:aefcdfe9ca2f 76 static pvMBFrameStop pvMBFrameStopCur;
stanley1228 0:aefcdfe9ca2f 77 static peMBFrameReceive peMBFrameReceiveCur;
stanley1228 0:aefcdfe9ca2f 78 static pvMBFrameClose pvMBFrameCloseCur;
stanley1228 0:aefcdfe9ca2f 79
stanley1228 0:aefcdfe9ca2f 80 /* Callback functions required by the porting layer. They are called when
stanley1228 0:aefcdfe9ca2f 81 * an external event has happend which includes a timeout or the reception
stanley1228 0:aefcdfe9ca2f 82 * or transmission of a character.
stanley1228 0:aefcdfe9ca2f 83 */
stanley1228 0:aefcdfe9ca2f 84 BOOL( *pxMBFrameCBByteReceived ) ( void );
stanley1228 0:aefcdfe9ca2f 85 BOOL( *pxMBFrameCBTransmitterEmpty ) ( void );
stanley1228 0:aefcdfe9ca2f 86 BOOL( *pxMBPortCBTimerExpired ) ( void );
stanley1228 0:aefcdfe9ca2f 87
stanley1228 0:aefcdfe9ca2f 88 BOOL( *pxMBFrameCBReceiveFSMCur ) ( void );
stanley1228 0:aefcdfe9ca2f 89 BOOL( *pxMBFrameCBTransmitFSMCur ) ( void );
stanley1228 0:aefcdfe9ca2f 90
stanley1228 0:aefcdfe9ca2f 91 /* An array of Modbus functions handlers which associates Modbus function
stanley1228 0:aefcdfe9ca2f 92 * codes with implementing functions.
stanley1228 0:aefcdfe9ca2f 93 */
stanley1228 0:aefcdfe9ca2f 94 static xMBFunctionHandler xFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
stanley1228 0:aefcdfe9ca2f 95 #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 96 {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID},
stanley1228 0:aefcdfe9ca2f 97 #endif
stanley1228 0:aefcdfe9ca2f 98 #if MB_FUNC_READ_INPUT_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 99 {MB_FUNC_READ_INPUT_REGISTER, eMBFuncReadInputRegister},
stanley1228 0:aefcdfe9ca2f 100 #endif
stanley1228 0:aefcdfe9ca2f 101 #if MB_FUNC_READ_HOLDING_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 102 {MB_FUNC_READ_HOLDING_REGISTER, eMBFuncReadHoldingRegister},
stanley1228 0:aefcdfe9ca2f 103 #endif
stanley1228 0:aefcdfe9ca2f 104 #if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 105 {MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBFuncWriteMultipleHoldingRegister},
stanley1228 0:aefcdfe9ca2f 106 #endif
stanley1228 0:aefcdfe9ca2f 107 #if MB_FUNC_WRITE_HOLDING_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 108 {MB_FUNC_WRITE_REGISTER, eMBFuncWriteHoldingRegister},
stanley1228 0:aefcdfe9ca2f 109 #endif
stanley1228 0:aefcdfe9ca2f 110 #if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 111 {MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBFuncReadWriteMultipleHoldingRegister},
stanley1228 0:aefcdfe9ca2f 112 #endif
stanley1228 0:aefcdfe9ca2f 113 #if MB_FUNC_READ_COILS_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 114 {MB_FUNC_READ_COILS, eMBFuncReadCoils},
stanley1228 0:aefcdfe9ca2f 115 #endif
stanley1228 0:aefcdfe9ca2f 116 #if MB_FUNC_WRITE_COIL_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 117 {MB_FUNC_WRITE_SINGLE_COIL, eMBFuncWriteCoil},
stanley1228 0:aefcdfe9ca2f 118 #endif
stanley1228 0:aefcdfe9ca2f 119 #if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 120 {MB_FUNC_WRITE_MULTIPLE_COILS, eMBFuncWriteMultipleCoils},
stanley1228 0:aefcdfe9ca2f 121 #endif
stanley1228 0:aefcdfe9ca2f 122 #if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 123 {MB_FUNC_READ_DISCRETE_INPUTS, eMBFuncReadDiscreteInputs},
stanley1228 0:aefcdfe9ca2f 124 #endif
stanley1228 0:aefcdfe9ca2f 125 };
stanley1228 0:aefcdfe9ca2f 126
stanley1228 0:aefcdfe9ca2f 127 /* ----------------------- Start implementation -----------------------------*/
stanley1228 0:aefcdfe9ca2f 128 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 129 eMBInit( eMBMode eMode, UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity ) {
stanley1228 0:aefcdfe9ca2f 130 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 131
stanley1228 0:aefcdfe9ca2f 132 /* check preconditions */
stanley1228 0:aefcdfe9ca2f 133 if ( ( ucSlaveAddress == MB_ADDRESS_BROADCAST ) ||
stanley1228 0:aefcdfe9ca2f 134 ( ucSlaveAddress < MB_ADDRESS_MIN ) || ( ucSlaveAddress > MB_ADDRESS_MAX ) ) {
stanley1228 0:aefcdfe9ca2f 135 eStatus = MB_EINVAL;
stanley1228 0:aefcdfe9ca2f 136 } else {
stanley1228 0:aefcdfe9ca2f 137 ucMBAddress = ucSlaveAddress;
stanley1228 0:aefcdfe9ca2f 138
stanley1228 0:aefcdfe9ca2f 139 switch ( eMode ) {
stanley1228 0:aefcdfe9ca2f 140 #if MB_RTU_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 141 case MB_RTU:
stanley1228 0:aefcdfe9ca2f 142 pvMBFrameStartCur = eMBRTUStart;
stanley1228 0:aefcdfe9ca2f 143 pvMBFrameStopCur = eMBRTUStop;
stanley1228 0:aefcdfe9ca2f 144 peMBFrameSendCur = eMBRTUSend;
stanley1228 0:aefcdfe9ca2f 145 peMBFrameReceiveCur = eMBRTUReceive;
stanley1228 0:aefcdfe9ca2f 146 pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
stanley1228 0:aefcdfe9ca2f 147 pxMBFrameCBByteReceived = xMBRTUReceiveFSM;
stanley1228 0:aefcdfe9ca2f 148 pxMBFrameCBTransmitterEmpty = xMBRTUTransmitFSM;
stanley1228 0:aefcdfe9ca2f 149 pxMBPortCBTimerExpired = xMBRTUTimerT35Expired;
stanley1228 0:aefcdfe9ca2f 150
stanley1228 0:aefcdfe9ca2f 151 eStatus = eMBRTUInit( ucMBAddress, ucPort, ulBaudRate, eParity );
stanley1228 0:aefcdfe9ca2f 152 break;
stanley1228 0:aefcdfe9ca2f 153 #endif
stanley1228 0:aefcdfe9ca2f 154 #if MB_ASCII_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 155 case MB_ASCII:
stanley1228 0:aefcdfe9ca2f 156 pvMBFrameStartCur = eMBASCIIStart;
stanley1228 0:aefcdfe9ca2f 157 pvMBFrameStopCur = eMBASCIIStop;
stanley1228 0:aefcdfe9ca2f 158 peMBFrameSendCur = eMBASCIISend;
stanley1228 0:aefcdfe9ca2f 159 peMBFrameReceiveCur = eMBASCIIReceive;
stanley1228 0:aefcdfe9ca2f 160 pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBPortClose : NULL;
stanley1228 0:aefcdfe9ca2f 161 pxMBFrameCBByteReceived = xMBASCIIReceiveFSM;
stanley1228 0:aefcdfe9ca2f 162 pxMBFrameCBTransmitterEmpty = xMBASCIITransmitFSM;
stanley1228 0:aefcdfe9ca2f 163 pxMBPortCBTimerExpired = xMBASCIITimerT1SExpired;
stanley1228 0:aefcdfe9ca2f 164
stanley1228 0:aefcdfe9ca2f 165 eStatus = eMBASCIIInit( ucMBAddress, ucPort, ulBaudRate, eParity );
stanley1228 0:aefcdfe9ca2f 166 break;
stanley1228 0:aefcdfe9ca2f 167 #endif
stanley1228 0:aefcdfe9ca2f 168 default:
stanley1228 0:aefcdfe9ca2f 169 eStatus = MB_EINVAL;
stanley1228 0:aefcdfe9ca2f 170 }
stanley1228 0:aefcdfe9ca2f 171
stanley1228 0:aefcdfe9ca2f 172 if ( eStatus == MB_ENOERR ) {
stanley1228 0:aefcdfe9ca2f 173 if ( !xMBPortEventInit( ) ) {
stanley1228 0:aefcdfe9ca2f 174 /* port dependent event module initalization failed. */
stanley1228 0:aefcdfe9ca2f 175 eStatus = MB_EPORTERR;
stanley1228 0:aefcdfe9ca2f 176 } else {
stanley1228 0:aefcdfe9ca2f 177 eMBCurrentMode = eMode;
stanley1228 0:aefcdfe9ca2f 178 eMBState = STATE_DISABLED;
stanley1228 0:aefcdfe9ca2f 179 }
stanley1228 0:aefcdfe9ca2f 180 }
stanley1228 0:aefcdfe9ca2f 181 }
stanley1228 0:aefcdfe9ca2f 182 return eStatus;
stanley1228 0:aefcdfe9ca2f 183 }
stanley1228 0:aefcdfe9ca2f 184
stanley1228 0:aefcdfe9ca2f 185 #if MB_TCP_ENABLED > 0
stanley1228 0:aefcdfe9ca2f 186 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 187 eMBTCPInit( USHORT ucTCPPort ) {
stanley1228 0:aefcdfe9ca2f 188 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 189
stanley1228 0:aefcdfe9ca2f 190 if ( ( eStatus = eMBTCPDoInit( ucTCPPort ) ) != MB_ENOERR ) {
stanley1228 0:aefcdfe9ca2f 191 eMBState = STATE_DISABLED;
stanley1228 0:aefcdfe9ca2f 192 } else if ( !xMBPortEventInit( ) ) {
stanley1228 0:aefcdfe9ca2f 193 /* Port dependent event module initalization failed. */
stanley1228 0:aefcdfe9ca2f 194 eStatus = MB_EPORTERR;
stanley1228 0:aefcdfe9ca2f 195 } else {
stanley1228 0:aefcdfe9ca2f 196 pvMBFrameStartCur = eMBTCPStart;
stanley1228 0:aefcdfe9ca2f 197 pvMBFrameStopCur = eMBTCPStop;
stanley1228 0:aefcdfe9ca2f 198 peMBFrameReceiveCur = eMBTCPReceive;
stanley1228 0:aefcdfe9ca2f 199 peMBFrameSendCur = eMBTCPSend;
stanley1228 0:aefcdfe9ca2f 200 pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBTCPPortClose : NULL;
stanley1228 0:aefcdfe9ca2f 201 ucMBAddress = MB_TCP_PSEUDO_ADDRESS;
stanley1228 0:aefcdfe9ca2f 202 eMBCurrentMode = MB_TCP;
stanley1228 0:aefcdfe9ca2f 203 eMBState = STATE_DISABLED;
stanley1228 0:aefcdfe9ca2f 204 }
stanley1228 0:aefcdfe9ca2f 205 return eStatus;
stanley1228 0:aefcdfe9ca2f 206 }
stanley1228 0:aefcdfe9ca2f 207 #endif
stanley1228 0:aefcdfe9ca2f 208
stanley1228 0:aefcdfe9ca2f 209
stanley1228 0:aefcdfe9ca2f 210 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 211 eMBRegisterCB( UCHAR ucFunctionCode, pxMBFunctionHandler pxHandler ) {
stanley1228 0:aefcdfe9ca2f 212 int i;
stanley1228 0:aefcdfe9ca2f 213 eMBErrorCode eStatus;
stanley1228 0:aefcdfe9ca2f 214
stanley1228 0:aefcdfe9ca2f 215 if ( ( 0 < ucFunctionCode ) && ( ucFunctionCode <= 127 ) ) {
stanley1228 0:aefcdfe9ca2f 216 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 217 if ( pxHandler != NULL ) {
stanley1228 0:aefcdfe9ca2f 218 for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ ) {
stanley1228 0:aefcdfe9ca2f 219 if ( ( xFuncHandlers[i].pxHandler == NULL ) ||
stanley1228 0:aefcdfe9ca2f 220 ( xFuncHandlers[i].pxHandler == pxHandler ) ) {
stanley1228 0:aefcdfe9ca2f 221 xFuncHandlers[i].ucFunctionCode = ucFunctionCode;
stanley1228 0:aefcdfe9ca2f 222 xFuncHandlers[i].pxHandler = pxHandler;
stanley1228 0:aefcdfe9ca2f 223 break;
stanley1228 0:aefcdfe9ca2f 224 }
stanley1228 0:aefcdfe9ca2f 225 }
stanley1228 0:aefcdfe9ca2f 226 eStatus = ( i != MB_FUNC_HANDLERS_MAX ) ? MB_ENOERR : MB_ENORES;
stanley1228 0:aefcdfe9ca2f 227 } else {
stanley1228 0:aefcdfe9ca2f 228 for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ ) {
stanley1228 0:aefcdfe9ca2f 229 if ( xFuncHandlers[i].ucFunctionCode == ucFunctionCode ) {
stanley1228 0:aefcdfe9ca2f 230 xFuncHandlers[i].ucFunctionCode = 0;
stanley1228 0:aefcdfe9ca2f 231 xFuncHandlers[i].pxHandler = NULL;
stanley1228 0:aefcdfe9ca2f 232 break;
stanley1228 0:aefcdfe9ca2f 233 }
stanley1228 0:aefcdfe9ca2f 234 }
stanley1228 0:aefcdfe9ca2f 235 /* Remove can't fail. */
stanley1228 0:aefcdfe9ca2f 236 eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 237 }
stanley1228 0:aefcdfe9ca2f 238 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 239 } else {
stanley1228 0:aefcdfe9ca2f 240 eStatus = MB_EINVAL;
stanley1228 0:aefcdfe9ca2f 241 }
stanley1228 0:aefcdfe9ca2f 242 return eStatus;
stanley1228 0:aefcdfe9ca2f 243 }
stanley1228 0:aefcdfe9ca2f 244
stanley1228 0:aefcdfe9ca2f 245
stanley1228 0:aefcdfe9ca2f 246 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 247 eMBClose( void ) {
stanley1228 0:aefcdfe9ca2f 248 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 249
stanley1228 0:aefcdfe9ca2f 250 if ( eMBState == STATE_DISABLED ) {
stanley1228 0:aefcdfe9ca2f 251 if ( pvMBFrameCloseCur != NULL ) {
stanley1228 0:aefcdfe9ca2f 252 pvMBFrameCloseCur( );
stanley1228 0:aefcdfe9ca2f 253 }
stanley1228 0:aefcdfe9ca2f 254 } else {
stanley1228 0:aefcdfe9ca2f 255 eStatus = MB_EILLSTATE;
stanley1228 0:aefcdfe9ca2f 256 }
stanley1228 0:aefcdfe9ca2f 257 return eStatus;
stanley1228 0:aefcdfe9ca2f 258 }
stanley1228 0:aefcdfe9ca2f 259
stanley1228 0:aefcdfe9ca2f 260 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 261 eMBEnable( void ) {
stanley1228 0:aefcdfe9ca2f 262 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 263
stanley1228 0:aefcdfe9ca2f 264 if ( eMBState == STATE_DISABLED ) {
stanley1228 0:aefcdfe9ca2f 265 /* Activate the protocol stack. */
stanley1228 0:aefcdfe9ca2f 266 pvMBFrameStartCur( );
stanley1228 0:aefcdfe9ca2f 267 eMBState = STATE_ENABLED;
stanley1228 0:aefcdfe9ca2f 268 } else {
stanley1228 0:aefcdfe9ca2f 269 eStatus = MB_EILLSTATE;
stanley1228 0:aefcdfe9ca2f 270 }
stanley1228 0:aefcdfe9ca2f 271 return eStatus;
stanley1228 0:aefcdfe9ca2f 272 }
stanley1228 0:aefcdfe9ca2f 273
stanley1228 0:aefcdfe9ca2f 274 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 275 eMBDisable( void ) {
stanley1228 0:aefcdfe9ca2f 276 eMBErrorCode eStatus;
stanley1228 0:aefcdfe9ca2f 277
stanley1228 0:aefcdfe9ca2f 278 if ( eMBState == STATE_ENABLED ) {
stanley1228 0:aefcdfe9ca2f 279 pvMBFrameStopCur( );
stanley1228 0:aefcdfe9ca2f 280 eMBState = STATE_DISABLED;
stanley1228 0:aefcdfe9ca2f 281 eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 282 } else if ( eMBState == STATE_DISABLED ) {
stanley1228 0:aefcdfe9ca2f 283 eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 284 } else {
stanley1228 0:aefcdfe9ca2f 285 eStatus = MB_EILLSTATE;
stanley1228 0:aefcdfe9ca2f 286 }
stanley1228 0:aefcdfe9ca2f 287 return eStatus;
stanley1228 0:aefcdfe9ca2f 288 }
stanley1228 0:aefcdfe9ca2f 289
stanley1228 0:aefcdfe9ca2f 290 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 291 eMBPoll( void ) {
stanley1228 0:aefcdfe9ca2f 292 static UCHAR *ucMBFrame;
stanley1228 0:aefcdfe9ca2f 293 static UCHAR ucRcvAddress;
stanley1228 0:aefcdfe9ca2f 294 static UCHAR ucFunctionCode;
stanley1228 0:aefcdfe9ca2f 295 static USHORT usLength;
stanley1228 0:aefcdfe9ca2f 296 static eMBException eException;
stanley1228 0:aefcdfe9ca2f 297
stanley1228 0:aefcdfe9ca2f 298 int i;
stanley1228 0:aefcdfe9ca2f 299 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 300 eMBEventType eEvent;
stanley1228 0:aefcdfe9ca2f 301
stanley1228 0:aefcdfe9ca2f 302 /* Check if the protocol stack is ready. */
stanley1228 0:aefcdfe9ca2f 303 if ( eMBState != STATE_ENABLED ) {
stanley1228 0:aefcdfe9ca2f 304 return MB_EILLSTATE;
stanley1228 0:aefcdfe9ca2f 305 }
stanley1228 0:aefcdfe9ca2f 306
stanley1228 0:aefcdfe9ca2f 307 /* Check if there is a event available. If not return control to caller.
stanley1228 0:aefcdfe9ca2f 308 * Otherwise we will handle the event. */
stanley1228 0:aefcdfe9ca2f 309 if ( xMBPortEventGet( &eEvent ) == TRUE ) {
stanley1228 0:aefcdfe9ca2f 310 switch ( eEvent ) {
stanley1228 0:aefcdfe9ca2f 311 case EV_READY:
stanley1228 0:aefcdfe9ca2f 312 break;
stanley1228 0:aefcdfe9ca2f 313
stanley1228 0:aefcdfe9ca2f 314 case EV_FRAME_RECEIVED:
stanley1228 0:aefcdfe9ca2f 315 eStatus = peMBFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength );
stanley1228 0:aefcdfe9ca2f 316 if ( eStatus == MB_ENOERR ) {
stanley1228 0:aefcdfe9ca2f 317 /* Check if the frame is for us. If not ignore the frame. */
stanley1228 0:aefcdfe9ca2f 318 if ( ( ucRcvAddress == ucMBAddress ) || ( ucRcvAddress == MB_ADDRESS_BROADCAST ) ) {
stanley1228 0:aefcdfe9ca2f 319 ( void )xMBPortEventPost( EV_EXECUTE );
stanley1228 0:aefcdfe9ca2f 320 }
stanley1228 0:aefcdfe9ca2f 321 }
stanley1228 0:aefcdfe9ca2f 322 break;
stanley1228 0:aefcdfe9ca2f 323
stanley1228 0:aefcdfe9ca2f 324 case EV_EXECUTE:
stanley1228 0:aefcdfe9ca2f 325 ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
stanley1228 0:aefcdfe9ca2f 326 eException = MB_EX_ILLEGAL_FUNCTION;
stanley1228 0:aefcdfe9ca2f 327
stanley1228 0:aefcdfe9ca2f 328
stanley1228 0:aefcdfe9ca2f 329 for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ ) {
stanley1228 0:aefcdfe9ca2f 330 /* No more function handlers registered. Abort. */
stanley1228 0:aefcdfe9ca2f 331 if ( xFuncHandlers[i].ucFunctionCode == 0 ) {
stanley1228 0:aefcdfe9ca2f 332 break;
stanley1228 0:aefcdfe9ca2f 333 } else if ( xFuncHandlers[i].ucFunctionCode == ucFunctionCode ) {
stanley1228 0:aefcdfe9ca2f 334 eException = xFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
stanley1228 0:aefcdfe9ca2f 335 break;
stanley1228 0:aefcdfe9ca2f 336 }
stanley1228 0:aefcdfe9ca2f 337 }
stanley1228 0:aefcdfe9ca2f 338
stanley1228 0:aefcdfe9ca2f 339 /* If the request was not sent to the broadcast address we
stanley1228 0:aefcdfe9ca2f 340 * return a reply. */
stanley1228 0:aefcdfe9ca2f 341 if ( ucRcvAddress != MB_ADDRESS_BROADCAST ) {
stanley1228 0:aefcdfe9ca2f 342 if ( eException != MB_EX_NONE ) {
stanley1228 0:aefcdfe9ca2f 343 /* An exception occured. Build an error frame. */
stanley1228 0:aefcdfe9ca2f 344 usLength = 0;
stanley1228 0:aefcdfe9ca2f 345 ucMBFrame[usLength++] = ( UCHAR )( ucFunctionCode | MB_FUNC_ERROR );
stanley1228 0:aefcdfe9ca2f 346 ucMBFrame[usLength++] = eException;
stanley1228 0:aefcdfe9ca2f 347 }
stanley1228 0:aefcdfe9ca2f 348 eStatus = peMBFrameSendCur( ucMBAddress, ucMBFrame, usLength );
stanley1228 0:aefcdfe9ca2f 349 }
stanley1228 0:aefcdfe9ca2f 350 break;
stanley1228 0:aefcdfe9ca2f 351
stanley1228 0:aefcdfe9ca2f 352 case EV_FRAME_SENT:
stanley1228 0:aefcdfe9ca2f 353 break;
stanley1228 0:aefcdfe9ca2f 354 }
stanley1228 0:aefcdfe9ca2f 355 }
stanley1228 0:aefcdfe9ca2f 356 return MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 357 }