WINCE - ThreadSafe wrapper for LEDs

Fraser
////////////////////////////////////////////////////////////////////////////////
///////////////////
//  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;
};

Fraser
////////////////////////////////////////////////////////////////////////////////
///////////////////
//  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;
}

Fraser
I have only tested the above code on the Mini6410

Luki
Do u have a C# code for 6410 for controlling leds?