OSDN Git Service

Changed the implementation with lib.
[kozos-expbrd/kozos_expbrd.git] / firm / sample / simple_mp3_player / os / driver_console.c
1 #include "defines.h"
2 #include "kozos.h"
3 #include "intr.h"
4 #include "interrupt.h"
5 #include "serial.h"
6 #include "lib.h"
7 #include "driver_console.h"
8
9 #define CONS_BUFFER_SIZE 32
10
11 #define CONSDRV_CMD_USE   'u' /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
12 #define CONSDRV_CMD_WRITE 'w' /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
13
14 static struct consreg {
15   kz_thread_id_t id; /* ¥³¥ó¥½¡¼¥ë¤òÍøÍѤ¹¤ë¥¹¥ì¥Ã¥É */
16   int index;         /* ÍøÍѤ¹¤ë¥·¥ê¥¢¥ë¤ÎÈÖ¹æ */
17
18   char *send_buf;    /* Á÷¿®¥Ð¥Ã¥Õ¥¡ */
19   int send_len;      /* Á÷¿®¥Ð¥Ã¥Õ¥¡Ãæ¤Î¥Ç¡¼¥¿¥µ¥¤¥º */
20
21   /* kozos.c ¤Î kz_msgbox ¤ÈƱÍͤÎÍýͳ¤Ç¡¤¥À¥ß¡¼¡¦¥á¥ó¥Ð¤Ç¥µ¥¤¥ºÄ´À°¤¹¤ë */
22   long dummy[3];
23 } consreg[CONSDRV_DEVICE_NUM];
24
25 /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï¤ò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
26 void console_use(int index)
27 {
28   char *p;
29   p = kz_kmalloc(3);
30   p[0] = '0';
31   p[1] = CONSDRV_CMD_USE;
32   p[2] = '0' + index;
33   kz_send(MSGBOX_ID_CONSOUTPUT, 3, p);
34 }
35
36 /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎϤò¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Ë°ÍÍꤹ¤ë */
37 void console_write(char *str)
38 {
39   char *p;
40   int len;
41   len = strlen(str);
42   p = kz_kmalloc(len + 2);
43   p[0] = '0';
44   p[1] = CONSDRV_CMD_WRITE;
45   memcpy(&p[2], str, len);
46   kz_send(MSGBOX_ID_CONSOUTPUT, len + 2, p);
47 }
48
49 /*
50  * °Ê²¼¤Î£²¤Ä¤Î´Ø¿ô(send_char(), send_string())¤Ï³ä¹þ¤ß½èÍý¤È¥¹¥ì¥Ã¥É¤«¤é
51  * ¸Æ¤Ð¤ì¤ë¤¬Á÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤΤ¿¤á¡¤¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ó½Ð¤¹
52  * ¾ì¹ç¤ÏÇÓ¾¤Î¤¿¤á³ä¹þ¤ß¶Ø»ß¾õÂ֤ǸƤ֤³¤È¡¥
53  */
54
55 /* Á÷¿®¥Ð¥Ã¥Õ¥¡¤ÎÀèƬ£±Ê¸»ú¤òÁ÷¿®¤¹¤ë */
56 static void send_char(struct consreg *cons)
57 {
58   int i;
59   serial_send_byte(cons->index, cons->send_buf[0]);
60   cons->send_len--;
61   /* ÀèƬʸ»ú¤òÁ÷¿®¤·¤¿¤Î¤Ç¡¤£±Ê¸»ú¤Ö¤ó¤º¤é¤¹ */
62   for (i = 0; i < cons->send_len; i++)
63     cons->send_buf[i] = cons->send_buf[i + 1];
64 }
65
66 /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤ßÁ÷¿®³«»Ï¤¹¤ë */
67 static void send_string(struct consreg *cons, char *str, int len)
68 {
69   int i;
70   for (i = 0; i < len; i++) { /* Ê¸»úÎó¤òÁ÷¿®¥Ð¥Ã¥Õ¥¡¤Ë¥³¥Ô¡¼ */
71     if (str[i] == '\n') /* \n¢ª\r\n¤ËÊÑ´¹ */
72       cons->send_buf[cons->send_len++] = '\r';
73     cons->send_buf[cons->send_len++] = str[i];
74   }
75   /*
76    * Á÷¿®³ä¹þ¤ß̵¸ú¤Ê¤é¤Ð¡¤Á÷¿®³«»Ï¤µ¤ì¤Æ¤¤¤Ê¤¤¤Î¤ÇÁ÷¿®³«»Ï¤¹¤ë¡¥
77    * Á÷¿®³ä¹þ¤ßÍ­¸ú¤Ê¤é¤ÐÁ÷¿®³«»Ï¤µ¤ì¤Æ¤ª¤ê¡¤Á÷¿®³ä¹þ¤ß¤Î±äŤÇ
78    * Á÷¿®¥Ð¥Ã¥Õ¥¡Æâ¤Î¥Ç¡¼¥¿¤¬½ç¼¡Á÷¿®¤µ¤ì¤ë¤Î¤Ç¡¤²¿¤â¤·¤Ê¤¯¤Æ¤è¤¤¡¥
79    */
80   if (cons->send_len && !serial_intr_is_send_enable(cons->index)) {
81     serial_intr_send_enable(cons->index); /* Á÷¿®³ä¹þ¤ßÍ­¸ú²½ */
82     send_char(cons); /* Á÷¿®³«»Ï */
83   }
84 }
85
86 /*
87  * °Ê²¼¤Ï³ä¹þ¤ß¥Ï¥ó¥É¥é¤«¤é¸Æ¤Ð¤ì¤ë³ä¹þ¤ß½èÍý¤Ç¤¢¤ê¡¤ÈóƱ´ü¤Ç
88  * ¸Æ¤Ð¤ì¤ë¤Î¤Ç¡¤¥é¥¤¥Ö¥é¥ê´Ø¿ô¤Ê¤É¤ò¸Æ¤Ó½Ð¤¹¾ì¹ç¤Ë¤ÏÃí°Õ¤¬É¬Íס¥
89  * ´ðËܤȤ·¤Æ¡¤°Ê²¼¤Î¤¤¤º¤ì¤«¤ËÅö¤Æ¤Ï¤Þ¤ë´Ø¿ô¤·¤«¸Æ¤Ó½Ð¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
90  * ¡¦ºÆÆþ²Äǽ¤Ç¤¢¤ë¡¥
91  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤Ï̵¤¤´Ø¿ô¤Ç¤¢¤ë¡¥
92  * ¡¦¥¹¥ì¥Ã¥É¤«¤é¸Æ¤Ð¤ì¤ë¤³¤È¤¬¤¢¤ë¤¬¡¤³ä¹þ¤ß¶Ø»ß¤Ç¸Æ¤Ó½Ð¤·¤Æ¤¤¤ë¡¥
93  * ¤Þ¤¿Èó¥³¥ó¥Æ¥­¥¹¥È¾õÂ֤ǸƤФì¤ë¤¿¤á¡¤¥·¥¹¥Æ¥à¡¦¥³¡¼¥ë¤ÏÍøÍѤ·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
94  * (¥µ¡¼¥Ó¥¹¡¦¥³¡¼¥ë¤òÍøÍѤ¹¤ë¤³¤È)
95  */
96 static int consdrv_intrproc(struct consreg *cons)
97 {
98   unsigned char c;
99   char *p;
100
101   if (serial_is_recv_enable(cons->index)) { /* ¼õ¿®³ä¹þ¤ß */
102       c = serial_recv_byte(cons->index);
103       p = kx_kmalloc(1);
104       p[0] = c;
105       kx_send(MSGBOX_ID_CONSINPUT, 1, p);
106   }
107
108   if (serial_is_send_enable(cons->index)) { /* Á÷¿®³ä¹þ¤ß */
109     if (!cons->id || !cons->send_len) {
110       /* Á÷¿®¥Ç¡¼¥¿¤¬Ìµ¤¤¤Ê¤é¤Ð¡¤Á÷¿®½èÍý½ªÎ» */
111       serial_intr_send_disable(cons->index);
112     } else {
113       /* Á÷¿®¥Ç¡¼¥¿¤¬¤¢¤ë¤Ê¤é¤Ð¡¤°ú³¤­Á÷¿®¤¹¤ë */
114       send_char(cons);
115     }
116   }
117
118   return 0;
119 }
120
121 /* ³ä¹þ¤ß¥Ï¥ó¥É¥é */
122 static void consdrv_intr(void)
123 {
124   int i;
125   struct consreg *cons;
126
127   for (i = 0; i < CONSDRV_DEVICE_NUM; i++) {
128     cons = &consreg[i];
129     if (cons->id) {
130       if (serial_is_send_enable(cons->index) ||
131           serial_is_recv_enable(cons->index))
132         /* ³ä¹þ¤ß¤¬¤¢¤ë¤Ê¤é¤Ð¡¤³ä¹þ¤ß½èÍý¤ò¸Æ¤Ó½Ð¤¹ */
133         consdrv_intrproc(cons);
134     }
135   }
136 }
137
138 static int consdrv_init(void)
139 {
140   memset(consreg, 0, sizeof(consreg));
141   return 0;
142 }
143
144 /* ¥¹¥ì¥Ã¥É¤«¤é¤ÎÍ×µá¤ò½èÍý¤¹¤ë */
145 static int consdrv_command(struct consreg *cons, kz_thread_id_t id,
146     int index, int size, char *command)
147 {
148   switch (command[0]) {
149     case CONSDRV_CMD_USE: /* ¥³¥ó¥½¡¼¥ë¡¦¥É¥é¥¤¥Ð¤Î»ÈÍѳ«»Ï */
150       cons->id = id;
151       cons->index = command[1] - '0';
152       cons->send_buf = kz_kmalloc(CONS_BUFFER_SIZE);
153       cons->send_len = 0;
154       serial_init(cons->index);
155       serial_intr_recv_enable(cons->index); /* ¼õ¿®³ä¹þ¤ßÍ­¸ú²½(¼õ¿®³«»Ï) */
156       break;
157
158     case CONSDRV_CMD_WRITE: /* ¥³¥ó¥½¡¼¥ë¤Ø¤Îʸ»úÎó½ÐÎÏ */
159       /*
160        * send_string()¤Ç¤ÏÁ÷¿®¥Ð¥Ã¥Õ¥¡¤òÁàºî¤·¤Æ¤ª¤êºÆÆþÉԲĤʤΤǡ¤
161        * ÇÓ¾¤Î¤¿¤á¤Ë³ä¹þ¤ß¶Ø»ß¤Ë¤·¤Æ¸Æ¤Ó½Ð¤¹¡¥
162        */
163       INTR_DISABLE;
164       send_string(cons, command + 1, size - 1); /* Ê¸»úÎó¤ÎÁ÷¿® */
165       INTR_ENABLE;
166       break;
167
168     default:
169       break;
170   }
171
172   return 0;
173 }
174
175 int driver_console(int argc, char *argv[])
176 {
177   int size, index;
178   kz_thread_id_t id;
179   char *p;
180
181   consdrv_init();
182   kz_setintr(SOFTVEC_TYPE_SERINTR, consdrv_intr); /* ³ä¹þ¤ß¥Ï¥ó¥É¥éÀßÄê */
183
184   while (1) {
185     id = kz_recv(MSGBOX_ID_CONSOUTPUT, &size, &p);
186     index = p[0] - '0';
187     consdrv_command(&consreg[index], id, index, size - 1, p + 1);
188     kz_kmfree(p);
189   }
190
191   return 0;
192 }