modified for NuMaker_PFM series

Dependents:   NuMaker-mbed-modbus-sample NuMaker_NuWicam_Lite NuMaker-mbed-modbus-sample

Fork of Modbus by Wayne Lin

Committer:
cyliang
Date:
Thu Feb 25 15:36:09 2021 +0800
Revision:
10:288aeae1458f
Parent:
3:419ee4c5e10f
Change serial R/W method to fulfill OS v6.x API

Who changed what in which revision?

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