123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- /*
- * FreeModbus Libary: RT-Thread Port
- * Copyright (C) 2013 Armink <armink.ztl@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * File: $Id: portserial_m.c,v 1.60 2013/08/13 15:07:05 Armink add Master Functions $
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/select.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <unistd.h>
- #include "port.h"
- /* ----------------------- Modbus includes ----------------------------------*/
- #include "mb.h"
- #include "mbport.h"
- #include "mbconfig.h"
- #include "mbctx.h"
- #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
- /* ----------------------- Static variables ---------------------------------*/
- /* ----------------------- static functions ---------------------------------*/
- void prvvMBMasterUARTTxReadyISR(void);
- void prvvMBMasterUARTRxISR(void);
- /* ----------------------- Start implementation -----------------------------*/
- BOOL xMBMasterPortSerialInit(fmodbus_t* ctx)
- {
- CHAR szDevice[32];
- BOOL bStatus = TRUE;
- struct termios xNewTIO;
- speed_t xNewSpeed;
- snprintf( szDevice, 32, "%s", ctx->szPort );
- if( ( ctx->iSerialFd = open( szDevice, O_RDWR | O_NOCTTY ) ) < 0 ){
- vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't open serial port %s: %s\n", szDevice, strerror( errno ) );
- }else if( tcgetattr( ctx->iSerialFd, &(ctx->xOldTIO) ) != 0 ){
- vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't get settings from port %s: %s\n", szDevice, strerror( errno ) );
- }else{
- vMBPortLog( MB_LOG_INFO, "SER-INIT", "init ok %s\n", szDevice );
- bzero( &xNewTIO, sizeof( struct termios ) );
- xNewTIO.c_iflag |= IGNBRK | INPCK;
- xNewTIO.c_cflag |= CREAD | CLOCAL;
- switch ( ctx->eParity )
- {
- case MB_PAR_NONE:
- break;
- case MB_PAR_EVEN:
- xNewTIO.c_cflag |= PARENB;
- break;
- case MB_PAR_ODD:
- xNewTIO.c_cflag |= PARENB | PARODD;
- break;
- default:
- bStatus = FALSE;
- }
- switch ( ctx->ucDataBits )
- {
- case 8:
- xNewTIO.c_cflag |= CS8;
- break;
- case 7:
- xNewTIO.c_cflag |= CS7;
- break;
- default:
- bStatus = FALSE;
- }
- switch ( ctx->ulBaudRate )
- {
- case 4800:
- xNewSpeed = B4800;
- break;
- case 9600:
- xNewSpeed = B9600;
- break;
- case 19200:
- xNewSpeed = B19200;
- break;
- case 38400:
- xNewSpeed = B38400;
- break;
- case 57600:
- xNewSpeed = B57600;
- break;
- case 115200:
- xNewSpeed = B115200;
- break;
- default:
- bStatus = FALSE;
- }
- if( bStatus )
- {
- if( cfsetispeed( &xNewTIO, xNewSpeed ) != 0 )
- {
- vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set baud rate %ld for port %s: %s\n",
- ctx->ulBaudRate, strerror( errno ) );
- }
- else if( cfsetospeed( &xNewTIO, xNewSpeed ) != 0 )
- {
- vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set baud rate %ld for port %s: %s\n",
- ctx->ulBaudRate, szDevice, strerror( errno ) );
- }
- else if( tcsetattr( ctx->iSerialFd, TCSANOW, &xNewTIO ) != 0 )
- {
- vMBPortLog( MB_LOG_ERROR, "SER-INIT", "Can't set settings for port %s: %s\n",
- szDevice, strerror( errno ) );
- }
- else
- {
- vMBPortSerialEnable(ctx, FALSE, FALSE );
- bStatus = TRUE;
- }
- }
- }
- return bStatus;
- }
- void vMBMasterPortSerialEnable(fmodbus_t* ctx, BOOL bEnableRx, BOOL bEnableTx )
- {
- /* it is not allowed that both receiver and transmitter are enabled. */
- assert( !bEnableRx || !bEnableTx );
- if( bEnableRx )
- {
- ( void )tcflush( ctx->iSerialFd, TCIFLUSH );
- ctx->uiRxBufferPos = 0;
- ctx->bRxEnabled = TRUE;
- }
- else
- {
- ctx->bRxEnabled = FALSE;
- }
- if( bEnableTx )
- {
- ctx->bTxEnabled = TRUE;
- ctx->uiTxBufferPos = 0;
- }
- else
- {
- ctx->bTxEnabled = FALSE;
- }
- }
- void vMBMasterPortClose( fmodbus_t* ctx )
- {
- if( ctx->iSerialFd != -1 )
- {
- ( void )tcsetattr( ctx->iSerialFd, TCSANOW, &ctx->xOldTIO );
- ( void )close( ctx->iSerialFd );
- ctx->iSerialFd = -1;
- }
- }
- BOOL xMBMasterPortSerialPutByte(fmodbus_t* ctx, CHAR ucByte )
- {
- assert( ctx->uiTxBufferPos < BUF_SIZE );
- ctx->ucBuffer[ctx->uiTxBufferPos] = ucByte;
- ctx->uiTxBufferPos++;
- return TRUE;
- }
- BOOL xMBMasterPortSerialGetByte(fmodbus_t* ctx, CHAR * pucByte )
- {
- assert( ctx->uiRxBufferPos < BUF_SIZE );
- *pucByte = ctx->ucBuffer[ctx->uiRxBufferPos];
- ctx->uiRxBufferPos++;
- return TRUE;
- }
- /*
- * Create an interrupt handler for the transmit buffer empty interrupt
- * (or an equivalent) for your target processor. This function should then
- * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
- * a new character can be sent. The protocol stack will then call
- * xMBPortSerialPutByte( ) to send the character.
- */
- void prvvMBMasterUARTTxReadyISR(void)
- {
- pxMBMasterFrameCBTransmitterEmpty();
- }
- /*
- * Create an interrupt handler for the receive interrupt for your target
- * processor. This function should then call pxMBFrameCBByteReceived( ). The
- * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
- * character.
- */
- void prvvMBMasterUARTRxISR(void)
- {
- pxMBMasterFrameCBByteReceived();
- }
- #endif
|