BeRTOS
timer_dsp56k.h
Go to the documentation of this file.
00001 #error This code must be revised for the new timer API
00002 
00041 /*#*
00042  *#* $Log$
00043  *#* Revision 1.10  2006/07/19 12:56:26  bernie
00044  *#* Convert to new Doxygen style.
00045  *#*
00046  *#* Revision 1.9  2006/02/21 21:28:02  bernie
00047  *#* New time handling based on TIMER_TICKS_PER_SEC to support slow timers with ticks longer than 1ms.
00048  *#*
00049  *#* Revision 1.8  2005/11/04 16:20:02  bernie
00050  *#* Fix reference to README.devlib in header.
00051  *#*
00052  *#* Revision 1.7  2005/04/11 19:10:28  bernie
00053  *#* Include top-level headers from cfg/ subdir.
00054  *#*
00055  *#* Revision 1.6  2004/11/16 22:37:14  bernie
00056  *#* Replace IPTR with iptr_t.
00057  *#*
00058  *#* Revision 1.5  2004/08/25 14:12:08  rasky
00059  *#* Aggiornato il comment block dei log RCS
00060  *#*
00061  *#* Revision 1.4  2004/07/30 14:27:49  rasky
00062  *#* Aggiornati alcuni file DSP56k per la nuova libreria di IRQ management
00063  *#*
00064  *#* Revision 1.3  2004/06/06 18:30:34  bernie
00065  *#* Import DSP56800 changes from SC.
00066  *#*
00067  *#* Revision 1.2  2004/06/03 11:27:09  bernie
00068  *#* Add dual-license information.
00069  *#*
00070  *#* Revision 1.1  2004/05/23 18:23:30  bernie
00071  *#* Import drv/timer module.
00072  *#*
00073  *#*/
00074 
00075 #ifndef DRV_TIMER_DSP56K_H
00076 #define DRV_TIMER_DSP56K_H
00077 
00078 #include "timer.h"
00079 #include <DSP56F807.h>
00080 #include <cfg/compiler.h>
00081 #include <hw.h>
00082 #include <drv/irq.h>
00083 
00084 // Calculate register pointer and irq vector from hw.h setting
00085 #define REG_SYSTEM_TIMER          PP_CAT(REG_TIMER_, SYSTEM_TIMER)
00086 #define SYSTEM_TIMER_IRQ_VECTOR   PP_CAT(IRQ_TIMER_, SYSTEM_TIMER)
00087 
00089 #define TIMER_PRESCALER           16
00090 
00092 #define TIMER_HW_HPTICKS_PER_SEC           (IPBUS_FREQ / TIMER_PRESCALER)
00093 
00095 typedef uint16_t hptime_t;
00096 
00097 static void system_timer_isr(UNUSED(iptr_t, arg));
00098 
00099 static void timer_hw_init(void)
00100 {
00101     uint16_t compare;
00102 
00103     // Clear compare flag status and enable interrupt on compare
00104     REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
00105     REG_SYSTEM_TIMER->SCR |= REG_TIMER_SCR_TCFIE;
00106 
00107     // Calculate the compare value needed to generate an interrupt exactly
00108     //  TICKS_PER_SEC times each second (usually, every millisecond). Check that
00109     //  the calculation is accurate, otherwise there is a precision error
00110     // (probably the prescaler is too big or too small).
00111     compare = TIMER_HW_HPTICKS_PER_SEC / TICKS_PER_SEC;
00112     ASSERT((uint32_t)compare * TICKS_PER_SEC == IPBUS_FREQ / TIMER_PRESCALER);
00113     REG_SYSTEM_TIMER->CMP1 = compare;
00114 
00115     // The value for reload (at initializationa and after compare is met) is zero
00116     REG_SYSTEM_TIMER->LOAD = 0;
00117 
00118     // Set the interrupt handler and priority
00119     irq_install(SYSTEM_TIMER_IRQ_VECTOR, &system_timer_isr, NULL);
00120     irq_setpriority(SYSTEM_TIMER_IRQ_VECTOR, IRQ_PRIORITY_SYSTEM_TIMER);
00121 
00122     // Small preprocessor trick to generate the REG_TIMER_CTRL_PRIMARY_IPBYNN macro
00123     //  needed to set the prescaler
00124     #define REG_CONTROL_PRESCALER             PP_CAT(REG_TIMER_CTRL_PRIMARY_IPBY, TIMER_PRESCALER)
00125 
00126     // Setup the counter and start counting
00127     REG_SYSTEM_TIMER->CTRL =
00128         REG_TIMER_CTRL_MODE_RISING    |          // count rising edges (normal)
00129         REG_CONTROL_PRESCALER         |          // frequency (IPbus / TIMER_PRESCALER)
00130         REG_TIMER_CTRL_LENGTH;                   // up to CMP1, then reload
00131 }
00132 
00133 INLINE void timer_hw_irq(void)
00134 {
00135     // Clear the overflow flag so that we are ready for another interrupt
00136     REG_SYSTEM_TIMER->SCR &= ~REG_TIMER_SCR_TCF;
00137 }
00138 
00139 INLINE hptime_t timer_hw_hpread(void)
00140 {
00141     return REG_SYSTEM_TIMER->CNTR;
00142 }
00143 
00144 #define DEFINE_TIMER_ISR \
00145     static void system_timer_isr(UNUSED(iptr_t, arg))
00146 
00147 #endif /* DRV_TIMER_DSP56_H */