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: mbrtu.c,v 1.18 2007/09/12 10:15:56 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 "mbrtu.h"
stanley1228 0:aefcdfe9ca2f 41 #include "mbframe.h"
stanley1228 0:aefcdfe9ca2f 42
stanley1228 0:aefcdfe9ca2f 43 #include "mbcrc.h"
stanley1228 0:aefcdfe9ca2f 44 #include "mbport.h"
stanley1228 0:aefcdfe9ca2f 45
stanley1228 0:aefcdfe9ca2f 46 /* ----------------------- Defines ------------------------------------------*/
stanley1228 0:aefcdfe9ca2f 47 #define MB_SER_PDU_SIZE_MIN 4 /*!< Minimum size of a Modbus RTU frame. */
stanley1228 0:aefcdfe9ca2f 48 #define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus RTU frame. */
stanley1228 0:aefcdfe9ca2f 49 #define MB_SER_PDU_SIZE_CRC 2 /*!< Size of CRC field in PDU. */
stanley1228 0:aefcdfe9ca2f 50 #define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
stanley1228 0:aefcdfe9ca2f 51 #define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
stanley1228 0:aefcdfe9ca2f 52
stanley1228 0:aefcdfe9ca2f 53 /* ----------------------- Type definitions ---------------------------------*/
stanley1228 0:aefcdfe9ca2f 54 typedef enum
stanley1228 0:aefcdfe9ca2f 55 {
stanley1228 0:aefcdfe9ca2f 56 STATE_RX_INIT, /*!< Receiver is in initial state. */
stanley1228 0:aefcdfe9ca2f 57 STATE_RX_IDLE, /*!< Receiver is in idle state. */
stanley1228 0:aefcdfe9ca2f 58 STATE_RX_RCV, /*!< Frame is beeing received. */
stanley1228 0:aefcdfe9ca2f 59 STATE_RX_ERROR /*!< If the frame is invalid. */
stanley1228 0:aefcdfe9ca2f 60 } eMBRcvState;
stanley1228 0:aefcdfe9ca2f 61
stanley1228 0:aefcdfe9ca2f 62 typedef enum
stanley1228 0:aefcdfe9ca2f 63 {
stanley1228 0:aefcdfe9ca2f 64 STATE_TX_IDLE, /*!< Transmitter is in idle state. */
stanley1228 0:aefcdfe9ca2f 65 STATE_TX_XMIT /*!< Transmitter is in transfer state. */
stanley1228 0:aefcdfe9ca2f 66 } eMBSndState;
stanley1228 0:aefcdfe9ca2f 67
stanley1228 0:aefcdfe9ca2f 68 /* ----------------------- Static variables ---------------------------------*/
stanley1228 0:aefcdfe9ca2f 69 static volatile eMBSndState eSndState;
stanley1228 0:aefcdfe9ca2f 70 static volatile eMBRcvState eRcvState;
stanley1228 0:aefcdfe9ca2f 71
stanley1228 0:aefcdfe9ca2f 72 volatile UCHAR ucRTUBuf[MB_SER_PDU_SIZE_MAX];
stanley1228 0:aefcdfe9ca2f 73
stanley1228 0:aefcdfe9ca2f 74 static volatile UCHAR *pucSndBufferCur;
stanley1228 0:aefcdfe9ca2f 75 static volatile USHORT usSndBufferCount;
stanley1228 0:aefcdfe9ca2f 76
stanley1228 0:aefcdfe9ca2f 77 static volatile USHORT usRcvBufferPos;
stanley1228 0:aefcdfe9ca2f 78
stanley1228 0:aefcdfe9ca2f 79 /* ----------------------- Start implementation -----------------------------*/
stanley1228 0:aefcdfe9ca2f 80 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 81 eMBRTUInit( UCHAR ucSlaveAddress, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
stanley1228 0:aefcdfe9ca2f 82 {
stanley1228 0:aefcdfe9ca2f 83 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 84 ULONG usTimerT35_50us;
stanley1228 0:aefcdfe9ca2f 85
stanley1228 0:aefcdfe9ca2f 86 ( void )ucSlaveAddress;
stanley1228 0:aefcdfe9ca2f 87 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 88
stanley1228 0:aefcdfe9ca2f 89 /* Modbus RTU uses 8 Databits. */
stanley1228 0:aefcdfe9ca2f 90 if( xMBPortSerialInit( ucPort, ulBaudRate, 8, eParity ) != TRUE )
stanley1228 0:aefcdfe9ca2f 91 {
stanley1228 0:aefcdfe9ca2f 92 eStatus = MB_EPORTERR;
stanley1228 0:aefcdfe9ca2f 93 }
stanley1228 0:aefcdfe9ca2f 94 else
stanley1228 0:aefcdfe9ca2f 95 {
stanley1228 0:aefcdfe9ca2f 96 /* If baudrate > 19200 then we should use the fixed timer values
stanley1228 0:aefcdfe9ca2f 97 * t35 = 1750us. Otherwise t35 must be 3.5 times the character time.
stanley1228 0:aefcdfe9ca2f 98 */
stanley1228 0:aefcdfe9ca2f 99 if( ulBaudRate > 19200 )
stanley1228 0:aefcdfe9ca2f 100 {
stanley1228 0:aefcdfe9ca2f 101 usTimerT35_50us = 35; /* 1800us. */
stanley1228 0:aefcdfe9ca2f 102 }
stanley1228 0:aefcdfe9ca2f 103 else
stanley1228 0:aefcdfe9ca2f 104 {
stanley1228 0:aefcdfe9ca2f 105 /* The timer reload value for a character is given by:
stanley1228 0:aefcdfe9ca2f 106 *
stanley1228 0:aefcdfe9ca2f 107 * ChTimeValue = Ticks_per_1s / ( Baudrate / 11 )
stanley1228 0:aefcdfe9ca2f 108 * = 11 * Ticks_per_1s / Baudrate
stanley1228 0:aefcdfe9ca2f 109 * = 220000 / Baudrate
stanley1228 0:aefcdfe9ca2f 110 * The reload for t3.5 is 1.5 times this value and similary
stanley1228 0:aefcdfe9ca2f 111 * for t3.5.
stanley1228 0:aefcdfe9ca2f 112 */
stanley1228 0:aefcdfe9ca2f 113 usTimerT35_50us = ( 7UL * 220000UL ) / ( 2UL * ulBaudRate );
stanley1228 0:aefcdfe9ca2f 114 }
stanley1228 0:aefcdfe9ca2f 115 if( xMBPortTimersInit( ( USHORT ) usTimerT35_50us ) != TRUE )
stanley1228 0:aefcdfe9ca2f 116 {
stanley1228 0:aefcdfe9ca2f 117 eStatus = MB_EPORTERR;
stanley1228 0:aefcdfe9ca2f 118 }
stanley1228 0:aefcdfe9ca2f 119 }
stanley1228 0:aefcdfe9ca2f 120 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 121
stanley1228 0:aefcdfe9ca2f 122 return eStatus;
stanley1228 0:aefcdfe9ca2f 123 }
stanley1228 0:aefcdfe9ca2f 124
stanley1228 0:aefcdfe9ca2f 125 void
stanley1228 0:aefcdfe9ca2f 126 eMBRTUStart( void )
stanley1228 0:aefcdfe9ca2f 127 {
stanley1228 0:aefcdfe9ca2f 128 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 129 /* Initially the receiver is in the state STATE_RX_INIT. we start
stanley1228 0:aefcdfe9ca2f 130 * the timer and if no character is received within t3.5 we change
stanley1228 0:aefcdfe9ca2f 131 * to STATE_RX_IDLE. This makes sure that we delay startup of the
stanley1228 0:aefcdfe9ca2f 132 * modbus protocol stack until the bus is free.
stanley1228 0:aefcdfe9ca2f 133 */
stanley1228 0:aefcdfe9ca2f 134 eRcvState = STATE_RX_INIT;
stanley1228 0:aefcdfe9ca2f 135 vMBPortSerialEnable( TRUE, FALSE );
stanley1228 0:aefcdfe9ca2f 136 vMBPortTimersEnable( );
stanley1228 0:aefcdfe9ca2f 137
stanley1228 0:aefcdfe9ca2f 138 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 139 }
stanley1228 0:aefcdfe9ca2f 140
stanley1228 0:aefcdfe9ca2f 141 void
stanley1228 0:aefcdfe9ca2f 142 eMBRTUStop( void )
stanley1228 0:aefcdfe9ca2f 143 {
stanley1228 0:aefcdfe9ca2f 144 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 145 vMBPortSerialEnable( FALSE, FALSE );
stanley1228 0:aefcdfe9ca2f 146 vMBPortTimersDisable( );
stanley1228 0:aefcdfe9ca2f 147 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 148 }
stanley1228 0:aefcdfe9ca2f 149
stanley1228 0:aefcdfe9ca2f 150 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 151 eMBRTUReceive( UCHAR * pucRcvAddress, UCHAR ** pucFrame, USHORT * pusLength )
stanley1228 0:aefcdfe9ca2f 152 {
stanley1228 0:aefcdfe9ca2f 153 BOOL xFrameReceived = FALSE;
stanley1228 0:aefcdfe9ca2f 154 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 155
stanley1228 0:aefcdfe9ca2f 156 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 157 assert( usRcvBufferPos < MB_SER_PDU_SIZE_MAX );
stanley1228 0:aefcdfe9ca2f 158
stanley1228 0:aefcdfe9ca2f 159 /* Length and CRC check */
stanley1228 0:aefcdfe9ca2f 160 if( ( usRcvBufferPos >= MB_SER_PDU_SIZE_MIN )
stanley1228 0:aefcdfe9ca2f 161 && ( usMBCRC16( ( UCHAR * ) ucRTUBuf, usRcvBufferPos ) == 0 ) )
stanley1228 0:aefcdfe9ca2f 162 {
stanley1228 0:aefcdfe9ca2f 163 /* Save the address field. All frames are passed to the upper layed
stanley1228 0:aefcdfe9ca2f 164 * and the decision if a frame is used is done there.
stanley1228 0:aefcdfe9ca2f 165 */
stanley1228 0:aefcdfe9ca2f 166 *pucRcvAddress = ucRTUBuf[MB_SER_PDU_ADDR_OFF];
stanley1228 0:aefcdfe9ca2f 167
stanley1228 0:aefcdfe9ca2f 168 /* Total length of Modbus-PDU is Modbus-Serial-Line-PDU minus
stanley1228 0:aefcdfe9ca2f 169 * size of address field and CRC checksum.
stanley1228 0:aefcdfe9ca2f 170 */
stanley1228 0:aefcdfe9ca2f 171 *pusLength = ( USHORT )( usRcvBufferPos - MB_SER_PDU_PDU_OFF - MB_SER_PDU_SIZE_CRC );
stanley1228 0:aefcdfe9ca2f 172
stanley1228 0:aefcdfe9ca2f 173 /* Return the start of the Modbus PDU to the caller. */
stanley1228 0:aefcdfe9ca2f 174 *pucFrame = ( UCHAR * ) & ucRTUBuf[MB_SER_PDU_PDU_OFF];
stanley1228 0:aefcdfe9ca2f 175 xFrameReceived = TRUE;
stanley1228 0:aefcdfe9ca2f 176
stanley1228 0:aefcdfe9ca2f 177 // Added by Cam
stanley1228 0:aefcdfe9ca2f 178 // Now that the poll routine knows about the received frame,
stanley1228 0:aefcdfe9ca2f 179 // clear the receive buffer position ready for the next frame received
stanley1228 0:aefcdfe9ca2f 180 //usRcvBufferPos = 0;
stanley1228 0:aefcdfe9ca2f 181
stanley1228 0:aefcdfe9ca2f 182 }
stanley1228 0:aefcdfe9ca2f 183 else
stanley1228 0:aefcdfe9ca2f 184 {
stanley1228 0:aefcdfe9ca2f 185 eStatus = MB_EIO;
stanley1228 0:aefcdfe9ca2f 186 }
stanley1228 0:aefcdfe9ca2f 187
stanley1228 0:aefcdfe9ca2f 188 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 189 return eStatus;
stanley1228 0:aefcdfe9ca2f 190 }
stanley1228 0:aefcdfe9ca2f 191
stanley1228 0:aefcdfe9ca2f 192 eMBErrorCode
stanley1228 0:aefcdfe9ca2f 193 eMBRTUSend( UCHAR ucSlaveAddress, const UCHAR * pucFrame, USHORT usLength )
stanley1228 0:aefcdfe9ca2f 194 {
stanley1228 0:aefcdfe9ca2f 195 eMBErrorCode eStatus = MB_ENOERR;
stanley1228 0:aefcdfe9ca2f 196 USHORT usCRC16;
stanley1228 0:aefcdfe9ca2f 197
stanley1228 0:aefcdfe9ca2f 198 ENTER_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 199
stanley1228 0:aefcdfe9ca2f 200 /* Check if the receiver is still in idle state. If not we where to
stanley1228 0:aefcdfe9ca2f 201 * slow with processing the received frame and the master sent another
stanley1228 0:aefcdfe9ca2f 202 * frame on the network. We have to abort sending the frame.
stanley1228 0:aefcdfe9ca2f 203 */
stanley1228 0:aefcdfe9ca2f 204 if( eRcvState == STATE_RX_IDLE )
stanley1228 0:aefcdfe9ca2f 205 {
stanley1228 0:aefcdfe9ca2f 206 /* First byte before the Modbus-PDU is the slave address. */
stanley1228 0:aefcdfe9ca2f 207 pucSndBufferCur = ( UCHAR * ) pucFrame - 1;
stanley1228 0:aefcdfe9ca2f 208 usSndBufferCount = 1;
stanley1228 0:aefcdfe9ca2f 209
stanley1228 0:aefcdfe9ca2f 210 /* Now copy the Modbus-PDU into the Modbus-Serial-Line-PDU. */
stanley1228 0:aefcdfe9ca2f 211 pucSndBufferCur[MB_SER_PDU_ADDR_OFF] = ucSlaveAddress;
stanley1228 0:aefcdfe9ca2f 212 usSndBufferCount += usLength;
stanley1228 0:aefcdfe9ca2f 213
stanley1228 0:aefcdfe9ca2f 214 /* Calculate CRC16 checksum for Modbus-Serial-Line-PDU. */
stanley1228 0:aefcdfe9ca2f 215 usCRC16 = usMBCRC16( ( UCHAR * ) pucSndBufferCur, usSndBufferCount );
stanley1228 0:aefcdfe9ca2f 216 ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 & 0xFF );
stanley1228 0:aefcdfe9ca2f 217 ucRTUBuf[usSndBufferCount++] = ( UCHAR )( usCRC16 >> 8 );
stanley1228 0:aefcdfe9ca2f 218
stanley1228 0:aefcdfe9ca2f 219 /* Activate the transmitter. */
stanley1228 0:aefcdfe9ca2f 220 eSndState = STATE_TX_XMIT;
stanley1228 0:aefcdfe9ca2f 221 vMBPortSerialEnable( FALSE, TRUE );
stanley1228 0:aefcdfe9ca2f 222 }
stanley1228 0:aefcdfe9ca2f 223 else
stanley1228 0:aefcdfe9ca2f 224 {
stanley1228 0:aefcdfe9ca2f 225 eStatus = MB_EIO;
stanley1228 0:aefcdfe9ca2f 226 }
stanley1228 0:aefcdfe9ca2f 227 EXIT_CRITICAL_SECTION( );
stanley1228 0:aefcdfe9ca2f 228 return eStatus;
stanley1228 0:aefcdfe9ca2f 229 }
stanley1228 0:aefcdfe9ca2f 230
stanley1228 0:aefcdfe9ca2f 231 BOOL
stanley1228 0:aefcdfe9ca2f 232 xMBRTUReceiveFSM( void )
stanley1228 0:aefcdfe9ca2f 233 {
stanley1228 0:aefcdfe9ca2f 234 BOOL xTaskNeedSwitch = FALSE;
stanley1228 0:aefcdfe9ca2f 235 UCHAR ucByte;
stanley1228 0:aefcdfe9ca2f 236
stanley1228 0:aefcdfe9ca2f 237 assert( eSndState == STATE_TX_IDLE );
stanley1228 0:aefcdfe9ca2f 238
stanley1228 0:aefcdfe9ca2f 239 /* Always read the character. */
stanley1228 0:aefcdfe9ca2f 240 ( void )xMBPortSerialGetByte( ( CHAR * ) & ucByte );
stanley1228 0:aefcdfe9ca2f 241
stanley1228 0:aefcdfe9ca2f 242 switch ( eRcvState )
stanley1228 0:aefcdfe9ca2f 243 {
stanley1228 0:aefcdfe9ca2f 244 /* If we have received a character in the init state we have to
stanley1228 0:aefcdfe9ca2f 245 * wait until the frame is finished.
stanley1228 0:aefcdfe9ca2f 246 */
stanley1228 0:aefcdfe9ca2f 247 case STATE_RX_INIT:
stanley1228 0:aefcdfe9ca2f 248 vMBPortTimersEnable( );
stanley1228 0:aefcdfe9ca2f 249 break;
stanley1228 0:aefcdfe9ca2f 250
stanley1228 0:aefcdfe9ca2f 251 /* In the error state we wait until all characters in the
stanley1228 0:aefcdfe9ca2f 252 * damaged frame are transmitted.
stanley1228 0:aefcdfe9ca2f 253 */
stanley1228 0:aefcdfe9ca2f 254 case STATE_RX_ERROR:
stanley1228 0:aefcdfe9ca2f 255 vMBPortTimersEnable( );
stanley1228 0:aefcdfe9ca2f 256 break;
stanley1228 0:aefcdfe9ca2f 257
stanley1228 0:aefcdfe9ca2f 258 /* In the idle state we wait for a new character. If a character
stanley1228 0:aefcdfe9ca2f 259 * is received the t1.5 and t3.5 timers are started and the
stanley1228 0:aefcdfe9ca2f 260 * receiver is in the state STATE_RX_RECEIVCE.
stanley1228 0:aefcdfe9ca2f 261 */
stanley1228 0:aefcdfe9ca2f 262 case STATE_RX_IDLE:
stanley1228 0:aefcdfe9ca2f 263 usRcvBufferPos = 0; //cam will comment this
stanley1228 0:aefcdfe9ca2f 264 ucRTUBuf[usRcvBufferPos++] = ucByte;
stanley1228 0:aefcdfe9ca2f 265 eRcvState = STATE_RX_RCV;
stanley1228 0:aefcdfe9ca2f 266
stanley1228 0:aefcdfe9ca2f 267 /* Enable t3.5 timers. */
stanley1228 0:aefcdfe9ca2f 268 vMBPortTimersEnable( );
stanley1228 0:aefcdfe9ca2f 269 break;
stanley1228 0:aefcdfe9ca2f 270
stanley1228 0:aefcdfe9ca2f 271 /* We are currently receiving a frame. Reset the timer after
stanley1228 0:aefcdfe9ca2f 272 * every character received. If more than the maximum possible
stanley1228 0:aefcdfe9ca2f 273 * number of bytes in a modbus frame is received the frame is
stanley1228 0:aefcdfe9ca2f 274 * ignored.
stanley1228 0:aefcdfe9ca2f 275 */
stanley1228 0:aefcdfe9ca2f 276 case STATE_RX_RCV:
stanley1228 0:aefcdfe9ca2f 277 if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
stanley1228 0:aefcdfe9ca2f 278 {
stanley1228 0:aefcdfe9ca2f 279 ucRTUBuf[usRcvBufferPos++] = ucByte;
stanley1228 0:aefcdfe9ca2f 280 }
stanley1228 0:aefcdfe9ca2f 281 else
stanley1228 0:aefcdfe9ca2f 282 {
stanley1228 0:aefcdfe9ca2f 283 eRcvState = STATE_RX_ERROR;
stanley1228 0:aefcdfe9ca2f 284 }
stanley1228 0:aefcdfe9ca2f 285 vMBPortTimersEnable( );
stanley1228 0:aefcdfe9ca2f 286 break;
stanley1228 0:aefcdfe9ca2f 287 }
stanley1228 0:aefcdfe9ca2f 288 return xTaskNeedSwitch;
stanley1228 0:aefcdfe9ca2f 289 }
stanley1228 0:aefcdfe9ca2f 290
stanley1228 0:aefcdfe9ca2f 291 BOOL
stanley1228 0:aefcdfe9ca2f 292 xMBRTUTransmitFSM( void )
stanley1228 0:aefcdfe9ca2f 293 {
stanley1228 0:aefcdfe9ca2f 294 BOOL xNeedPoll = FALSE;
stanley1228 0:aefcdfe9ca2f 295
stanley1228 0:aefcdfe9ca2f 296 assert( eRcvState == STATE_RX_IDLE );
stanley1228 0:aefcdfe9ca2f 297
stanley1228 0:aefcdfe9ca2f 298 switch ( eSndState )
stanley1228 0:aefcdfe9ca2f 299 {
stanley1228 0:aefcdfe9ca2f 300 /* We should not get a transmitter event if the transmitter is in
stanley1228 0:aefcdfe9ca2f 301 * idle state. */
stanley1228 0:aefcdfe9ca2f 302 case STATE_TX_IDLE:
stanley1228 0:aefcdfe9ca2f 303 /* enable receiver/disable transmitter. */
stanley1228 0:aefcdfe9ca2f 304 vMBPortSerialEnable( TRUE, FALSE );
stanley1228 0:aefcdfe9ca2f 305 break;
stanley1228 0:aefcdfe9ca2f 306
stanley1228 0:aefcdfe9ca2f 307 case STATE_TX_XMIT:
stanley1228 0:aefcdfe9ca2f 308 /* check if we are finished. */
stanley1228 0:aefcdfe9ca2f 309 if( usSndBufferCount != 0 )
stanley1228 0:aefcdfe9ca2f 310 {
stanley1228 0:aefcdfe9ca2f 311 xMBPortSerialPutByte( ( CHAR )*pucSndBufferCur );
stanley1228 0:aefcdfe9ca2f 312 pucSndBufferCur++; /* next byte in sendbuffer. */
stanley1228 0:aefcdfe9ca2f 313 usSndBufferCount--;
stanley1228 0:aefcdfe9ca2f 314 }
stanley1228 0:aefcdfe9ca2f 315 else
stanley1228 0:aefcdfe9ca2f 316 {
stanley1228 0:aefcdfe9ca2f 317 xNeedPoll = xMBPortEventPost( EV_FRAME_SENT );
stanley1228 0:aefcdfe9ca2f 318 /* Disable transmitter. This prevents another transmit buffer
stanley1228 0:aefcdfe9ca2f 319 * empty interrupt. */
stanley1228 0:aefcdfe9ca2f 320 vMBPortSerialEnable( TRUE, FALSE );
stanley1228 0:aefcdfe9ca2f 321 eSndState = STATE_TX_IDLE;
stanley1228 0:aefcdfe9ca2f 322 }
stanley1228 0:aefcdfe9ca2f 323 break;
stanley1228 0:aefcdfe9ca2f 324 }
stanley1228 0:aefcdfe9ca2f 325
stanley1228 0:aefcdfe9ca2f 326 return xNeedPoll;
stanley1228 0:aefcdfe9ca2f 327 }
stanley1228 0:aefcdfe9ca2f 328
stanley1228 0:aefcdfe9ca2f 329 BOOL
stanley1228 0:aefcdfe9ca2f 330 xMBRTUTimerT35Expired( void )
stanley1228 0:aefcdfe9ca2f 331 {
stanley1228 0:aefcdfe9ca2f 332 BOOL xNeedPoll = FALSE;
stanley1228 0:aefcdfe9ca2f 333
stanley1228 0:aefcdfe9ca2f 334 switch ( eRcvState )
stanley1228 0:aefcdfe9ca2f 335 {
stanley1228 0:aefcdfe9ca2f 336 /* Timer t35 expired. Startup phase is finished. */
stanley1228 0:aefcdfe9ca2f 337 case STATE_RX_INIT:
stanley1228 0:aefcdfe9ca2f 338 xNeedPoll = xMBPortEventPost( EV_READY );
stanley1228 0:aefcdfe9ca2f 339 break;
stanley1228 0:aefcdfe9ca2f 340
stanley1228 0:aefcdfe9ca2f 341 /* A frame was received and t35 expired. Notify the listener that
stanley1228 0:aefcdfe9ca2f 342 * a new frame was received. */
stanley1228 0:aefcdfe9ca2f 343 case STATE_RX_RCV:
stanley1228 0:aefcdfe9ca2f 344 xNeedPoll = xMBPortEventPost( EV_FRAME_RECEIVED );
stanley1228 0:aefcdfe9ca2f 345 break;
stanley1228 0:aefcdfe9ca2f 346
stanley1228 0:aefcdfe9ca2f 347 /* An error occured while receiving the frame. */
stanley1228 0:aefcdfe9ca2f 348 case STATE_RX_ERROR:
stanley1228 0:aefcdfe9ca2f 349 break;
stanley1228 0:aefcdfe9ca2f 350
stanley1228 0:aefcdfe9ca2f 351 /* Function called in an illegal state. */
stanley1228 0:aefcdfe9ca2f 352 default:
stanley1228 0:aefcdfe9ca2f 353 assert( ( eRcvState == STATE_RX_INIT ) ||
stanley1228 0:aefcdfe9ca2f 354 ( eRcvState == STATE_RX_RCV ) || ( eRcvState == STATE_RX_ERROR ) );
stanley1228 0:aefcdfe9ca2f 355 }
stanley1228 0:aefcdfe9ca2f 356
stanley1228 0:aefcdfe9ca2f 357 vMBPortTimersDisable( );
stanley1228 0:aefcdfe9ca2f 358 eRcvState = STATE_RX_IDLE;
stanley1228 0:aefcdfe9ca2f 359
stanley1228 0:aefcdfe9ca2f 360 return xNeedPoll;
stanley1228 0:aefcdfe9ca2f 361 }