timer.c
00001
00002
00003
00004
00005
00006
00007 #include "sh7045lib.h"
00008 #include "cpu_spec.h"
00009
00010
00014 typedef struct {
00015 timerHandler_t callback;
00016 unsigned long interval;
00017 long interval_left;
00018 } eachTimerHandler_t;
00019
00020
00024 typedef struct {
00025 int numHandler;
00026 unsigned long interval_usec;
00027 eachTimerHandler_t handler[TIMER_HANDLER_MAX];
00028 } timerHandlerSet_t;
00029 static timerHandlerSet_t Handler;
00030
00031
00032 static unsigned long Usec = 0;
00033 static unsigned long Sec = 0;
00034
00035
00036 static void rawTimerHandler(void) {
00037 int i;
00038 eachTimerHandler_t *p;
00039
00040 Usec += Handler.interval_usec;
00041 if (Usec >= 1000000) {
00042 Usec -= 1000000;
00043 ++Sec;
00044 }
00045 for (i = 0; i < Handler.numHandler; ++i) {
00046 p = &Handler.handler[i];
00047 p->interval_left -= Handler.interval_usec;
00048 while (Handler.interval_usec > p->interval_left) {
00049 p->interval_left += p->interval;
00050 p->callback();
00051 }
00052 }
00053 }
00054
00055
00056 int set_timerHandler(timerHandler_t callback, int interval_usec) {
00057 if (Handler.numHandler >= TIMER_HANDLER_MAX) {
00058 return -1;
00059 }
00060 Handler.handler[Handler.numHandler].callback = callback;
00061 Handler.handler[Handler.numHandler].interval = interval_usec;
00062 Handler.handler[Handler.numHandler].interval_left = interval_usec;
00063
00064 ++Handler.numHandler;
00065 return 0;
00066 }
00067
00068
00069 void unset_timerHandler(timerHandler_t callback) {
00070 int i;
00071
00072 if (Handler.numHandler <= 1) {
00073 Handler.numHandler = 0;
00074 }
00075
00076 for (i = 0; i < Handler.numHandler; ++i) {
00077 if (Handler.handler[i].callback == callback) {
00078 Handler.handler[i] = Handler.handler[Handler.numHandler];
00079 --Handler.numHandler;
00080 return;
00081 }
00082 }
00083 }
00084
00085
00086 void init_timer(int level) {
00087 Handler.numHandler = 0;
00088 Handler.interval_usec = ~0;
00089
00090 MTU.TSTR.BYTE &= ~0x80;
00091 MTU4.TCR.BYTE = 0x20;
00092 MTU4.TMDR.BYTE = 0x00;
00093 MTU4.TIOR.BYTE.H = 0x03;
00094 MTU.TOER.BYTE |= 0x02;
00095
00096 INTC.IPRF.WORD &= ~0xf000;
00097 INTC.IPRF.WORD |= level << 12;
00098
00099 MTU4.TIER.BYTE |= 0x01;
00100
00101 PFC.PECR1.WORD |= 0x0100;
00102 PFC.PEIOR.WORD |= 0x1000;
00103 }
00104
00105
00106 int start_timer(int usec) {
00107 unsigned long cnt = (MTU4_MSEC_CNT * usec) >> 10;
00108 if (cnt > 0xffff) {
00109 return -1;
00110 }
00111 Handler.interval_usec = usec;
00112 MTU4.TGRA = cnt;
00113 MTU4.TCNT = 0;
00114 MTU.TSTR.BYTE |= 0x80;
00115
00116 return 0;
00117 }
00118
00119
00120 void stop_timer(void) {
00121 MTU.TSTR.BYTE &= ~0x80;
00122 }
00123
00124
00125 void getRawCount(unsigned short *cnt) {
00126 int level = get_imask();
00127
00128 set_imask((INTC.IPRF.WORD >> 12) & 0xf);
00129 *cnt = MTU4.TCNT;
00130 set_imask(level);
00131 }
00132
00133
00134 void getTimestamp(unsigned long *msec, unsigned short *usec) {
00135 int level = get_imask();
00136
00137 set_imask((INTC.IPRF.WORD >> 12) & 0xf);
00138 if (usec) {
00139 *usec = Usec % 1000;
00140 }
00141 if (msec) {
00142 *msec = Sec * 1000 + Usec / 1000;
00143 }
00144 set_imask(level);
00145 }
00146
00147
00148 #pragma interrupt
00149 void tgi4a(void) {
00150 MTU4.TSR.BYTE &= ~0x01;
00151 rawTimerHandler();
00152 }
00153