Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/QNX4/TimerBook.cpp

Go to the documentation of this file.
00001 // From O'Reilly
00002 
00003 enum TimerState { Idle, Active, Done };
00004 enum TimerType  { OneShot, Periodic  };
00005 
00006 class Timer
00007 {
00008 public:
00009   Timer();
00010   virtual ~Timer();
00011 
00012   int  start( unsigned int nMilliseconds, TimerType  =OneShot);
00013   int  waitfor();
00014   void cancel();
00015 
00016   volatile TimerState  state;  // Changed by some other process.
00017            TimerType   type;
00018 
00019   ULONG   length;
00020 
00021   ULONG   count;      // The number of ticks remaining.
00022   Timer*  pNext;      // For a Linked List of Timer
00023                       // Ordered by the number of ticks
00024                       // remaining for each timer.
00025 
00026 private:
00027   // It's static because it can't manipulate software timer variable
00028   // Our interrupt service routine.
00029   static void interrupt  Interrupt();   
00030 };
00031 
00032 #include "i8018xEB.h"   // Declare the gProcessor global object
00033 #include "Timer.hpp"
00034 
00035 #define  CYCLES_PER_TICK   (25000/4)
00036 /* Number of clock cycles per tick.
00037    for a 25 MHz => 25,000,000 cycles/s  OR  25,000 cycles/ms
00038    and a tick takes 4 ms.
00039 
00040    The software timer can have a duration from 1 to 65,535 ms,
00041    a bit more than a minute.
00042 */
00043 
00044 
00045 /**************************************************************************
00046 *                                                                         *
00047 *  Method:       Timer()                                                  *
00048 *  Description:  Constructor for the Timer Class.                         *
00049 *                                                                         *
00050 *  Returns:      None defined.                                            *
00051 *                                                                         *
00052 **************************************************************************/
00053 
00054 Timer::Timer (void)
00055 {
00056     static int bInitialized = 0;
00057 
00058     // Initialize the new software timer.
00059 
00060     state  = Idle;
00061     type   = OneShot;
00062     length = 0;
00063     count  = 0;
00064     pNext  = NULL;
00065 
00066     // Initialize the timer hardware, if not previously done.
00067 
00068     if ( !bInitialized )
00069     {
00070         // Install the interrupt handler and enable timer interrupts.
00071         gProcessor.installHandler( TIMER2_INT, Timer::Interrupt);
00072         gProcessor.pPCB->intControl.timerControl &= ~(TIMER_MASK | TIMER_PRIORITY );
00073 
00074         // Initialize the hardware device (using Timer #2)
00075         gProcessor.pPCB->timer[2].count     = 0;
00076         gProcessor.pPCB->timer[2].maxCountA = CYCLES_PER_TICK;
00077         gProcessor.pPCB->timer[2].control   = TIMER_ENABLE | TIMER_INTERRUPT | TIMER_PERIODIC;
00078 
00079         // Mark the timer hardware initialized.
00080         bInitialized = 1;
00081     }
00082 
00083 } /* Timer constructor */
00084 
00085 /**************************************************************************
00086 *                                                                         *
00087 *  Method:       Start()                                                  *
00088 *  Description:  Start a software timer, based on the tick                *
00089 *                from the underlying hardware timer.                      *
00090 *                                                                         *
00091 *  Returns:      0 on success, -1 if the timer is already in use.         *
00092 *                                                                         *
00093 **************************************************************************/
00094 
00095 int Timer::start( unsigned int nMilliseconds, TimerType timerType )
00096 {
00097     if ( state != Idle ) {   // Timer already in use.
00098         return (-1);
00099     }
00100 
00101     // Initialize the software timer.
00102     state  = Active;
00103     type   = timerType;
00104     length = nMilliseconds / MS_PER_TICK;
00105 
00106     // Add this timer to the active timer list.
00107     timerList.insert( this );
00108               
00109     return (0);
00110 
00111 } /* start() */
00112 
00113 /**************************************************************************
00114 *                                                                         *
00115 *  Method:       Interrupt()                                              *
00116 *  Description:  An interrupt handler for the timer hardware              *
00117 *                                                                         *
00118 *  Notes:      - This method is declared static, so that we cannot        *
00119 *                inadvertently modify any of the software timers.         *
00120 *              - The keyword interrupt is to ask a x86 compiler           *
00121 *                to save and restore every registers before and after     *
00122 *                that specific method (more than ordinary method call).   *
00123 *                                                                         *
00124 *  Returns:      None defined.                                            *
00125 *                                                                         *
00126 **************************************************************************/
00127 void interrupt  Timer::Interrupt()
00128 {
00129     // Decrement the active timer's count.
00130     timerList.tick();
00131 
00132     // Acknowledge the timer interrupt.
00133     gProcessor.pPCB->intControl.eoi = EOI_NONSPECIFIC;
00134 
00135     // Clear the Maximum Count bit (to start the next cycle).
00136     gProcessor.pPCB->timer[2].control &= ~TIMER_MAXCOUNT;
00137 
00138 } /* Interrupt() */
00139 
00140 /**************************************************************************
00141 *                                                                         *
00142 *  Method:       waitfor()                                                *
00143 *  Description:  Wait for the software timer to finish.                   *
00144 *                                                                         *
00145 *  Returns:      0 on success, -1 if the timer is not running.            *
00146 *                                                                         *
00147 **************************************************************************/
00148 int Timer::waitfor()
00149 {
00150     if (state != Active)
00151     {
00152         return (-1);
00153     }
00154 
00155     // Wait for the timer to expire in a stupid busy-loop.
00156     while ( state != Done);
00157 
00158     // Restart or idle the timer, depending on its type.
00159     if ( type == Periodic )
00160     {
00161         state = Active;
00162         timerList.insert( this );
00163     }
00164     else
00165     {
00166         state = Idle;
00167     }
00168 
00169     return (0);
00170 
00171 } /* waitfor() */
00172 
00173 /**************************************************************************
00174 *                                                                         *
00175 *  Method:       cancel()                                                 *
00176 *  Description:  Stop a running timer                                     *
00177 *                                                                         *
00178 *  Returns:      None defined.                                            *
00179 *                                                                         *
00180 **************************************************************************/
00181 void Timer::cancel( void )
00182 {
00183     // Remove the timer from the timer list.
00184     if ( state == Active )
00185     {
00186         timerList.remove( this );
00187     }
00188 
00189     // Reset the timer's state.
00190     state = Idle;
00191 
00192 } /* cancel() */
00193 
00194 Timer::~Timer()
00195 {
00196     cancel();
00197 }
00198 
00199 // Careful with Periodic timer that waitfor is never called.
00200 int Timer::poll()
00201 {
00202     return ( state == Done );
00203 }
00204 
00205 // Asynchronous CallBack
00206 
00207       
00208 

Generated on Sun Oct 14 18:46:42 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001