Forking https://os.mbed.com/users/cam/code/Modbus/ to work for NUCLEO 64 boards

Fork of Cam's original FreeModbus port (https://os.mbed.com/users/cam/code/Modbus/)

Change: - Serial implementation to work for NUCLEO 64 boards and receive interrupts instead of timer. (see `portserial.cpp`)

Added: - Custom RTU mode. Allows for external implementation of packet receiving and sending. Sends and receives packets as whole frames (address + PDU) (i.e. this was added for a custom LoRa implementation). implement `xMBRTUCustGetPDU` and `xMBRTUCustSendResponse` (see `mbport.h`) and call `eMBRTUCustomInit( address )`. implementations need to be fully initialised as `eMBRTUCustomInit` only sets the address and nothing else.

Committer:
danielmckinnell
Date:
Tue Aug 04 04:42:52 2020 +0000
Revision:
4:7621103c5a40
Parent:
0:0453a0a7e500
RTU Serial updates

Who changed what in which revision?

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