#include "stdafx.h"
#include "IrPulse.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif#define charWidth 73 //length of transmitted character in us//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////CIrPulse::CIrPulse()
{

m_irPort=INVALID_HANDLE_VALUE;

//set defaults for Sony type remotes

iDataLength=12; //default number of bits to transmit
iHPulse=2200; //length of start bit (us)
iHSpace=550; //length of start space (us)
i1Pulse=1100; //length of 1pulse (us)
i1Space=550; //length of 1space (us)
i0Pulse=550; //length of 0pulse (us)
i0Space=550; //length of 0space (us)
bPulseStream.SetSize(charWidth*4,16); //allocate space for buffer
for(int i=0;i<charWidth*4;i++)
bPulseStream.Add(0xdb); //fill the buffer with char to produce 40kHz pulses
}CIrPulse::~CIrPulse()
{
Close();
bPulseStream.RemoveAll(); //remove buffer

}BOOL CIrPulse::Open(UINT uiPort)
{
    ASSERT(uiPort > 0 && uiPort <= 255);    Close();     // Open the IRDA port    CString strPort;
    strPort.Format(_T("COM%d:"), uiPort);
    
    m_irPort = CreateFile((LPCTSTR) strPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (m_irPort == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }    // Set the size of input and output buffers    VERIFY(SetupComm(m_irPort, 2048, 2048));    // clear the read and write buffers    VERIFY(PurgeComm(m_irPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));    // Reinitializes all IRDA port settings    DCB dcb;    dcb.DCBlength = sizeof(DCB);    VERIFY(GetCommState(m_irPort, &dcb));    dcb.BaudRate          = CBR_115200;
    dcb.fBinary           = TRUE;
    dcb.fParity           = TRUE;
    dcb.fOutxCtsFlow      = FALSE;
    dcb.fOutxDsrFlow      = FALSE;
    dcb.fDtrControl       = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity   = FALSE;
    dcb.fTXContinueOnXoff = FALSE;
    dcb.fOutX             = FALSE;
    dcb.fInX              = FALSE;
    dcb.fErrorChar        = FALSE;  
    dcb.fNull             = FALSE;
    dcb.fRtsControl       = RTS_CONTROL_DISABLE;
    dcb.fAbortOnError     = FALSE;
    dcb.ByteSize          = 8; 
    dcb.Parity            = EVENPARITY; 
    dcb.StopBits          = TWOSTOPBITS;
 
    
    VERIFY(SetCommState(m_irPort, &dcb));    // Set the timeouts for all read and write operations    COMMTIMEOUTS timeouts;    VERIFY(GetCommTimeouts(m_irPort, &timeouts));    timeouts.ReadIntervalTimeout         = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier  = 0;
    timeouts.ReadTotalTimeoutConstant    = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant   = 0;    VERIFY(SetCommTimeouts(m_irPort, &timeouts)); DWORD dwEvent=EV_TXEMPTY;
SetCommMask(m_irPort,dwEvent);    return TRUE;
}void CIrPulse::Close()
{
    // Close the IR port
    
    if (IsOpen())
    {
        VERIFY(PurgeComm(m_irPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));        VERIFY(CloseHandle(m_irPort));        m_irPort = INVALID_HANDLE_VALUE;
    }
}BOOL CIrPulse::IsOpen() const

    return m_irPort != INVALID_HANDLE_VALUE; 
}UINT CIrPulse::FindIrPort()
{
    // Look into the registry for the IR port number    HKEY hKey = NULL;    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Comm\\IrDA"), 
0, 0, &hKey) == ERROR_SUCCESS)
{
        DWORD dwType = 0;
        DWORD dwData = 0;
        DWORD dwSize = sizeof(dwData);        if (RegQueryValueEx(hKey, _T("Port"), NULL, &dwType, 
(LPBYTE) &dwData, &dwSize) == ERROR_SUCCESS)
        {
            if (dwType == REG_DWORD && dwSize == sizeof(dwData))
            {
                RegCloseKey(hKey);
                                
                return (UINT) dwData;
            }
        }        RegCloseKey(hKey);
    }    return 0;
}DWORD CIrPulse::Write(const char* pData, DWORD dwCount) const
{
    ASSERT(IsOpen());    DWORD dwBytesWritten = 0;    WriteFile(m_irPort, pData, dwCount, &dwBytesWritten, NULL);    return dwBytesWritten;
}BOOL CIrPulse::SetCodeSize(DWORD dwCodeSize) { iDataLength=dwCodeSize;
return true;
}BOOL CIrPulse::SendCode(long lValue)
{ DWORD dwCount;
int i=0; ASSERT(iDataLength>0);


//purge the transmit buffer 
VERIFY(PurgeComm(m_irPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR));

// send the code 6 times for each button press
for(int x=0;x<6;x++) {
MakeStream(lValue); //send the code
dwCount=GetTickCount();
while(GetTickCount()<dwCount+26) //delay for 26 ms
i++;
}
return true;
}BOOL CIrPulse::MakeStream(long lValue) {
DWORD dwStreamLength;
//make the start pulse
dwStreamLength=iHPulse/charWidth;
ASSERT(Write((const char *)bPulseStream.GetData(),dwStreamLength)==dwStreamLength);
// ********************************************
// ***** The Delay before the next pulse goes here
// ********************************************

//loop through the bits in the Code sending the pulse
for(int i=0;i<iDataLength;i++) {
if(lValue & 1) {
//make the 1 pulse
dwStreamLength=i1Pulse/charWidth;
ASSERT(Write((const char *)bPulseStream.GetData(),dwStreamLength)==dwStreamLength);
// ********************************************
// ***** The Delay before the next pulse goes here
// ********************************************
}
else {
//make the 0 pulse
dwStreamLength=i0Pulse/charWidth;
ASSERT(Write((const char *)bPulseStream.GetData(),dwStreamLength)==dwStreamLength);
// ********************************************
// ***** The Delay before the next pulse goes here
// ********************************************

}
lValue >>= 1;
}
return TRUE;
}
分不够另开贴