OSDN Git Service

Added the target and the host directory.
[kozos-expbrd/kozos_expbrd.git] / firm / sample / simple_mp3_player / target / os / driver_timer.c
1 #include "defines.h"
2 #include "kozos.h"
3 #include "intr.h"
4 #include "interrupt.h"
5 #include "timer.h"
6 #include "lib.h"
7 #include "driver_timer.h"
8
9 #define TIMERDRV_CMD_EXPIRE 'e' /* ¥¿¥¤¥ÞËþλ */
10 #define TIMERDRV_CMD_START  's' /* ¥¿¥¤¥Þ¤Î¥¹¥¿¡¼¥È */
11
12 struct timerbuf {
13   struct timerbuf *next;
14   kz_msgbox_id_t id; /* ¥¿¥¤¥ÞËþλ»þ¤Î¥á¥Ã¥»¡¼¥¸Á÷¿®Àè */
15   int msec;
16 };
17
18 static struct timerreg {
19   struct timerbuf *timers; /* ¥¿¥¤¥Þ¡¦¥Ð¥Ã¥Õ¥¡¤Î¥ê¥ó¥¯¥ê¥¹¥È */
20   int index; /* ÍøÍѤ¹¤ë¥¿¥¤¥Þ¤ÎÈÖ¹æ */
21 } timerreg;
22
23 void timerdrv_start(int msec)
24 {
25     struct timerreq *req;
26     req = kz_kmalloc(sizeof(*req));
27     req->id = MSGBOX_ID_TIMEXPIRE;
28     req->msec = msec;
29     kz_send(MSGBOX_ID_TIMDRIVE, TIMERDRV_CMD_START, (char *)req);
30 }
31
32 void timerdrv_wait()
33 {
34     kz_recv(MSGBOX_ID_TIMEXPIRE, NULL, NULL);
35 }
36
37 /*
38  * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò
39  * ¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
40  * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
41  * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
42  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
43  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
44  * ¤Þ¤¿Èó¥³¥ó¥Æ¥­¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
45  * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
46  */
47 static void timerdrv_intr(void)
48 {
49   struct timerreg *tim = &timerreg;
50
51   if (timer_is_expired(tim->index)) { /* ¥¿¥¤¥Þ³ä¹þ¤ß */
52     timer_cancel(tim->index);
53     kx_send(MSGBOX_ID_TIMDRIVE, TIMERDRV_CMD_EXPIRE, NULL);
54   }
55 }
56
57 static int timerdrv_init(void)
58 {
59   memset(&timerreg, 0, sizeof(timerreg));
60   timerreg.index = TIMER_DEFAULT_DEVICE;
61   return 0;
62 }
63
64 /* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
65 static int timerdrv_command(struct timerreg *tim, int cmd, char *p)
66 {
67   struct timerbuf *tmbuf;
68   struct timerbuf **tmbufp;
69   struct timerreq *req;
70   int t, msec;
71
72   switch (cmd) {
73   case TIMERDRV_CMD_EXPIRE: /* ¥¿¥¤¥ÞËþλ */
74     tmbuf = tim->timers;
75     if (tmbuf) {
76       tim->timers = tmbuf->next;
77       kz_send(tmbuf->id, 0, NULL);
78       kz_kmfree(tmbuf);
79       if (tim->timers)
80         timer_start(tim->index, tim->timers->msec, 0);
81     }
82     break;
83
84   case TIMERDRV_CMD_START: /* ¥¿¥¤¥Þ¤Î¥¹¥¿¡¼¥È */
85     req = (struct timerreq *)p;
86
87     tmbuf = kz_kmalloc(sizeof(*tmbuf));
88     tmbuf->next = NULL;
89     tmbuf->id   = req->id;
90     tmbuf->msec = req->msec;
91
92     t = 0;
93     if (tim->timers) {
94       t = timer_gettime(tim->index);
95     }
96
97     for (tmbufp = &tim->timers;; tmbufp = &(*tmbufp)->next) {
98       if (*tmbufp == NULL) {
99         *tmbufp = tmbuf;
100         if (tmbufp == &tim->timers)
101           timer_start(tim->index, tim->timers->msec, 0);
102         break;
103       }
104       msec = (*tmbufp)->msec - t;
105       if (msec < 0) msec = 0;
106       if (tmbuf->msec < msec) {
107         (*tmbufp)->msec = msec - tmbuf->msec;
108         tmbuf->next = *tmbufp;
109         *tmbufp = tmbuf;
110         timer_start(tim->index, tim->timers->msec, 0);
111         break;
112       }
113       t = 0;
114       tmbuf->msec -= msec;
115     }
116
117     kz_kmfree(p);
118     break;
119
120   default:
121     break;
122   }
123
124   return 0;
125 }
126
127 int driver_timer(int argc, char *argv[])
128 {
129   int cmd;
130   char *p;
131
132   timerdrv_init();
133   kz_setintr(SOFTVEC_TYPE_TIMINTR, timerdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
134
135   while (1) {
136     kz_recv(MSGBOX_ID_TIMDRIVE, &cmd, &p);
137     timerdrv_command(&timerreg, cmd, p);
138   }
139
140   return 0;
141 }