Port of the FreeModbus Libary for mbed, copied from https://developer.mbed.org/users/cam/code/Modbus/ and upgraded to mbed 5

Dependents:   NUCLEO-F401-printf

Committer:
Rajit Singh
Date:
Wed Aug 16 17:31:26 2017 +0100
Revision:
1:3e360cf155b6
Parent:
0:9db3bed8fffd
Remove main.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Rajit Singh 0:9db3bed8fffd 1 /*
Rajit Singh 0:9db3bed8fffd 2 * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
Rajit Singh 0:9db3bed8fffd 3 * Copyright (c) 2006 Christian Walter <wolti@sil.at>
Rajit Singh 0:9db3bed8fffd 4 * All rights reserved.
Rajit Singh 0:9db3bed8fffd 5 *
Rajit Singh 0:9db3bed8fffd 6 * Redistribution and use in source and binary forms, with or without
Rajit Singh 0:9db3bed8fffd 7 * modification, are permitted provided that the following conditions
Rajit Singh 0:9db3bed8fffd 8 * are met:
Rajit Singh 0:9db3bed8fffd 9 * 1. Redistributions of source code must retain the above copyright
Rajit Singh 0:9db3bed8fffd 10 * notice, this list of conditions and the following disclaimer.
Rajit Singh 0:9db3bed8fffd 11 * 2. Redistributions in binary form must reproduce the above copyright
Rajit Singh 0:9db3bed8fffd 12 * notice, this list of conditions and the following disclaimer in the
Rajit Singh 0:9db3bed8fffd 13 * documentation and/or other materials provided with the distribution.
Rajit Singh 0:9db3bed8fffd 14 * 3. The name of the author may not be used to endorse or promote products
Rajit Singh 0:9db3bed8fffd 15 * derived from this software without specific prior written permission.
Rajit Singh 0:9db3bed8fffd 16 *
Rajit Singh 0:9db3bed8fffd 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
Rajit Singh 0:9db3bed8fffd 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Rajit Singh 0:9db3bed8fffd 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Rajit Singh 0:9db3bed8fffd 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
Rajit Singh 0:9db3bed8fffd 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Rajit Singh 0:9db3bed8fffd 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Rajit Singh 0:9db3bed8fffd 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Rajit Singh 0:9db3bed8fffd 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Rajit Singh 0:9db3bed8fffd 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Rajit Singh 0:9db3bed8fffd 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Rajit Singh 0:9db3bed8fffd 27 *
Rajit Singh 0:9db3bed8fffd 28 * File: $Id: mbrtu.c,v 1.18 2007/09/12 10:15:56 wolti Exp $
Rajit Singh 0:9db3bed8fffd 29 */
Rajit Singh 0:9db3bed8fffd 30
Rajit Singh 0:9db3bed8fffd 31 /* ----------------------- System includes ----------------------------------*/
Rajit Singh 0:9db3bed8fffd 32 #include "stdlib.h"
Rajit Singh 0:9db3bed8fffd 33 #include "string.h"
Rajit Singh 0:9db3bed8fffd 34
Rajit Singh 0:9db3bed8fffd 35 /* ----------------------- Platform includes --------------------------------*/
Rajit Singh 0:9db3bed8fffd 36 #include "port.h"
Rajit Singh 0:9db3bed8fffd 37
Rajit Singh 0:9db3bed8fffd 38 /* ----------------------- Modbus includes ----------------------------------*/
Rajit Singh 0:9db3bed8fffd 39 #include "mb.h"
Rajit Singh 0:9db3bed8fffd 40 #include "mbrtu.h"
Rajit Singh 0:9db3bed8fffd 41 #include "mbframe.h"
Rajit Singh 0:9db3bed8fffd 42
Rajit Singh 0:9db3bed8fffd 43 #include "mbcrc.h"
Rajit Singh 0:9db3bed8fffd 44 #include "mbport.h"
Rajit Singh 0:9db3bed8fffd 45
Rajit Singh 0:9db3bed8fffd 46 /* ----------------------- Defines ------------------------------------------*/
Rajit Singh 0:9db3bed8fffd 47 #define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */
Rajit Singh 0:9db3bed8fffd 48 #define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */
Rajit Singh 0:9db3bed8fffd 49 #define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */
Rajit Singh 0:9db3bed8fffd 50 #define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
Rajit Singh 0:9db3bed8fffd 51 #define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
Rajit Singh 0:9db3bed8fffd 52
Rajit Singh 0:9db3bed8fffd 53 /* ----------------------- Type definitions ---------------------------------*/
Rajit Singh 0:9db3bed8fffd 54 typedef enum
Rajit Singh 0:9db3bed8fffd 55 {
Rajit Singh 0:9db3bed8fffd 56 STATE_RX_INIT, /*!< Receiver is in initial state. */
Rajit Singh 0:9db3bed8fffd 57 STATE_RX_IDLE, /*!< Receiver is in idle state. */
Rajit Singh 0:9db3bed8fffd 58 STATE_RX_RCV, /*!< Frame is beeing received. */
Rajit Singh 0:9db3bed8fffd 59 STATE_RX_ERROR /*!< If the frame is invalid. */
Rajit Singh 0:9db3bed8fffd 60 } eMBRcvState;
Rajit Singh 0:9db3bed8fffd 61
Rajit Singh 0:9db3bed8fffd 62 typedef enum
Rajit Singh 0:9db3bed8fffd 63 {
Rajit Singh 0:9db3bed8fffd 64 STATE_TX_IDLE, /*!< Transmitter is in idle state. */
Rajit Singh 0:9db3bed8fffd 65 STATE_TX_XMIT /*!< Transmitter is in transfer state. */
Rajit Singh 0:9db3bed8fffd 66 } eMBSndState;
Rajit Singh 0:9db3bed8fffd 67
Rajit Singh 0:9db3bed8fffd 68 /* ----------------------- Static variables ---------------------------------*/
Rajit Singh 0:9db3bed8fffd 69 static volatile eMBSndState eSndState;
Rajit Singh 0:9db3bed8fffd 70 static volatile eMBRcvState eRcvState;
Rajit Singh 0:9db3bed8fffd 71
Rajit Singh 0:9db3bed8fffd 72 volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX];
Rajit Singh 0:9db3bed8fffd 73
Rajit Singh 0:9db3bed8fffd 74 static volatile UCHAR *pucSndBufferCur;
Rajit Singh 0:9db3bed8fffd 75 static volatile USHORT usSndBufferCount;
Rajit Singh 0:9db3bed8fffd 76
Rajit Singh 0:9db3bed8fffd 77 static volatile USHORT usRcvBufferPos;
Rajit Singh 0:9db3bed8fffd 78
Rajit Singh 0:9db3bed8fffd 79 /* ----------------------- Start implementation -----------------------------*/
Rajit Singh 0:9db3bed8fffd 80 eMBErrorCode
Rajit Singh 0:9db3bed8fffd 81 eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
Rajit Singh 0:9db3bed8fffd 82 {
Rajit Singh 0:9db3bed8fffd 83 eMBErrorCode eStatus = MB_ENOERR;
Rajit Singh 0:9db3bed8fffd 84 ULONG usTimerT35_50us;
Rajit Singh 0:9db3bed8fffd 85
Rajit Singh 0:9db3bed8fffd 86 ( void )ucSlaveAddress;
Rajit Singh 0:9db3bed8fffd 87 ENTER_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 88
Rajit Singh 0:9db3bed8fffd 89 /* Modbus RTU uses 8 Databits. */
Rajit Singh 0:9db3bed8fffd 90 if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE )
Rajit Singh 0:9db3bed8fffd 91 {
Rajit Singh 0:9db3bed8fffd 92 eStatus = MB_EPORTERR;
Rajit Singh 0:9db3bed8fffd 93 }
Rajit Singh 0:9db3bed8fffd 94 else
Rajit Singh 0:9db3bed8fffd 95 {
Rajit Singh 0:9db3bed8fffd 96 /* If baudrate > 19200 then we should use the fixed timer values
Rajit Singh 0:9db3bed8fffd 97 * t35 = 1750us. Otherwise t35 must be 3.5 times the character time.
Rajit Singh 0:9db3bed8fffd 98 */
Rajit Singh 0:9db3bed8fffd 99 if( ulBaudRate > 19200 )
Rajit Singh 0:9db3bed8fffd 100 {
Rajit Singh 0:9db3bed8fffd 101 usTimerT35_50us = 35; /* 1800us. */
Rajit Singh 0:9db3bed8fffd 102 }
Rajit Singh 0:9db3bed8fffd 103 else
Rajit Singh 0:9db3bed8fffd 104 {
Rajit Singh 0:9db3bed8fffd 105 /* The timer reload value for a character is given by:
Rajit Singh 0:9db3bed8fffd 106 *
Rajit Singh 0:9db3bed8fffd 107 * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 )
Rajit Singh 0:9db3bed8fffd 108 * = 11 * Ticks_per_1s / Baudrate
Rajit Singh 0:9db3bed8fffd 109 * = 220000 / Baudrate
Rajit Singh 0:9db3bed8fffd 110 * The reload for t3.5 is 1.5 times this value and similary
Rajit Singh 0:9db3bed8fffd 111 * for t3.5.
Rajit Singh 0:9db3bed8fffd 112 */
Rajit Singh 0:9db3bed8fffd 113 usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate );
Rajit Singh 0:9db3bed8fffd 114 }
Rajit Singh 0:9db3bed8fffd 115 if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE )
Rajit Singh 0:9db3bed8fffd 116 {
Rajit Singh 0:9db3bed8fffd 117 eStatus = MB_EPORTERR;
Rajit Singh 0:9db3bed8fffd 118 }
Rajit Singh 0:9db3bed8fffd 119 }
Rajit Singh 0:9db3bed8fffd 120 EXIT_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 121
Rajit Singh 0:9db3bed8fffd 122 return eStatus;
Rajit Singh 0:9db3bed8fffd 123 }
Rajit Singh 0:9db3bed8fffd 124
Rajit Singh 0:9db3bed8fffd 125 void
Rajit Singh 0:9db3bed8fffd 126 eMBRTUStart( void )
Rajit Singh 0:9db3bed8fffd 127 {
Rajit Singh 0:9db3bed8fffd 128 ENTER_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 129 /* Initially the receiver is in the state STATE_RX_INIT. we start
Rajit Singh 0:9db3bed8fffd 130 * the timer and if no character is received within t3.5 we change
Rajit Singh 0:9db3bed8fffd 131 * to STATE_RX_IDLE. This makes sure that we delay startup of the
Rajit Singh 0:9db3bed8fffd 132 * modbus protocol stack until the bus is free.
Rajit Singh 0:9db3bed8fffd 133 */
Rajit Singh 0:9db3bed8fffd 134 eRcvState = STATE_RX_INIT;
Rajit Singh 0:9db3bed8fffd 135 vMBPortSerialEnable( TRUE, FALSE );
Rajit Singh 0:9db3bed8fffd 136 vMBPortTimersEnable( );
Rajit Singh 0:9db3bed8fffd 137 EXIT_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 138 }
Rajit Singh 0:9db3bed8fffd 139
Rajit Singh 0:9db3bed8fffd 140 void
Rajit Singh 0:9db3bed8fffd 141 eMBRTUStop( void )
Rajit Singh 0:9db3bed8fffd 142 {
Rajit Singh 0:9db3bed8fffd 143 ENTER_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 144 vMBPortSerialEnable( FALSE, FALSE );
Rajit Singh 0:9db3bed8fffd 145 vMBPortTimersDisable( );
Rajit Singh 0:9db3bed8fffd 146 EXIT_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 147 }
Rajit Singh 0:9db3bed8fffd 148
Rajit Singh 0:9db3bed8fffd 149 eMBErrorCode
Rajit Singh 0:9db3bed8fffd 150 eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
Rajit Singh 0:9db3bed8fffd 151 {
Rajit Singh 0:9db3bed8fffd 152 BOOL xFrameReceived = FALSE;
Rajit Singh 0:9db3bed8fffd 153 eMBErrorCode eStatus = MB_ENOERR;
Rajit Singh 0:9db3bed8fffd 154
Rajit Singh 0:9db3bed8fffd 155 ENTER_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 156 assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
Rajit Singh 0:9db3bed8fffd 157
Rajit Singh 0:9db3bed8fffd 158 /* Length and CRC check */
Rajit Singh 0:9db3bed8fffd 159 if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
Rajit Singh 0:9db3bed8fffd 160 && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
Rajit Singh 0:9db3bed8fffd 161 {
Rajit Singh 0:9db3bed8fffd 162 /* Save the address field. All frames are passed to the upper layer
Rajit Singh 0:9db3bed8fffd 163 * and the decision if a frame is used is done there.
Rajit Singh 0:9db3bed8fffd 164 */
Rajit Singh 0:9db3bed8fffd 165 *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];
Rajit Singh 0:9db3bed8fffd 166
Rajit Singh 0:9db3bed8fffd 167 /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
Rajit Singh 0:9db3bed8fffd 168 * size of address field and CRC checksum.
Rajit Singh 0:9db3bed8fffd 169 */
Rajit Singh 0:9db3bed8fffd 170 *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
Rajit Singh 0:9db3bed8fffd 171
Rajit Singh 0:9db3bed8fffd 172 /* Return the start of the Modbus PDU to the caller. */
Rajit Singh 0:9db3bed8fffd 173 *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
Rajit Singh 0:9db3bed8fffd 174 xFrameReceived = TRUE;
Rajit Singh 0:9db3bed8fffd 175
Rajit Singh 0:9db3bed8fffd 176 // Added by Cam
Rajit Singh 0:9db3bed8fffd 177 // Now that the poll routine knows about the received frame,
Rajit Singh 0:9db3bed8fffd 178 // clear the receive buffer position ready for the next frame received
Rajit Singh 0:9db3bed8fffd 179 usRcvBufferPos = 0;
Rajit Singh 0:9db3bed8fffd 180
Rajit Singh 0:9db3bed8fffd 181 }
Rajit Singh 0:9db3bed8fffd 182 else
Rajit Singh 0:9db3bed8fffd 183 {
Rajit Singh 0:9db3bed8fffd 184 eStatus = MB_EIO;
Rajit Singh 0:9db3bed8fffd 185 }
Rajit Singh 0:9db3bed8fffd 186
Rajit Singh 0:9db3bed8fffd 187 EXIT_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 188 return eStatus;
Rajit Singh 0:9db3bed8fffd 189 }
Rajit Singh 0:9db3bed8fffd 190
Rajit Singh 0:9db3bed8fffd 191 eMBErrorCode
Rajit Singh 0:9db3bed8fffd 192 eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
Rajit Singh 0:9db3bed8fffd 193 {
Rajit Singh 0:9db3bed8fffd 194 eMBErrorCode eStatus = MB_ENOERR;
Rajit Singh 0:9db3bed8fffd 195 USHORT usCRC16;
Rajit Singh 0:9db3bed8fffd 196
Rajit Singh 0:9db3bed8fffd 197 ENTER_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 198
Rajit Singh 0:9db3bed8fffd 199 /* Check if the receiver is still in idle state. If not we where to
Rajit Singh 0:9db3bed8fffd 200 * slow with processing the received frame and the master sent another
Rajit Singh 0:9db3bed8fffd 201 * frame on the network. We have to abort sending the frame.
Rajit Singh 0:9db3bed8fffd 202 */
Rajit Singh 0:9db3bed8fffd 203 if( eRcvState == STATE_RX_IDLE )
Rajit Singh 0:9db3bed8fffd 204 {
Rajit Singh 0:9db3bed8fffd 205 /* First byte before the Modbus-PDU is the slave address. */
Rajit Singh 0:9db3bed8fffd 206 pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
Rajit Singh 0:9db3bed8fffd 207 usSndBufferCount = 1;
Rajit Singh 0:9db3bed8fffd 208
Rajit Singh 0:9db3bed8fffd 209 /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
Rajit Singh 0:9db3bed8fffd 210 pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
Rajit Singh 0:9db3bed8fffd 211 usSndBufferCount += usLength;
Rajit Singh 0:9db3bed8fffd 212
Rajit Singh 0:9db3bed8fffd 213 /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
Rajit Singh 0:9db3bed8fffd 214 usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
Rajit Singh 0:9db3bed8fffd 215 ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
Rajit Singh 0:9db3bed8fffd 216 ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
Rajit Singh 0:9db3bed8fffd 217
Rajit Singh 0:9db3bed8fffd 218 /* Activate the transmitter. */
Rajit Singh 0:9db3bed8fffd 219 eSndState = STATE_TX_XMIT;
Rajit Singh 0:9db3bed8fffd 220 vMBPortSerialEnable( FALSE, TRUE );
Rajit Singh 0:9db3bed8fffd 221 }
Rajit Singh 0:9db3bed8fffd 222 else
Rajit Singh 0:9db3bed8fffd 223 {
Rajit Singh 0:9db3bed8fffd 224 eStatus = MB_EIO;
Rajit Singh 0:9db3bed8fffd 225 }
Rajit Singh 0:9db3bed8fffd 226 EXIT_CRITICAL_SECTION( );
Rajit Singh 0:9db3bed8fffd 227 return eStatus;
Rajit Singh 0:9db3bed8fffd 228 }
Rajit Singh 0:9db3bed8fffd 229
Rajit Singh 0:9db3bed8fffd 230 BOOL
Rajit Singh 0:9db3bed8fffd 231 xMBRTUReceiveFSM( void )
Rajit Singh 0:9db3bed8fffd 232 {
Rajit Singh 0:9db3bed8fffd 233 BOOL xTaskNeedSwitch = FALSE;
Rajit Singh 0:9db3bed8fffd 234 UCHAR ucByte;
Rajit Singh 0:9db3bed8fffd 235
Rajit Singh 0:9db3bed8fffd 236 assert( eSndState == STATE_TX_IDLE );
Rajit Singh 0:9db3bed8fffd 237
Rajit Singh 0:9db3bed8fffd 238 /* Always read the character. */
Rajit Singh 0:9db3bed8fffd 239 ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
Rajit Singh 0:9db3bed8fffd 240
Rajit Singh 0:9db3bed8fffd 241 switch ( eRcvState )
Rajit Singh 0:9db3bed8fffd 242 {
Rajit Singh 0:9db3bed8fffd 243 /* If we have received a character in the init state we have to
Rajit Singh 0:9db3bed8fffd 244 * wait until the frame is finished.
Rajit Singh 0:9db3bed8fffd 245 */
Rajit Singh 0:9db3bed8fffd 246 case STATE_RX_INIT:
Rajit Singh 0:9db3bed8fffd 247 vMBPortTimersEnable( );
Rajit Singh 0:9db3bed8fffd 248 break;
Rajit Singh 0:9db3bed8fffd 249
Rajit Singh 0:9db3bed8fffd 250 /* In the error state we wait until all characters in the
Rajit Singh 0:9db3bed8fffd 251 * damaged frame are transmitted.
Rajit Singh 0:9db3bed8fffd 252 */
Rajit Singh 0:9db3bed8fffd 253 case STATE_RX_ERROR:
Rajit Singh 0:9db3bed8fffd 254 vMBPortTimersEnable( );
Rajit Singh 0:9db3bed8fffd 255 break;
Rajit Singh 0:9db3bed8fffd 256
Rajit Singh 0:9db3bed8fffd 257 /* In the idle state we wait for a new character. If a character
Rajit Singh 0:9db3bed8fffd 258 * is received the t1.5 and t3.5 timers are started and the
Rajit Singh 0:9db3bed8fffd 259 * receiver is in the state STATE_RX_RECEIVE.
Rajit Singh 0:9db3bed8fffd 260 */
Rajit Singh 0:9db3bed8fffd 261 case STATE_RX_IDLE:
Rajit Singh 0:9db3bed8fffd 262 ucRTUBuf[usRcvBufferPos++] = ucByte;
Rajit Singh 0:9db3bed8fffd 263 eRcvState = STATE_RX_RCV;
Rajit Singh 0:9db3bed8fffd 264
Rajit Singh 0:9db3bed8fffd 265 /* Enable t3.5 timers. */
Rajit Singh 0:9db3bed8fffd 266 vMBPortTimersEnable( );
Rajit Singh 0:9db3bed8fffd 267 break;
Rajit Singh 0:9db3bed8fffd 268
Rajit Singh 0:9db3bed8fffd 269 /* We are currently receiving a frame. Reset the timer after
Rajit Singh 0:9db3bed8fffd 270 * every character received. If more than the maximum possible
Rajit Singh 0:9db3bed8fffd 271 * number of bytes in a modbus frame is received the frame is
Rajit Singh 0:9db3bed8fffd 272 * ignored.
Rajit Singh 0:9db3bed8fffd 273 */
Rajit Singh 0:9db3bed8fffd 274 case STATE_RX_RCV:
Rajit Singh 0:9db3bed8fffd 275 if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
Rajit Singh 0:9db3bed8fffd 276 {
Rajit Singh 0:9db3bed8fffd 277 ucRTUBuf[usRcvBufferPos++] = ucByte;
Rajit Singh 0:9db3bed8fffd 278 }
Rajit Singh 0:9db3bed8fffd 279 else
Rajit Singh 0:9db3bed8fffd 280 {
Rajit Singh 0:9db3bed8fffd 281 eRcvState = STATE_RX_ERROR;
Rajit Singh 0:9db3bed8fffd 282 }
Rajit Singh 0:9db3bed8fffd 283 vMBPortTimersEnable( );
Rajit Singh 0:9db3bed8fffd 284 break;
Rajit Singh 0:9db3bed8fffd 285 }
Rajit Singh 0:9db3bed8fffd 286 return xTaskNeedSwitch;
Rajit Singh 0:9db3bed8fffd 287 }
Rajit Singh 0:9db3bed8fffd 288
Rajit Singh 0:9db3bed8fffd 289 BOOL
Rajit Singh 0:9db3bed8fffd 290 xMBRTUTransmitFSM( void )
Rajit Singh 0:9db3bed8fffd 291 {
Rajit Singh 0:9db3bed8fffd 292 BOOL xNeedPoll = FALSE;
Rajit Singh 0:9db3bed8fffd 293
Rajit Singh 0:9db3bed8fffd 294 assert( eRcvState == STATE_RX_IDLE );
Rajit Singh 0:9db3bed8fffd 295 switch ( eSndState )
Rajit Singh 0:9db3bed8fffd 296 {
Rajit Singh 0:9db3bed8fffd 297 /* We should not get a transmitter event if the transmitter is in
Rajit Singh 0:9db3bed8fffd 298 * idle state. */
Rajit Singh 0:9db3bed8fffd 299 case STATE_TX_IDLE:
Rajit Singh 0:9db3bed8fffd 300 /* enable receiver/disable transmitter. */
Rajit Singh 0:9db3bed8fffd 301 vMBPortSerialEnable( TRUE, FALSE );
Rajit Singh 0:9db3bed8fffd 302 break;
Rajit Singh 0:9db3bed8fffd 303
Rajit Singh 0:9db3bed8fffd 304 case STATE_TX_XMIT:
Rajit Singh 0:9db3bed8fffd 305 /* check if we are finished. */
Rajit Singh 0:9db3bed8fffd 306 if( usSndBufferCount != 0 )
Rajit Singh 0:9db3bed8fffd 307 {
Rajit Singh 0:9db3bed8fffd 308 xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
Rajit Singh 0:9db3bed8fffd 309 pucSndBufferCur++; /* next byte in sendbuffer. */
Rajit Singh 0:9db3bed8fffd 310 usSndBufferCount--;
Rajit Singh 0:9db3bed8fffd 311 }
Rajit Singh 0:9db3bed8fffd 312 else
Rajit Singh 0:9db3bed8fffd 313 {
Rajit Singh 0:9db3bed8fffd 314 xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
Rajit Singh 0:9db3bed8fffd 315 /* Disable transmitter. This prevents another transmit buffer
Rajit Singh 0:9db3bed8fffd 316 * empty interrupt. */
Rajit Singh 0:9db3bed8fffd 317 vMBPortSerialEnable( TRUE, FALSE );
Rajit Singh 0:9db3bed8fffd 318 eSndState = STATE_TX_IDLE;
Rajit Singh 0:9db3bed8fffd 319 }
Rajit Singh 0:9db3bed8fffd 320 break;
Rajit Singh 0:9db3bed8fffd 321 }
Rajit Singh 0:9db3bed8fffd 322
Rajit Singh 0:9db3bed8fffd 323 return xNeedPoll;
Rajit Singh 0:9db3bed8fffd 324 }
Rajit Singh 0:9db3bed8fffd 325
Rajit Singh 0:9db3bed8fffd 326 BOOL
Rajit Singh 0:9db3bed8fffd 327 xMBRTUTimerT35Expired( void )
Rajit Singh 0:9db3bed8fffd 328 {
Rajit Singh 0:9db3bed8fffd 329 BOOL xNeedPoll = FALSE;
Rajit Singh 0:9db3bed8fffd 330
Rajit Singh 0:9db3bed8fffd 331 switch ( eRcvState )
Rajit Singh 0:9db3bed8fffd 332 {
Rajit Singh 0:9db3bed8fffd 333 /* Timer t35 expired. Startup phase is finished. */
Rajit Singh 0:9db3bed8fffd 334 case STATE_RX_INIT:
Rajit Singh 0:9db3bed8fffd 335 xNeedPoll = xMBPortEventPost( EV_READY );
Rajit Singh 0:9db3bed8fffd 336 break;
Rajit Singh 0:9db3bed8fffd 337
Rajit Singh 0:9db3bed8fffd 338 /* A frame was received and t35 expired. Notify the listener that
Rajit Singh 0:9db3bed8fffd 339 * a new frame was received. */
Rajit Singh 0:9db3bed8fffd 340 case STATE_RX_RCV:
Rajit Singh 0:9db3bed8fffd 341 xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED );
Rajit Singh 0:9db3bed8fffd 342 break;
Rajit Singh 0:9db3bed8fffd 343
Rajit Singh 0:9db3bed8fffd 344 /* An error occured while receiving the frame. */
Rajit Singh 0:9db3bed8fffd 345 case STATE_RX_ERROR:
Rajit Singh 0:9db3bed8fffd 346 break;
Rajit Singh 0:9db3bed8fffd 347
Rajit Singh 0:9db3bed8fffd 348 /* Function called in an illegal state. */
Rajit Singh 0:9db3bed8fffd 349 default:
Rajit Singh 0:9db3bed8fffd 350 assert( ( eRcvState == STATE_RX_INIT ) ||
Rajit Singh 0:9db3bed8fffd 351 ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
Rajit Singh 0:9db3bed8fffd 352 }
Rajit Singh 0:9db3bed8fffd 353
Rajit Singh 0:9db3bed8fffd 354 vMBPortTimersDisable( );
Rajit Singh 0:9db3bed8fffd 355 eRcvState = STATE_RX_IDLE;
Rajit Singh 0:9db3bed8fffd 356
Rajit Singh 0:9db3bed8fffd 357 return xNeedPoll;
Rajit Singh 0:9db3bed8fffd 358 }