/* * PortCore.cpp * * Created on: 13 May 2016 * Author: wentzelc */ // redA Libraries #include "PortCore.h" #include "TimingCore.h" #include "LogCore.h" // Standard C/C++ Libraries #include #include #include #include #include #include #include //--------------------------------------------------------------------------- CPortCore::CPortCore( const char * PortName, const int PortInBufLen ) : InBufLen( PortInBufLen ) { // Port File Handle Handle = -1; // Copy Port name if (PortName) { Name = (char*)malloc( strlen( PortName)+ 1); strcpy( Name, PortName ); } else { Name = NULL; } // In buffer InBuffer = (char *)malloc( InBufLen ); InLen = 0; BytesRead = 0; // In buffer Timer InStart.tv_sec = 0; InStart.tv_usec = 0; InTimeout = 100; // millisecs } //--------------------------------------------------------------------------- CPortCore::~CPortCore() { // Destroy pointers if (Name) { free( Name ); } } //--------------------------------------------------------------------------- bool CPortCore::Open() { // Check if valid port name if (!Name) { return false; } // Check if port exits if (access( Name, F_OK ) != 0) { printf( "Port: %s -> Could not find port\n", Name ); return false; } // Open Port Handle = open( Name, O_RDWR ); if (Handle == -1) { printf( "Port: %s -> Could not open port\n", Name ); return false; } // Confirm open printf( "Port: %s -> Port opened\n", Name ); return true; } //--------------------------------------------------------------------------- bool CPortCore::Close() { int result; // Check if valid port if (Handle == -1) { return true; } // Close port result = close( Handle ); if (result) { printf( "Port: %s -> Port not closed properly\n", Name ); return false; } // Port closed printf( "Port: %s -> Port closed\n", Name ); return true; } //--------------------------------------------------------------------------- // Set serial port configuration parameters bool CPortCore::Config( int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait ) { struct termios newtio; int flags = 0; speed_t _baud = 0; int mcs = 0; // Flush Data from port tcflush( Handle, TCIFLUSH ); // Set Open flags flags = fcntl( Handle, F_GETFL, 0 ); fcntl( Handle, F_SETFL, flags & ~O_NDELAY ); // Read options if (tcgetattr( Handle, &newtio ) != 0) return false; // Process the baud rate switch (Baud) { case 921600: _baud = B921600; break; case 576000: _baud = B576000; break; case 460800: _baud = B460800; break; case 230400: _baud = B230400; break; //case 128000: _baud = B128000; break; case 115200: _baud = B115200; break; //case 76800: _baud = B76800; break; case 57600: _baud = B57600; break; case 38400: _baud = B38400; break; //case 28800: _baud = B28800; break; case 19200: _baud = B19200; break; //case 14400: _baud = B14400; break; case 9600: _baud = B9600; break; case 4800: _baud = B4800; break; case 2400: _baud = B2400; break; case 1800: _baud = B1800; break; case 1200: _baud = B1200; break; case 600: _baud = B600; break; case 300: _baud = B300; break; case 200: _baud = B200; break; case 150: _baud = B150; break; case 134: _baud = B134; break; case 110: _baud = B110; break; case 75: _baud = B75; break; case 50: _baud = B50; break; default: _baud = B9600; break; } // Set Baud rate cfsetospeed( &newtio, (speed_t)_baud ); cfsetispeed( &newtio, (speed_t)_baud ); // Generate Mark/Space parity if ((DataBits == 7) && ((Parity == MARK_PARITY) || (Parity == SPACE_PARITY))) DataBits = 8; // Process the data bits newtio.c_cflag &= ~CSIZE; switch (DataBits) { case 5: newtio.c_cflag |= CS5; break; case 6: newtio.c_cflag |= CS6; break; case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; default: newtio.c_cflag |= CS8; break; } // Set other flags newtio.c_cflag |= CLOCAL | CREAD; // Process Parity newtio.c_cflag &= ~(PARENB | PARODD); if (Parity == EVEN_PARITY) newtio.c_cflag |= PARENB; else if (Parity == ODD_PARITY) newtio.c_cflag |= (PARENB | PARODD); // Flow Control (for now) newtio.c_cflag &= ~CRTSCTS; // Process Stop Bits if (StopBits == 2) newtio.c_cflag |= CSTOPB; else newtio.c_cflag &= ~CSTOPB; newtio.c_iflag = IGNBRK; // Software Flow Control if (FlowCtrl == SW_FLOWCTRL) newtio.c_iflag |= IXON | IXOFF; else newtio.c_iflag &= ~(IXON | IXOFF | IXANY); // Set RAW input & output newtio.c_lflag=0; newtio.c_oflag=0; // Set wait parameters newtio.c_cc[VTIME] = Wait; // Blocking: Allow at least a tenth of a second to wait for data newtio.c_cc[VMIN] = 0; // Non-blocking: Don't set min bytes to receive // Set Options (first time) //tcflush( Handle, TCIFLUSH); if (tcsetattr( Handle, TCSANOW, &newtio)!=0) return false; // Set Terminal options ioctl( Handle, TIOCMGET, &mcs); mcs |= TIOCM_RTS; ioctl( Handle, TIOCMSET, &mcs); // Get Options (again) if (tcgetattr( Handle, &newtio) != 0) return false; // Process Hardware Flow Control if (FlowCtrl == HW_FLOWCTRL) newtio.c_cflag |= CRTSCTS; else newtio.c_cflag &= ~CRTSCTS; // Set Options (second time) if (tcsetattr( Handle, TCSANOW, &newtio ) != 0) { printf( "Port: %s -> Could not configure port\n", Name ); return false; } // Port configured printf( "Port: %s -> Port configured\n", Name ); return true; } //--------------------------------------------------------------------------- bool CPortCore::Read() { // Handle read event BytesRead = read( Handle, &InBuffer[InLen], InBufLen-InLen ); if (BytesRead > 0) { // Process Reply InLen += BytesRead; // Reset timer SetStartTime( &InStart ); } return true; } //--------------------------------------------------------------------------- bool CPortCore::Maintain( int SocketHandle ) { // Misc long Duration = 0; int BytesWritten = 0; int StartWrite = 0; if (InLen > 0) { // Check duration since last PortIn Duration = TimePassed( InStart ); if (Duration > InTimeout) { // Handle buffer as packet InBuffer[ InLen ] = 0; ShowOutput( "Port In", OUT_NORMAL|OUT_HEX, InBuffer, InLen ); // Write output to Port BytesWritten = 0; StartWrite = 0; if (SocketHandle != -1) { while (StartWrite < InLen) { BytesWritten = write( SocketHandle, &InBuffer[StartWrite], InLen ); StartWrite += BytesWritten; } } // Reset buffer and timer InLen = 0; SetInterval( &InStart, 0 ); } } return true; } //---------------------------------------------------------------------------