OpenCores
URL https://opencores.org/ocsvn/bw_tiff_compression/bw_tiff_compression/trunk

Subversion Repositories bw_tiff_compression

[/] [bw_tiff_compression/] [trunk/] [client_application/] [src/] [Kernel/] [CSerialportDevice.cpp] - Rev 16

Compare with Previous | Blame | View Log

/*
 * @file     SerialportDevice.cpp
 * @date     May 14, 2012
 * @author   Aart Mulder
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef linux
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <unistd.h>
#include "CPathLib.h"      //For serial port enumeration
#else
#include <windows.h>
#include <Winerror.h>
#endif
 
#include <QDebug>
#include <QStringList>
#include <QProcess>
 
#include "CSerialportDevice.h"
#include "sysconf.h"
 
    /** @author Aart Mulder
     *  @version 1
     */
 
#define RX_BUF_SIZE				5000
 
CSerialportDevice::CSerialportDevice(int nLoopTime, QString sName) : CDevice(nLoopTime, sName)
{
#ifdef linux
	fd1 = -1;
#else
	m_fpSerialPort = INVALID_HANDLE_VALUE;
#endif
 
	this->ResetRxCnt();
}
 
CSerialportDevice::~CSerialportDevice()
{
	this->Disconnect();
}
 
bool CSerialportDevice::Send(unsigned char cData)
{
	int wr;
 
#ifdef SIM_SERIAL_LOOPBACK
		REFER(wr);
		OnDataReceived(cData);
#else
#ifdef linux
	wr = write(fd1, &cData, 1);
#else
	WriteFile(m_fpSerialPort, &cData, 1, (DWORD*)&wr, 0);
#endif
	if(wr != 1)
	{
		return false;
	}
#endif
	return true;
}
 
bool CSerialportDevice::Send(unsigned char *pData, unsigned int nSize)
{
	unsigned int wr;
 
#ifdef SIM_SERIAL_LOOPBACK
	REFER(wr);
	for(unsigned int i = 0; i < nSize; i++)
	{
		OnDataReceived(pData[i]);
	}
#else
#ifdef linux
	wr = write(fd1, pData, nSize);
#else
	WriteFile(m_fpSerialPort, pData, nSize, (DWORD*)&wr, 0);
#endif
	if(wr != nSize)
	{
		return false;
	}
#endif
 
	return true;
}
 
QList<QString> CSerialportDevice::GetPortNames()
{
	QList<QString> aPortNames;
 
#ifdef linux
    CPathLib::ReadDir("/dev", &aPortNames, "\\b(ttyS|ttyUSB|rfcomm|ttyACM)");
	aPortNames = QStringList(aPortNames).replaceInStrings("tty", "/dev/tty");
    aPortNames = QStringList(aPortNames).replaceInStrings("rfcomm", "/dev/rfcomm");
#else
    HKEY hKey;
    long lResult;
 
    if( (lResult = RegCreateKeyExA(
            HKEY_LOCAL_MACHINE, //hKey
            "HARDWARE\\DEVICEMAP\\SERIALCOMM",
            0,                  //Reserved
            NULL,               //lpClass
            0,                  //dwOptions
            KEY_READ,     //samDesired
            NULL,               //lpSecurityAttributes
            &hKey,              //phkResult
            NULL)) == ERROR_SUCCESS) //lpdwDisposition
    {
        char rval[256];
        DWORD rval_len = 256 ;
 
        char rdata[256];
        DWORD rdata_len = 256;
 
        DWORD rtype = REG_SZ ;
        int i = 0;
 
        while( RegEnumValueA(hKey, i, rval, &rval_len, NULL, &rtype,
        (unsigned char*)rdata, &rdata_len) != ERROR_NO_MORE_ITEMS)
        {
            qDebug() << rval << " : " << rdata;
            aPortNames.append(QString(rdata));
            i++;
            rval_len=256;
            rdata_len=256;
            memset(rval, '\0', rval_len);
            memset(rdata, '\0', rdata_len);
        }
        RegCloseKey (hKey);
    }
#endif
 
	return aPortNames;
}
 
bool CSerialportDevice::Connect(char *sName)
{
    return Connect(sName, 9600);
}
 
bool CSerialportDevice::Connect(char *sName, quint32 nBaudrate)
{
#ifdef linux
    QProcess oProcess;
 
#if 0
    if(QString(sName).contains("/dev/rfcomm0"))
    {
        oProcess.start("gksudo rfcomm release /dev/rfcomm0");
        oProcess.waitForFinished(20000);
        oProcess.start("gksudo rfcomm bind /dev/rfcomm0 00:07:80:4B:23:7A 1");
        oProcess.waitForFinished(20000);
    }
#endif
	fd1 = open(sName, O_RDWR | O_NOCTTY | O_NDELAY);
 
	if (fd1 == -1 )
	{
		qDebug() << "Could not connect to " << sName << "\n";
		return false;
	}
	else
	{
		fcntl(fd1, F_SETFL,0);
        configure_port(nBaudrate);
		qDebug() << "Successfully connected to " << sName << "\n";
		return true;
	}
#else
	DCB dcb;
	BOOL fSuccess;
    char aTmpCommPort[20];
    HANDLE fpSerialPort = INVALID_HANDLE_VALUE;
 
    strcpy(aTmpCommPort, "\\\\.\\");
    strcat(aTmpCommPort, sName);
    fpSerialPort = CreateFileA( aTmpCommPort,
			GENERIC_READ | GENERIC_WRITE,
			0,    // must be opened with exclusive-access
			NULL, // default security attributes
			OPEN_EXISTING, // must use OPEN_EXISTING
            0,//FILE_FLAG_NO_BUFFERING,    // not overlapped I/O
			NULL  // hTemplate must be NULL for comm devices
	);
 
    if (fpSerialPort == INVALID_HANDLE_VALUE)
	{
        qDebug() << "Could not connect to " << sName << "\n";
        // Handle the error.
 
		return false;
	}
 
    qDebug() << "Successfully connected to " << sName << "\n";
 
	/*
	 * Build on the current configuration, and skip setting the size
	 * of the input and output buffers with SetupComm.
	 */
	dcb.DCBlength = sizeof(DCB);
    fSuccess = GetCommState(fpSerialPort, &dcb);
 
	if (!fSuccess)
	{
        // Handle the error.
        return false;
	}
 
    switch(nBaudrate)
    {
    case 9600:
        dcb.BaudRate = CBR_9600;     // set the baud rate
        break;
    case 19200:
        dcb.BaudRate = CBR_19200;     // set the baud rate
        break;
    case 38400:
        dcb.BaudRate = CBR_38400;     // set the baud rate
        break;
    case 57600:
        dcb.BaudRate = CBR_57600;     // set the baud rate
        break;
    case 115200:
        dcb.BaudRate = CBR_115200;     // set the baud rate
        break;
#ifdef linux
    case 230400:
        dcb.BaudRate = CBR_230400;     // set the baud rate
        break;
#endif
    default:
        dcb.BaudRate = CBR_9600;     // set the baud rate
        break;
    }
 
	dcb.ByteSize = 8;             // data size, xmit, and rcv
    dcb.Parity = ODDPARITY;        // no parity bit
	dcb.StopBits = ONESTOPBIT;    // one stop bit
 
    fSuccess = SetCommState(fpSerialPort, &dcb);
 
	if (!fSuccess)
	{
	   // Handle the error.
	   return false;
	}
 
	 COMMTIMEOUTS CommTimeouts;
     if(!GetCommTimeouts (fpSerialPort, &CommTimeouts))
	 {
		 // Handle the error.
		 return false;
	 }
	 // Change the COMMTIMEOUTS structure settings.
     memset((void*)&CommTimeouts, 0, sizeof(CommTimeouts));
     CommTimeouts.ReadIntervalTimeout = 5;
     CommTimeouts.ReadTotalTimeoutMultiplier = 1;
     CommTimeouts.ReadTotalTimeoutConstant = 5;
     CommTimeouts.WriteTotalTimeoutMultiplier = 10;
     CommTimeouts.WriteTotalTimeoutConstant = 10;
 
	 // Set the timeout parameters for all read and write operations
	 // on the port.
     if (!SetCommTimeouts (fpSerialPort, &CommTimeouts))
	 {
		 // Could not set the timeout parameters.
         return false;
	 }
 
	 m_fpSerialPort = fpSerialPort;
#endif
 
     return true;
}
 
bool CSerialportDevice::Disconnect()
{
#ifdef linux
	::close(fd1);
	fd1 = -1;
#else
    CloseHandle(m_fpSerialPort);
    m_fpSerialPort = INVALID_HANDLE_VALUE;
#endif
 
	return true;
}
 
void CSerialportDevice::BeforeDeviceLoop()
{
	quint8 aFlush[1000];
 
	this->serialRead((char*)aFlush, 1000);
 
	BeforeClientLoop();
}
 
void CSerialportDevice::DeviceLoop()
{
	quint8 rxBuf[RX_BUF_SIZE+1];
	int nBytesReceived = 0;
 
    while( (nBytesReceived = this->serialRead((char*)rxBuf, RX_BUF_SIZE+1)) > 0)
	{
        this->OnDataReceived(rxBuf, nBytesReceived);
	}
 
	ClientLoop();
}
 
void CSerialportDevice::AfterDeviceLoop()
{
	AfterClientLoop();
 
	qDebug() << "@CSerialportDevice::AfterDeviceLoop()";
}
 
int CSerialportDevice::serialRead(char* aData, int nMaxSize)
{
#ifdef linux
    int iIn = 0;
#else
    unsigned long iIn = 0;
#endif
 
#ifdef linux
	if (fd1 < 1)
		return -1;
#else
	if(m_fpSerialPort == INVALID_HANDLE_VALUE)
		return -1;
#endif
 
 
#ifdef linux
	iIn = read(fd1, aData, nMaxSize - 1);
#else
    ReadFile(m_fpSerialPort, aData, nMaxSize-1, &iIn, 0);
#endif
 
    if (iIn <= 0)
	{
		return 0; // assume that command generated no response
	}
	else if(iIn > 0)
	{
        aData[iIn < nMaxSize ? iIn : nMaxSize-1] = '\0';
		this->m_nRxCnt += iIn;
	}
	return iIn;
}
 
#ifdef linux
void CSerialportDevice::configure_port(quint32 nBaudrate)      // configure the port
{
	struct termios port_settings;      // structure to store the port settings in
 
    switch(nBaudrate)
    {
    case 9600:
        port_settings.c_cflag = B9600;
        break;
    case 19200:
        port_settings.c_cflag = B19200;
        break;
    case 38400:
        port_settings.c_cflag = B38400;
        break;
    case 57600:
        port_settings.c_cflag = B57600;
        break;
    case 115200:
        port_settings.c_cflag = B115200;
        break;
    case 230400:
        port_settings.c_cflag = B230400;
        break;
    default:
        port_settings.c_cflag = B9600;
        break;
    }
//    port_settings.c_cflag = B9600;
    port_settings.c_cflag &= ~PARODD;    // set no parity, stop bits, data bits
	port_settings.c_cflag &= ~CSTOPB;
	port_settings.c_cflag &= ~CSIZE;
	port_settings.c_cflag |= CS8;
 
	port_settings.c_lflag = 0;
 
	port_settings.c_cc[VTIME] = 1;
	port_settings.c_cc[VMIN] = 0;
 
	port_settings.c_iflag = 0;
	port_settings.c_oflag = 0;
 
	tcsetattr(fd1, TCSANOW, &port_settings);    // apply the settings to the port
 
	tcflush(fd1, TCIOFLUSH);
}
#endif
 
void CSerialportDevice::ResetRxCnt()
{
	this->m_nRxCnt = 0;
}
 
quint64 CSerialportDevice::GetRxCnt()
{
	return this->m_nRxCnt;
}
 
void CSerialportDevice::Flush()
{
#ifdef linux
    tcflush(fd1, TCIOFLUSH);
#endif
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.