From 36269097862c81753e4c9ddd012c04ce2ca17360 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 4 Mar 2019 16:42:29 +0200 Subject: [PATCH] Important Update: - Added SendEnable (vir RTS pin) for TTL/RS485 converter - Bug fix: Check for Handle->InTimeout before force output --- SelectableCore.cpp | 32 +++++++++++++++++++++++++++++--- SelectableCore.h | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 5f36109..f7dd274 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -128,6 +128,8 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) FlowCtrl = HW_FLOWCTRL; else if (!strcasecmp( FlowCtrlText, "software" )) FlowCtrl = SW_FLOWCTRL; + else if (!strcasecmp( FlowCtrlText, "rs485" )) + FlowCtrl = RS485_FLOWCTRL; else FlowCtrl = NO_FLOWCTRL; @@ -652,6 +654,12 @@ THandle * CSelectableCore::OpenSerialPort( THandle * Handle ) return NULL; } + // Set Send Enable (via RTS) for RS485 + if ((Handle->Type == ctSerial) && (Handle->FlowCtrl == RS485_FLOWCTRL)) { + int sercmd = TIOCM_RTS; + ioctl( Handle->FD, TIOCMBIS, &sercmd ); + } + // Log Event if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Serial Port opened [%s]", ProcessName, Name, Handle->Name, Handle->Path ); @@ -1748,6 +1756,12 @@ bool CSelectableCore::Close( THandle * Handle, bool QuickReopen ) } } + // Set Send Enable (via RTS) for RS485 + if ((Handle->Type == ctSerial) && (Handle->FlowCtrl == RS485_FLOWCTRL)) { + int sercmd = TIOCM_RTS; + ioctl( Handle->FD, TIOCMBIC, &sercmd ); + } + // Close Handle if (Handle->Type == ctUDPremote) { Fail = false; @@ -2099,10 +2113,22 @@ bool CSelectableCore::Write( THandle * Handle ) { // Write directly to handle / socket errno = 0; - if ((Handle->Type == ctUDPclient)|| (Handle->Type == ctUDPremote)) { + if ((Handle->Type == ctUDPclient) || (Handle->Type == ctUDPremote)) { Len = Handle->OutBuffer->Peek( &Data ); BytesWritten = WriteToUDP( Handle, Data, Len, true ); } + else if ((Handle->Type == ctSerial) && (Handle->FlowCtrl == RS485_FLOWCTRL)) { + // Set Send Enable (via RTS pin) when sending data + int sercmd = TIOCM_RTS; + ioctl( Handle->FD, TIOCMBIC, &sercmd ); + usleep( 1000 ); + + BytesWritten = Handle->OutBuffer->WriteToFD( Handle->FD ); + + tcdrain( Handle->FD ); + usleep( 1000 ); + ioctl( Handle->FD, TIOCMBIS, &sercmd ); + } else { BytesWritten = Handle->OutBuffer->WriteToFD( Handle->FD ); } @@ -2163,7 +2189,7 @@ bool CSelectableCore::ProcessInputBuffer( THandle * Handle, bool Force ) } // Check if forced processed - if (Force || !Handle->InMarkerLen) + if (Force || (!Handle->InMarkerLen && !Handle->InTimeout)) { // Show Packet Len = Handle->InBuffer->Peek( &Data ); @@ -2180,7 +2206,7 @@ bool CSelectableCore::ProcessInputBuffer( THandle * Handle, bool Force ) // Clear processed bytes from buffer Handle->InBuffer->Clear( Len ); } - else + else if (Handle->InMarkerLen) { // Search for end of packet marker while (Handle->InBuffer->FindStr( Handle->InMarker, Handle->InMarkerLen, Pos )) diff --git a/SelectableCore.h b/SelectableCore.h index 50ee239..cc97344 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -37,6 +37,7 @@ const char ConnectStateName[][15] = { "None", "OpenRequest", "WaitingToOpen", "O #define NO_FLOWCTRL 0 #define HW_FLOWCTRL 1 #define SW_FLOWCTRL 2 +#define RS485_FLOWCTRL 3 //---------------------------------------------------------------------------