BeRTOS
|
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 */