//---------------------------------------------------------------------------


#pragma hdrstop

#include "SerialComm.h"
#include "Pcomm.h"
#include "vcl.h"

//---------------------------------------------------------------------------
SerialComm::SerialComm(USHORT PortNum)
{
    if(PortNum < 1) m_usPortNum = 1 ;
    else m_usPortNum = PortNum ;

    if(sio_open(m_usPortNum) != SIO_OK) sio_close(m_usPortNum) ;

    m_iCommMode = 0 ;
}
//---------------------------------------------------------------------------
SerialComm::~SerialComm()
{
    sio_close(m_usPortNum) ;
}
//---------------------------------------------------------------------------
BOOL __fastcall SerialComm::PortIOCtrl(int nBaud, int nDataBit, int nStopBit, int nParity)
{
    m_iCommMode |= nDataBit ;
    m_iCommMode |= nStopBit ;
    m_iCommMode |= nParity ;

    return (sio_ioctl(m_usPortNum, nBaud, m_iCommMode) == SIO_OK);
}
//---------------------------------------------------------------------------
BOOL __fastcall SerialComm::Write(AnsiString Data)
{
    sio_flush(m_usPortNum, 2);
    if(Data.IsEmpty() == TRUE) return FALSE ;

    sio_write (m_usPortNum, Data.c_str(), Data.Length());

    Sleep(200) ;

    return TRUE ;
}
//---------------------------------------------------------------------------
BOOL __fastcall SerialComm::Write(char* Data, int Length)
{
    sio_flush(m_usPortNum, 2);
    if(Data == NULL) return FALSE ;

    sio_write (m_usPortNum, Data, Length);

    Sleep(200) ;

    return TRUE ;
}
//---------------------------------------------------------------------------
BOOL __fastcall SerialComm::Read(char* pData, int& Length)
{
    Length = sio_iqueue(m_usPortNum) ;
    
    if(Length > 1024 || Length == 0)
    {
        sio_flush(m_usPortNum, 2);
        return FALSE ;
    }

    if(Length > 0) sio_read(m_usPortNum, pData, Length) ;

    return TRUE ;
}
//---------------------------------------------------------------------------
BOOL __fastcall SerialComm::Read(AnsiString& Data)
{
    int iLen;
    char* pBuffer ;
    BOOL bReturn ;

    try
    {
        iLen = sio_iqueue(m_usPortNum) ;
        pBuffer = new char[iLen + 1] ;
        memset(pBuffer, 0, sizeof(pBuffer)) ;

        if(iLen > 1024 || iLen == 0) bReturn = FALSE ;
        else
        {
            sio_read(m_usPortNum, pBuffer, iLen);
            Data = pBuffer ;
            bReturn = TRUE ;
        }
    }
    __finally
    {
        delete[] pBuffer;
    }
    return bReturn ;
}
//---------------------------------------------------------------------------
USHORT __fastcall SerialComm::CRC16(USHORT *pData, short Length)
{
	USHORT CRC = 0xffff, next, carry ;

	while(Length--)
	{
		next = *pData;
		CRC ^= next;
		for(int n=0 ; n<8 ; n++)
		{
			carry = CRC & 1 ;
			CRC >>= 1 ;
			if(carry) CRC ^= 0xA001 ;
		}
		pData ++ ;
	}
    return CRC ;
}
//---------------------------------------------------------------------------

#pragma package(smart_init)
