////////////////////////////////////////////////////////////////////////////////
///////////////////
// OBJ_LED.h
#pragma once
////////////////////////////////////////////////////////////////////////////////
///////////////////
// CLASS OBJ_LED
class OBJ_LED
{
////////////////////////////////////////////////////////////////////////////////
///////////////////
// CTOR/DTOR
public:
OBJ_LED();
~OBJ_LED();
////////////////////////////////////////////////////////////////////////////////
///////////////////
// METHODS
public:
void Flash(int iLed, bool bOn);
void Set(int iLed, bool bOn);
bool Get (int iLed);
void ThreadLoop(void);
////////////////////////////////////////////////////////////////////////////////
///////////////////
// HELPERS
private:
void Start(void);
void Stop(void);
////////////////////////////////////////////////////////////////////////////////
///////////////////
// CONSTANTS
private:
enum
{
NUM_LEDS = 4,
SLEEP_DELAY = 100,
THREAD_PRIORITY = THREAD_PRIORITY_IDLE,
LED_1_ON = 0x01,
LED_2_ON = 0x02,
LED_3_ON = 0x03,
LED_4_ON =0x04,
LED_ALL_ON = 0x05,
LED_1_OFF = 0x06,
LED_2_OFF = 0x07,
LED_3_OFF = 0x08,
LED_4_OFF = 0x09,
LED_ALL_OFF = 0x0A,
};
////////////////////////////////////////////////////////////////////////////////
///////////////////
// DATA
struct
{
CRITICAL_SECTION Critical;
HANDLE hDevice;
bool bRunning;
bool bStop;
unsigned char ucLedState;
unsigned char ucLedFlash;
CWinThread* pThread;
}v;
};
WINCE - ThreadSafe wrapper for LEDs
////////////////////////////////////////////////////////////////////////////////
///////////////////
// OBJ_LED.cpp
#include "stdafx.h"
#include "OBJ_LED.h"
/////////////////////////////////////////////////////////////////////////////
// safe short jumped Hook for thread
UINT Thread_OBJ_LED(LPVOID pParam)
{
OBJ_LED* pOBJ_LED = (OBJ_LED*)pParam;
pOBJ_LED->ThreadLoop();
return 1;
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// CTOR
OBJ_LED::OBJ_LED()
{
v.pThread = NULL;
v.hDevice = NULL;
v.ucLedState = 0x00;
v.ucLedFlash = 0x00;
InitializeCriticalSection(&v.Critical);
Start();
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// DTOR
OBJ_LED::~OBJ_LED()
{
Stop();
DeleteCriticalSection(&v.Critical);
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// START THREAD
void OBJ_LED::Start(void)
{
v.bStop = false;
v.bRunning = false;
//OPEN STREAM
DWORD dwAccess = GENERIC_WRITE;
DWORD dwShareMode = NULL;
DWORD dwCreationDisposition = OPEN_ALWAYS;
DWORD dwFlagsAndAttributes = FILE_FLAG_NO_BUFFERING;
v.hDevice = CreateFile(L"LED1:", dwAccess, dwShareMode, NULL,
dwCreationDisposition, dwFlagsAndAttributes, NULL);
v.pThread = AfxBeginThread(Thread_OBJ_LED, this, THREAD_PRIORITY);
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// STOP THREAD
void OBJ_LED::Stop(void)
{
for(int l = 0; l < NUM_LEDS; l++)
Set(l, false);
if(v.bRunning)
{
v.bStop = true;
while(v.bRunning)
Sleep(THREAD_GRANULARITY);
}
DeleteFile(L"LED1:");
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// SET
void OBJ_LED::Set(int iLed, bool bOn)
{
////////////////////////////////////////////////////////////////////////////////
///////////////////
EnterCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
if(bOn)
v.ucLedState |= (0x01 << iLed);
else
v.ucLedState &= ~(0x01 << iLed);
////////////////////////////////////////////////////////////////////////////////
///////////////////
LeaveCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// GET
bool OBJ_LED::Get(int iLed)
{
bool bReturn;
////////////////////////////////////////////////////////////////////////////////
///////////////////
EnterCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
if(v.ucLedState & (0x01 << iLed))
bReturn = true;
else
bReturn = false;
////////////////////////////////////////////////////////////////////////////////
///////////////////
LeaveCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
return bReturn;
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// FLASH
void OBJ_LED::Flash(int iLed, bool bOn)
{
////////////////////////////////////////////////////////////////////////////////
///////////////////
EnterCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
if(bOn)
v.ucLedFlash |= (0x01 << iLed);
else
v.ucLedFlash &= ~(0x01 << iLed);
////////////////////////////////////////////////////////////////////////////////
///////////////////
LeaveCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
// MAIN THREAD LOOP
void OBJ_LED::ThreadLoop(void)
{
unsigned char ucOldState = 0xFF;
v.bStop = false;
v.bRunning = true;
while(!v.bStop)
{
////////////////////////////////////////////////////////////////////////////////
///////////////////
EnterCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
//FLASH LEDS
for(int l = 0; l < NUM_LEDS; l++)
if(v.ucLedFlash & (0x01<<l))
Set(l, !Get(l));
//MAKE LEDS REFLECT INTERNAL STATE
if(ucOldState != v.ucLedState)
{
ucOldState = v.ucLedState;
for(int l = 0; l < NUM_LEDS; l++)
if(v.ucLedState & (0x01<<l))
DeviceIoControl(v.hDevice, LED_1_ON + l, NULL, NULL, NULL, NULL,
NULL, NULL);
else
DeviceIoControl(v.hDevice, LED_1_OFF + l, NULL, NULL, NULL, NULL,
NULL, NULL);
}
////////////////////////////////////////////////////////////////////////////////
///////////////////
LeaveCriticalSection(&v.Critical);
////////////////////////////////////////////////////////////////////////////////
///////////////////
//DELAY
Sleep(SLEEP_DELAY);
}
v.bRunning = false;
}

