Listing 1: Ed Remmel's timer implementation

/* global #defines, typedefs and macros */

/* 8-bit unsigned integer */
#define u8  unsigned char 

/* 16-bit unsigned integer */ 
#define u16 unsigned int       

/* 32-bit unsigned integer */
#define u32 unsigned long      
    
/* timer tick occurs every 3 milliseconds */
#define TIMER_TICK_MSEC 3 

/* tx/rx cycle completes every 3 millisec */
#define TDM_CYCLE_MSEC 3  
    
#define LONG_MSEC_ELAPSED(startTime,timeout) \
 (((u32)(((u32)gMsecCnt)-((u32)startTime)))  \
  >=((u32)timeout))
#define WORD_MSEC_ELAPSED(startTime,timeout) \
 (((u16)(((u16)gMsecCnt)-((u16)startTime)))  \
  >=((u16)timeout))
#define BYTE_MSEC_ELAPSED(startTime,timeout) \
 (((u8)(((u8)gMsecCnt)-((u8)startTime)))     \
  >=((u8)timeout))
    
    
/* global variables */

/* count of 1 millisecond intervals
   elapsed since reset */
u32 gMsecCnt; 
    
    
/* timer control stuff */
#define RX_TIMEOUT_MSEC \
 (TDM_CYCLE_MSEC+1+TIMER_TICK_MSEC)
u8  lastRxBlkTime;
    
    
/* timer tick handler code */
__interrupt void
HandleHeartbeatInt()
{
    gMsecCnt += TIMER_TICK_MSEC;
}
    
    
/* main polling loop code */
if (/* some event occurred,
    i.e. received block */)
{ 
 /* reset state variable to indicate event
    processed */ 
 /* process the event some */
    
 /* (re)start received block timer */ 
 lastRxBlkTime = (u8) gMsecCnt;
}
    
/* poll timers for completion */
if (BYTE_MSEC_ELAPSED(lastRxBlkTime,
                      RX_TIMEOUT_MSEC))
{
 /* timer expired */
 /* handle exception condition,
    reset hardware */
}
/* End of File */