Modified version of ModbusTCP

Dependencies:   EthernetNetIf mbed

Committer:
paleskyjp
Date:
Tue Mar 13 09:11:49 2012 +0000
Revision:
0:62be54b8975d
The first modification of ModbusTCP

Who changed what in which revision?

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