1 /*
2 * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
3 * Copyright (C) 2013 Armink <armink.ztl@gmail.com>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * File: $Id: mbrtu_m.c,v 1.60 2013/08/20 11:18:10 Armink Add Master Functions $
29 */
30
31 /* ----------------------- System includes ----------------------------------*/
32 #include "stdlib.h"
33 #include "string.h"
34
35 /* ----------------------- Platform includes --------------------------------*/
36 #include "port.h"
37
38 /* ----------------------- Modbus includes ----------------------------------*/
39
40 #include "mb_m.h"
41 #include "mbconfig.h"
42 #include "mbframe.h"
43 #include "mbproto.h"
44 #include "mbfunc.h"
45
46 #include "mbport.h"
47 #if MB_MASTER_RTU_ENABLED
48 #include "mbrtu.h"
49 #endif
50 #if MB_MASTER_ASCII_ENABLED
51 #include "mbascii.h"
52 #endif
53 #if MB_MASTER_TCP_ENABLED
54 #include "mbtcp.h"
55 #include "mbtcp_m.h"
56 #endif
57
58 #if MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
59
60 #ifndef MB_PORT_HAS_CLOSE
61 #define MB_PORT_HAS_CLOSE 1
62 #endif
63
64 /* ----------------------- Static variables ---------------------------------*/
65
66 static UCHAR ucMBMasterDestAddress;
67 static BOOL xMBRunInMasterMode = FALSE;
68 static volatile eMBMasterErrorEventType eMBMasterCurErrorType;
69 static volatile USHORT usMasterSendPDULength;
70 static volatile eMBMode eMBMasterCurrentMode;
71
72 /*------------------------ Shared variables ---------------------------------*/
73
74 volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
75 volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
76 volatile eMBMasterTimerMode eMasterCurTimerMode;
77 volatile BOOL xFrameIsBroadcast = FALSE;
78
79 static enum
80 {
81 STATE_ENABLED,
82 STATE_DISABLED,
83 STATE_NOT_INITIALIZED
84 } eMBState = STATE_NOT_INITIALIZED;
85
86 /* Functions pointer which are initialized in eMBInit( ). Depending on the
87 * mode (RTU or ASCII) the are set to the correct implementations.
88 * Using for Modbus Master,Add by Armink 20130813
89 */
90 static peMBFrameSend peMBMasterFrameSendCur;
91 static pvMBFrameStart pvMBMasterFrameStartCur;
92 static pvMBFrameStop pvMBMasterFrameStopCur;
93 static peMBFrameReceive peMBMasterFrameReceiveCur;
94 static pvMBFrameClose pvMBMasterFrameCloseCur;
95
96 /* Callback functions required by the porting layer. They are called when
97 * an external event has happend which includes a timeout or the reception
98 * or transmission of a character.
99 * Using for Modbus Master,Add by Armink 20130813
100 */
101 BOOL( *pxMBMasterFrameCBByteReceived ) ( void );
102
103 BOOL( *pxMBMasterFrameCBTransmitterEmpty ) ( void );
104
105 BOOL( *pxMBMasterPortCBTimerExpired ) ( void );
106
107 BOOL( *pxMBMasterFrameCBReceiveFSMCur ) ( void );
108
109 BOOL( *pxMBMasterFrameCBTransmitFSMCur ) ( void );
110
111 /* An array of Modbus functions handlers which associates Modbus function
112 * codes with implementing functions.
113 */
114 static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = {
115 #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0
116 {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID},
117 #endif
118 #if MB_FUNC_READ_INPUT_ENABLED > 0
119 {MB_FUNC_READ_INPUT_REGISTER, eMBMasterFuncReadInputRegister},
120 #endif
121 #if MB_FUNC_READ_HOLDING_ENABLED > 0
122 {MB_FUNC_READ_HOLDING_REGISTER, eMBMasterFuncReadHoldingRegister},
123 #endif
124 #if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0
125 {MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBMasterFuncWriteMultipleHoldingRegister},
126 #endif
127 #if MB_FUNC_WRITE_HOLDING_ENABLED > 0
128 {MB_FUNC_WRITE_REGISTER, eMBMasterFuncWriteHoldingRegister},
129 #endif
130 #if MB_FUNC_READWRITE_HOLDING_ENABLED > 0
131 {MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBMasterFuncReadWriteMultipleHoldingRegister},
132 #endif
133 #if MB_FUNC_READ_COILS_ENABLED > 0
134 {MB_FUNC_READ_COILS, eMBMasterFuncReadCoils},
135 #endif
136 #if MB_FUNC_WRITE_COIL_ENABLED > 0
137 {MB_FUNC_WRITE_SINGLE_COIL, eMBMasterFuncWriteCoil},
138 #endif
139 #if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0
140 {MB_FUNC_WRITE_MULTIPLE_COILS, eMBMasterFuncWriteMultipleCoils},
141 #endif
142 #if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0
143 {MB_FUNC_READ_DISCRETE_INPUTS, eMBMasterFuncReadDiscreteInputs},
144 #endif
145 };
146
147 /* ----------------------- Start implementation -----------------------------*/
148 #if MB_MASTER_TCP_ENABLED > 0
149 eMBErrorCode
eMBMasterTCPInit(USHORT ucTCPPort)150 eMBMasterTCPInit( USHORT ucTCPPort )
151 {
152 eMBErrorCode eStatus = MB_ENOERR;
153
154 if( ( eStatus = eMBMasterTCPDoInit( ucTCPPort ) ) != MB_ENOERR ) {
155 eMBState = STATE_DISABLED;
156 }
157 else if( !xMBMasterPortEventInit( ) ) {
158 /* Port dependent event module initialization failed. */
159 eStatus = MB_EPORTERR;
160 } else {
161 pvMBMasterFrameStartCur = eMBMasterTCPStart;
162 pvMBMasterFrameStopCur = eMBMasterTCPStop;
163 peMBMasterFrameReceiveCur = eMBMasterTCPReceive;
164 peMBMasterFrameSendCur = eMBMasterTCPSend;
165 pxMBMasterPortCBTimerExpired = xMBMasterTCPTimerExpired;
166 pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterTCPPortClose : NULL;
167 ucMBMasterDestAddress = MB_TCP_PSEUDO_ADDRESS;
168 eMBMasterCurrentMode = MB_TCP;
169 eMBState = STATE_DISABLED;
170
171 // initialize the OS resource for modbus master.
172 vMBMasterOsResInit();
173 if( xMBMasterPortTimersInit( MB_MASTER_TIMEOUT_MS_RESPOND * MB_TIMER_TICS_PER_MS ) != TRUE )
174 {
175 eStatus = MB_EPORTERR;
176 }
177
178 }
179 return eStatus;
180 }
181 #endif
182
183 eMBErrorCode
eMBMasterSerialInit(eMBMode eMode,UCHAR ucPort,ULONG ulBaudRate,eMBParity eParity)184 eMBMasterSerialInit( eMBMode eMode, UCHAR ucPort, ULONG ulBaudRate, eMBParity eParity )
185 {
186 eMBErrorCode eStatus = MB_ENOERR;
187
188 switch (eMode)
189 {
190 #if MB_MASTER_RTU_ENABLED > 0
191 case MB_RTU:
192 pvMBMasterFrameStartCur = eMBMasterRTUStart;
193 pvMBMasterFrameStopCur = eMBMasterRTUStop;
194 peMBMasterFrameSendCur = eMBMasterRTUSend;
195 peMBMasterFrameReceiveCur = eMBMasterRTUReceive;
196 pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterPortClose : NULL;
197 pxMBMasterFrameCBByteReceived = xMBMasterRTUReceiveFSM;
198 pxMBMasterFrameCBTransmitterEmpty = xMBMasterRTUTransmitFSM;
199 pxMBMasterPortCBTimerExpired = xMBMasterRTUTimerExpired;
200 eMBMasterCurrentMode = MB_ASCII;
201
202 eStatus = eMBMasterRTUInit(ucPort, ulBaudRate, eParity);
203 break;
204 #endif
205 #if MB_MASTER_ASCII_ENABLED > 0
206 case MB_ASCII:
207 pvMBMasterFrameStartCur = eMBMasterASCIIStart;
208 pvMBMasterFrameStopCur = eMBMasterASCIIStop;
209 peMBMasterFrameSendCur = eMBMasterASCIISend;
210 peMBMasterFrameReceiveCur = eMBMasterASCIIReceive;
211 pvMBMasterFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBMasterPortClose : NULL;
212 pxMBMasterFrameCBByteReceived = xMBMasterASCIIReceiveFSM;
213 pxMBMasterFrameCBTransmitterEmpty = xMBMasterASCIITransmitFSM;
214 pxMBMasterPortCBTimerExpired = xMBMasterASCIITimerT1SExpired;
215 eMBMasterCurrentMode = MB_RTU;
216
217 eStatus = eMBMasterASCIIInit(ucPort, ulBaudRate, eParity );
218 break;
219 #endif
220 default:
221 eStatus = MB_EINVAL;
222 break;
223 }
224
225 if (eStatus == MB_ENOERR)
226 {
227 if (!xMBMasterPortEventInit())
228 {
229 /* port dependent event module initalization failed. */
230 eStatus = MB_EPORTERR;
231 }
232 else
233 {
234 eMBState = STATE_DISABLED;
235 }
236 /* initialize the OS resource for modbus master. */
237 vMBMasterOsResInit();
238 }
239 return eStatus;
240 }
241
242 eMBErrorCode
eMBMasterClose(void)243 eMBMasterClose( void )
244 {
245 eMBErrorCode eStatus = MB_ENOERR;
246
247 if( eMBState == STATE_DISABLED )
248 {
249 if( pvMBMasterFrameCloseCur != NULL )
250 {
251 pvMBMasterFrameCloseCur( );
252 }
253 }
254 else
255 {
256 eStatus = MB_EILLSTATE;
257 }
258 return eStatus;
259 }
260
261 eMBErrorCode
eMBMasterEnable(void)262 eMBMasterEnable( void )
263 {
264 eMBErrorCode eStatus = MB_ENOERR;
265
266 if( eMBState == STATE_DISABLED )
267 {
268 /* Activate the protocol stack. */
269 pvMBMasterFrameStartCur( );
270 /* Release the resource, because it created in busy state */
271 //vMBMasterRunResRelease( );
272 eMBState = STATE_ENABLED;
273 }
274 else
275 {
276 eStatus = MB_EILLSTATE;
277 }
278 return eStatus;
279 }
280
281 eMBErrorCode
eMBMasterDisable(void)282 eMBMasterDisable( void )
283 {
284 eMBErrorCode eStatus;
285
286 if( eMBState == STATE_ENABLED )
287 {
288 pvMBMasterFrameStopCur( );
289 eMBState = STATE_DISABLED;
290 eStatus = MB_ENOERR;
291 }
292 else if( eMBState == STATE_DISABLED )
293 {
294 eStatus = MB_ENOERR;
295 }
296 else
297 {
298 eStatus = MB_EILLSTATE;
299 }
300 return eStatus;
301 }
302
303 eMBErrorCode
eMBMasterPoll(void)304 eMBMasterPoll( void )
305 {
306 static UCHAR *ucMBFrame = NULL;
307 static UCHAR ucRcvAddress;
308 static UCHAR ucFunctionCode;
309 static USHORT usLength;
310 static eMBException eException;
311 int i;
312 int j;
313 eMBErrorCode eStatus = MB_ENOERR;
314 eMBMasterEventType eEvent;
315 eMBMasterErrorEventType errorType;
316
317 /* Check if the protocol stack is ready. */
318 if( eMBState != STATE_ENABLED )
319 {
320 return MB_EILLSTATE;
321 }
322
323 /* Check if there is a event available. If not return control to caller.
324 * Otherwise we will handle the event. */
325 if ( xMBMasterPortEventGet( &eEvent ) == TRUE )
326 {
327 while( eEvent ) {
328 // In some cases it is possible that more than one event set
329 // together (even from one subset mask) than process them consistently
330 if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_READY ) ) {
331 ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_READY", __func__);
332 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_READY );
333 } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
334 ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_FRAME_TRANSMIT", __func__);
335 /* Master is busy now. */
336 vMBMasterGetPDUSndBuf( &ucMBFrame );
337 ESP_LOG_BUFFER_HEX_LEVEL("POLL transmit buffer", (void*)ucMBFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
338 eStatus = peMBMasterFrameSendCur( ucMBMasterGetDestAddress(), ucMBFrame, usMBMasterGetPDUSndLength() );
339 if (eStatus != MB_ENOERR)
340 {
341 ESP_LOGE( MB_PORT_TAG, "%s:Frame send error. %d", __func__, eStatus );
342 }
343 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT );
344 } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_SENT ) ) {
345 ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_FRAME_SENT", __func__ );
346 ESP_LOG_BUFFER_HEX_LEVEL("POLL sent buffer", (void*)ucMBFrame, usMBMasterGetPDUSndLength(), ESP_LOG_DEBUG);
347 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_SENT );
348 } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED ) ) {
349 eStatus = peMBMasterFrameReceiveCur( &ucRcvAddress, &ucMBFrame, &usLength);
350
351 // Check if the frame is for us. If not ,send an error process event.
352 if ( ( eStatus == MB_ENOERR ) && ( ( ucRcvAddress == ucMBMasterGetDestAddress() )
353 || ( ucRcvAddress == MB_TCP_PSEUDO_ADDRESS ) ) )
354 {
355 ( void ) xMBMasterPortEventPost( EV_MASTER_EXECUTE );
356 ESP_LOGD(MB_PORT_TAG, "%s: Packet data received successfully (%u).", __func__, eStatus);
357 ESP_LOG_BUFFER_HEX_LEVEL("POLL receive buffer", (void*)ucMBFrame, (uint16_t)usLength, ESP_LOG_DEBUG);
358 }
359 else
360 {
361 vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
362 ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
363 ESP_LOGD( MB_PORT_TAG, "%s: Packet data receive failed (addr=%u)(%u).",
364 __func__, ucRcvAddress, eStatus);
365 }
366 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_FRAME_RECEIVED );
367 } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_EXECUTE ) ) {
368 if ( !ucMBFrame )
369 {
370 return MB_EILLSTATE;
371 }
372 ESP_LOGD(MB_PORT_TAG, "%s:EV_MASTER_EXECUTE", __func__);
373 ucFunctionCode = ucMBFrame[MB_PDU_FUNC_OFF];
374 eException = MB_EX_ILLEGAL_FUNCTION;
375 /* If receive frame has exception. The receive function code highest bit is 1.*/
376 if (ucFunctionCode & MB_FUNC_ERROR)
377 {
378 eException = (eMBException)ucMBFrame[MB_PDU_DATA_OFF];
379 } else {
380 for ( i = 0; i < MB_FUNC_HANDLERS_MAX; i++ )
381 {
382 /* No more function handlers registered. Abort. */
383 if (xMasterFuncHandlers[i].ucFunctionCode == 0)
384 {
385 break;
386 }
387 if (xMasterFuncHandlers[i].ucFunctionCode == ucFunctionCode)
388 {
389 vMBMasterSetCBRunInMasterMode(TRUE);
390 /* If master request is broadcast,
391 * the master need execute function for all slave.
392 */
393 if ( xMBMasterRequestIsBroadcast() )
394 {
395 usLength = usMBMasterGetPDUSndLength();
396 for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++)
397 {
398 vMBMasterSetDestAddress(j);
399 eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
400 }
401 }
402 else
403 {
404 eException = xMasterFuncHandlers[i].pxHandler( ucMBFrame, &usLength );
405 }
406 vMBMasterSetCBRunInMasterMode( FALSE );
407 break;
408 }
409 }
410 }
411 /* If master has exception, will send error process event. Otherwise the master is idle.*/
412 if ( eException != MB_EX_NONE )
413 {
414 vMBMasterSetErrorType( EV_ERROR_EXECUTE_FUNCTION );
415 ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
416 }
417 else
418 {
419 if ( eMBMasterGetErrorType( ) == EV_ERROR_INIT ) {
420 vMBMasterSetErrorType(EV_ERROR_OK);
421 ESP_LOGD( MB_PORT_TAG, "%s: set event EV_ERROR_OK", __func__ );
422 ( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
423 }
424 }
425 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
426 } else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_ERROR_PROCESS ) ) {
427 ESP_LOGD( MB_PORT_TAG, "%s:EV_MASTER_ERROR_PROCESS", __func__ );
428 /* Execute specified error process callback function. */
429 errorType = eMBMasterGetErrorType( );
430 vMBMasterGetPDUSndBuf( &ucMBFrame );
431 switch ( errorType )
432 {
433 case EV_ERROR_RESPOND_TIMEOUT:
434 vMBMasterErrorCBRespondTimeout( ucMBMasterGetDestAddress( ),
435 ucMBFrame, usMBMasterGetPDUSndLength( ) );
436 break;
437 case EV_ERROR_RECEIVE_DATA:
438 vMBMasterErrorCBReceiveData( ucMBMasterGetDestAddress( ),
439 ucMBFrame, usMBMasterGetPDUSndLength( ) );
440 break;
441 case EV_ERROR_EXECUTE_FUNCTION:
442 vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
443 ucMBFrame, usMBMasterGetPDUSndLength( ) );
444 break;
445 case EV_ERROR_OK:
446 vMBMasterCBRequestSuccess( );
447 break;
448 default:
449 ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %d.", __func__, errorType);
450 break;
451 }
452 vMBMasterSetErrorType( EV_ERROR_INIT );
453 MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_ERROR_PROCESS );
454 vMBMasterRunResRelease( );
455 }
456 }
457 } else {
458 // Something went wrong and task unblocked but there are no any correct events set
459 ESP_LOGE( MB_PORT_TAG, "%s: Unexpected event triggered 0x%02x.", __func__, eEvent );
460 eStatus = MB_EILLSTATE;
461 }
462 return eStatus;
463 }
464
465 // Get whether the Modbus Master is run in master mode.
xMBMasterGetCBRunInMasterMode(void)466 BOOL xMBMasterGetCBRunInMasterMode( void )
467 {
468 return xMBRunInMasterMode;
469 }
470
471 // Set whether the Modbus Master is run in master mode.
vMBMasterSetCBRunInMasterMode(BOOL IsMasterMode)472 void vMBMasterSetCBRunInMasterMode( BOOL IsMasterMode )
473 {
474 xMBRunInMasterMode = IsMasterMode;
475 }
476
477 // Get Modbus Master send destination address.
ucMBMasterGetDestAddress(void)478 UCHAR ucMBMasterGetDestAddress( void )
479 {
480 return ucMBMasterDestAddress;
481 }
482
483 // Set Modbus Master send destination address.
vMBMasterSetDestAddress(UCHAR Address)484 void vMBMasterSetDestAddress( UCHAR Address )
485 {
486 ucMBMasterDestAddress = Address;
487 }
488
489 // Get Modbus Master current error event type.
eMBMasterGetErrorType(void)490 eMBMasterErrorEventType inline eMBMasterGetErrorType( void )
491 {
492 return eMBMasterCurErrorType;
493 }
494
495 // Set Modbus Master current error event type.
vMBMasterSetErrorType(eMBMasterErrorEventType errorType)496 void IRAM_ATTR vMBMasterSetErrorType( eMBMasterErrorEventType errorType )
497 {
498 eMBMasterCurErrorType = errorType;
499 }
500
501 /* Get Modbus Master send PDU's buffer address pointer.*/
vMBMasterGetPDUSndBuf(UCHAR ** pucFrame)502 void vMBMasterGetPDUSndBuf( UCHAR ** pucFrame )
503 {
504 *pucFrame = ( UCHAR * ) &ucMasterSndBuf[MB_SER_PDU_PDU_OFF];
505 }
506
507 /* Set Modbus Master send PDU's buffer length.*/
vMBMasterSetPDUSndLength(USHORT SendPDULength)508 void vMBMasterSetPDUSndLength( USHORT SendPDULength )
509 {
510 usMasterSendPDULength = SendPDULength;
511 }
512
513 /* Get Modbus Master send PDU's buffer length.*/
usMBMasterGetPDUSndLength(void)514 USHORT usMBMasterGetPDUSndLength( void )
515 {
516 return usMasterSendPDULength;
517 }
518
519 /* Set Modbus Master current timer mode.*/
vMBMasterSetCurTimerMode(eMBMasterTimerMode eMBTimerMode)520 void vMBMasterSetCurTimerMode( eMBMasterTimerMode eMBTimerMode )
521 {
522 eMasterCurTimerMode = eMBTimerMode;
523 }
524
525 /* Get Modbus Master current timer mode.*/
xMBMasterGetCurTimerMode(void)526 eMBMasterTimerMode MB_PORT_ISR_ATTR xMBMasterGetCurTimerMode( void )
527 {
528 return eMasterCurTimerMode;
529 }
530
531 /* The master request is broadcast? */
xMBMasterRequestIsBroadcast(void)532 BOOL MB_PORT_ISR_ATTR xMBMasterRequestIsBroadcast( void )
533 {
534 return xFrameIsBroadcast;
535 }
536
537 /* The master request is broadcast? */
vMBMasterRequestSetType(BOOL xIsBroadcast)538 void vMBMasterRequestSetType( BOOL xIsBroadcast ){
539 xFrameIsBroadcast = xIsBroadcast;
540 }
541
542 #endif // MB_MASTER_RTU_ENABLED || MB_MASTER_ASCII_ENABLED || MB_MASTER_TCP_ENABLED
543