@ -22,6 +22,7 @@
@@ -22,6 +22,7 @@
*/
/* ----------------------- Standard includes --------------------------------*/
# include <nuttx/config.h>
# include <stdio.h>
# include <stdlib.h>
@ -31,17 +32,22 @@
@@ -31,17 +32,22 @@
# include <sys/stat.h>
# include <sys/select.h>
# include <fcntl.h>
# include <termios.h>
# include <unistd.h>
# include <assert.h>
# ifdef CONFIG_MB_TERMIOS
# include <termios.h>
# endif
# include "port.h"
/* ----------------------- Modbus includes ----------------------------------*/
# include <apps/modbus/mb.h>
# include <apps/modbus/mbport.h>
/* ----------------------- Defines -----------------------------------------*/
# ifdef CONFIG_MB_ASCII_ENABLED
# define BUF_SIZE 513 /* must hold a complete ASCII frame. */
# else
@ -49,6 +55,7 @@
@@ -49,6 +55,7 @@
# endif
/* ----------------------- Static variables ---------------------------------*/
static int iSerialFd = - 1 ;
static bool bRxEnabled ;
static bool bTxEnabled ;
@ -58,22 +65,28 @@ static uint8_t ucBuffer[BUF_SIZE];
@@ -58,22 +65,28 @@ static uint8_t ucBuffer[BUF_SIZE];
static int uiRxBufferPos ;
static int uiTxBufferPos ;
# ifdef CONFIG_MB_TERMIOS
static struct termios xOldTIO ;
# endif
/* ----------------------- Function prototypes ------------------------------*/
static bool prvbMBPortSerialRead ( uint8_t * pucBuffer , uint16_t usNBytes , uint16_t * usNBytesRead ) ;
static bool prvbMBPortSerialWrite ( uint8_t * pucBuffer , uint16_t usNBytes ) ;
/* ----------------------- Begin implementation -----------------------------*/
void
vMBPortSerialEnable ( bool bEnableRx , bool bEnableTx )
void vMBPortSerialEnable ( bool bEnableRx , bool bEnableTx )
{
/* it is not allowed that both receiver and transmitter are enabled. */
ASSERT ( ! bEnableRx | | ! bEnableTx ) ;
if ( bEnableRx )
{
# ifdef CONFIG_MB_TERMIOS
( void ) tcflush ( iSerialFd , TCIFLUSH ) ;
# endif
uiRxBufferPos = 0 ;
bRxEnabled = true ;
}
@ -81,6 +94,7 @@ vMBPortSerialEnable( bool bEnableRx, bool bEnableTx )
@@ -81,6 +94,7 @@ vMBPortSerialEnable( bool bEnableRx, bool bEnableTx )
{
bRxEnabled = false ;
}
if ( bEnableTx )
{
bTxEnabled = true ;
@ -92,26 +106,30 @@ vMBPortSerialEnable( bool bEnableRx, bool bEnableTx )
@@ -92,26 +106,30 @@ vMBPortSerialEnable( bool bEnableRx, bool bEnableTx )
}
}
bool
xMBPortSerialInit ( uint8_t ucPort , uint32_t ulBaudRate , uint8_t ucDataBits , eMBParity eParity )
bool xMBPortSerialInit ( uint8_t ucPort , uint32_t ulBaudRate ,
uint8_t ucDataBits , eMBParity eParity )
{
char szDevice [ 16 ] ;
bool bStatus = true ;
# ifdef CONFIG_MB_TERMIOS
struct termios xNewTIO ;
speed_t xNewSpeed ;
# endif
snprintf ( szDevice , 16 , " /dev/ttyS%d " , ucPort ) ;
if ( ( 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 ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't open serial port %s: %d \n " ,
szDevice , errno ) ;
}
# ifdef CONFIG_MB_TERMIOS
else if ( tcgetattr ( iSerialFd , & xOldTIO ) ! = 0 )
{
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't get settings from port %s: %s \n " , szDevice ,
strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't get settings from port %s: %d \n " ,
szDevice , errno ) ;
}
else
{
@ -132,6 +150,7 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
@@ -132,6 +150,7 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
default :
bStatus = false ;
}
switch ( ucDataBits )
{
case 8 :
@ -143,6 +162,7 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
@@ -143,6 +162,7 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
default :
bStatus = false ;
}
switch ( ulBaudRate )
{
case 9600 :
@ -163,22 +183,23 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
@@ -163,22 +183,23 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
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 " ,
ulBaudRate , strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't set baud rate %ld for port %s: %d \n " ,
ulBaudRate , errno ) ;
}
else if ( cfsetospeed ( & xNewTIO , xNewSpeed ) ! = 0 )
{
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't set baud rate %ld for port %s: %s \n " ,
ulBaudRate , szDevice , strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't set baud rate %ld for port %s: %d \n " ,
ulBaudRate , szDevice , errno ) ;
}
else if ( tcsetattr ( iSerialFd , TCSANOW , & xNewTIO ) ! = 0 )
{
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't set settings for port %s: %s \n " ,
szDevice , strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-INIT " , " Can't set settings for port %s: %d \n " ,
szDevice , errno ) ;
}
else
{
@ -187,11 +208,12 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
@@ -187,11 +208,12 @@ xMBPortSerialInit( uint8_t ucPort, uint32_t ulBaudRate, uint8_t ucDataBits, eMBP
}
}
}
# endif
return bStatus ;
}
bool
xMBPortSerialSetTimeout ( uint32_t ulNewTimeoutMs )
bool xMBPortSerialSetTimeout ( uint32_t ulNewTimeoutMs )
{
if ( ulNewTimeoutMs > 0 )
{
@ -201,22 +223,23 @@ xMBPortSerialSetTimeout( uint32_t ulNewTimeoutMs )
@@ -201,22 +223,23 @@ xMBPortSerialSetTimeout( uint32_t ulNewTimeoutMs )
{
ulTimeoutMs = 1 ;
}
return true ;
}
void
vMBPortClose ( void )
void vMBPortClose ( void )
{
if ( iSerialFd ! = - 1 )
{
# ifdef CONFIG_MB_TERMIOS
( void ) tcsetattr ( iSerialFd , TCSANOW , & xOldTIO ) ;
# endif
( void ) close ( iSerialFd ) ;
iSerialFd = - 1 ;
}
}
bool
prvbMBPortSerialRead ( uint8_t * pucBuffer , uint16_t usNBytes , uint16_t * usNBytesRead )
bool prvbMBPortSerialRead ( uint8_t * pucBuffer , uint16_t usNBytes , uint16_t * usNBytesRead )
{
bool bResult = true ;
ssize_t res ;
@ -229,7 +252,9 @@ prvbMBPortSerialRead( uint8_t * pucBuffer, uint16_t usNBytes, uint16_t * usNByte
@@ -229,7 +252,9 @@ prvbMBPortSerialRead( uint8_t * pucBuffer, uint16_t usNBytes, uint16_t * usNByte
FD_SET ( iSerialFd , & rfds ) ;
/* Wait until character received or timeout. Recover in case of an
* interrupted read system call . */
* interrupted read system call .
*/
do
{
if ( select ( iSerialFd + 1 , & rfds , NULL , NULL , & tv ) = = - 1 )
@ -257,12 +282,12 @@ prvbMBPortSerialRead( uint8_t * pucBuffer, uint16_t usNBytes, uint16_t * usNByte
@@ -257,12 +282,12 @@ prvbMBPortSerialRead( uint8_t * pucBuffer, uint16_t usNBytes, uint16_t * usNByte
break ;
}
}
while ( bResult = = true ) ;
return bResult ;
}
bool
prvbMBPortSerialWrite ( uint8_t * pucBuffer , uint16_t usNBytes )
bool prvbMBPortSerialWrite ( uint8_t * pucBuffer , uint16_t usNBytes )
{
ssize_t res ;
size_t left = ( size_t ) usNBytes ;
@ -276,12 +301,15 @@ prvbMBPortSerialWrite( uint8_t * pucBuffer, uint16_t usNBytes )
@@ -276,12 +301,15 @@ prvbMBPortSerialWrite( uint8_t * pucBuffer, uint16_t usNBytes )
{
break ;
}
/* call write again because of interrupted system call. */
continue ;
}
done + = res ;
left - = res ;
}
return left = = 0 ? true : false ;
}
@ -313,8 +341,8 @@ xMBPortSerialPoll( )
@@ -313,8 +341,8 @@ xMBPortSerialPoll( )
}
else
{
vMBPortLog ( MB_LOG_ERROR , " SER-POLL " , " read failed on serial device: %s \n " ,
strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-POLL " , " read failed on serial device: %d \n " ,
errno ) ;
bStatus = false ;
}
}
@ -327,8 +355,8 @@ xMBPortSerialPoll( )
@@ -327,8 +355,8 @@ xMBPortSerialPoll( )
}
if ( ! prvbMBPortSerialWrite ( & ucBuffer [ 0 ] , uiTxBufferPos ) )
{
vMBPortLog ( MB_LOG_ERROR , " SER-POLL " , " write failed on serial device: %s \n " ,
strerror ( errno ) ) ;
vMBPortLog ( MB_LOG_ERROR , " SER-POLL " , " write failed on serial device: %d \n " ,
errno ) ;
bStatus = false ;
}
}