OSDN Git Service

82bb8e1cb604c41aa477a1126167158e1366ff71
[trx-305dsp/dsp.git] / hirado / kernel / pdic / simple_sio / fdc37c935a.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
13  *  利用と呼ぶ)することを無償で許諾する.
14  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16  *      スコード中に含まれていること.
17  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20  *      の無保証規定を掲載すること.
21  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23  *      と.
24  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
26  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27  *        報告すること.
28  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30  * 
31  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: fdc37c935a.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39 /*
40  * スーパI/O FDC37C935A 用ドライバ
41  */
42
43 #include <s_services.h>
44 #include <fdc37c935a.h>
45
46 /*
47  *  初期化
48  */
49 void
50 smsc_init(void)
51 {
52     /*
53      * Enter Config mode 
54      */
55     sil_wrh_mem((VP)SMSC_CONFIG_PORT, (0x55 << 8));
56     sil_wrh_mem((VP)SMSC_CONFIG_PORT, (0x55 << 8));
57
58     /*
59      * Init SCI0
60      */
61     /* Power on */
62     smsc_config_write(0x22, (smsc_config_read(0x22) | 0x10));
63     /* Select SCI0 */
64     smsc_config_write(0x07, 0x04);
65     /* Enable SCI0 */
66     smsc_config_write(0x30, 0x01);
67     /* Set SCI0 Base Address */
68     smsc_config_write(0x60, (SMSC_SCI0_BASE_ADDR & 0xff00) >> 8);
69     smsc_config_write(0x61, (SMSC_SCI0_BASE_ADDR & 0xff));    
70     /* IRQ4 */
71     smsc_config_write(0x70, 0x04);
72     
73
74     /*
75      *  Exit Config mode
76      */
77     sil_wrh_mem((VP)SMSC_CONFIG_PORT, (0xAA << 8));
78 }
79
80
81 /*
82  *  スーパーI/O(FDC37C935A)用 簡易SIOドライバ
83  */
84
85 /*
86  *  シリアルI/Oポート初期化ブロック
87  */
88 typedef struct sio_port_initialization_block {
89
90 } SIOPINIB;
91
92 /*
93  *  シリアルI/Oポート管理ブロック
94  */
95 struct sio_port_control_block {
96     const SIOPINIB  *siopinib;  /* シリアルI/Oポート初期化ブロック */
97     VP_INT          exinf;      /* 拡張情報 */
98     BOOL    openflag;           /* オープン済みフラグ */
99     BOOL    sendflag;           /* 送信割込みイネーブルフラグ */
100     BOOL    getready;           /* 文字を受信した状態 */
101     BOOL    putready;           /* 文字を送信できる状態 */
102 };
103
104 /*
105  * シリアルI/Oポート初期化ブロック
106  */
107 const SIOPINIB siopinib_table[TNUM_SIOP] = {{}};
108
109 /*
110  *  シリアルI/Oポート管理ブロックのエリア
111  */
112 SIOPCB  siopcb_table[TNUM_SIOP];
113
114
115 /*
116  *  シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
117  */
118 #define INDEX_SIOP(siopid)  ((UINT)((siopid) - 1))
119 #define get_siopcb(siopid)  (&(siopcb_table[INDEX_SIOP(siopid)]))
120
121
122 /*
123  * 文字を受信したか?
124  */ 
125 Inline BOOL
126 smsc_sci0_getready(SIOPCB *siopcb)
127 {
128     return(((sil_reh_mem((VP)SMSC_SCI0_LSR) >> 8) & 0x01) != 0);
129 }
130
131 /*
132  * 文字を送信できるか?
133  */
134 Inline BOOL
135 smsc_sci0_putready(SIOPCB *siopcb)
136 {
137     return(((sil_reh_mem((VP)SMSC_SCI0_LSR) >> 8) & 0x60) != 0);
138 }
139
140 /*
141  *  受信した文字の取り出し
142  */
143 Inline char
144 smsc_sci0_getchar(SIOPCB *siopcb)
145 {
146     return (sil_reh_mem((VP)SMSC_SCI0_RBR) >> 8);
147 }
148
149 /*
150  *  送信する文字の書き込み
151  */
152 Inline void
153 smsc_sci0_putchar(SIOPCB *siopcb, char c)
154 {
155     sil_wrh_mem((VP)SMSC_SCI0_THR, c << 8);
156 }
157
158 /*
159  *  送信割込み許可
160  */
161 Inline void
162 smsc_sci0_enable_send(SIOPCB *siopcb)
163 {
164
165     sil_wrh_mem((VP)SMSC_SCI0_IER,
166                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) | 0x02) << 8));   
167 }
168
169 /*
170  *  送信割込み禁止
171  */
172 Inline void
173 smsc_sci0_disable_send(SIOPCB *siopcb)
174 {
175     sil_wrh_mem((VP)SMSC_SCI0_IER,
176                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) & ~0x02) << 8));   
177 }
178
179 /*
180  *  受信割込み許可
181  */
182 Inline void
183 smsc_sci0_enable_rcv(SIOPCB *siopcb)
184 {
185
186     sil_wrh_mem((VP)SMSC_SCI0_IER,
187                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) | 0x01) << 8));   
188 }
189
190 /*
191  *  受信割込み禁止
192  */
193 Inline void
194 smsc_sci0_disable_rcv(SIOPCB *siopcb)
195 {
196     sil_wrh_mem((VP)SMSC_SCI0_IER,
197                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) & ~0x01) << 8));   
198 }
199
200
201
202
203
204 /*
205  *  SIOドライバの初期化ルーチン
206  *  1ポートしかないため,あまり意味はない
207  */
208 void
209 smsc_sci0_initialize()
210 {
211     SIOPCB  *siopcb;
212     UINT    i;
213
214     /*
215      *  シリアルI/Oポート管理ブロックの初期化
216      */
217     for (siopcb = siopcb_table, i = 0; i < TNUM_SIOP; siopcb++, i++) {
218         siopcb->siopinib = &(siopinib_table[i]);
219         siopcb->openflag = FALSE;
220         siopcb->sendflag = FALSE;
221     }
222 }
223
224 /*
225  *  割込み以外の初期化
226  */
227 void
228 fdc37c935a_init(void)
229 {
230     volatile UH dummy;
231     
232     /* BIT7 = 1 */
233     sil_wrh_mem((VP)SMSC_SCI0_LCR, 0x83 << 8);
234
235     /* Set BPS */
236     sil_wrh_mem((VP)SMSC_SCI0_DLL, ((SMSC_SCI0_BPS & 0x00ff) << 8));   
237     sil_wrh_mem((VP)SMSC_SCI0_DLM, ((SMSC_SCI0_BPS >> 8) << 8));
238
239     /* BIT7 = 0 Divisor Latch BIT6 = 0 No Break : BIT3 = 0 NoParity
240        : BIT2 = 0 1Stopbit : BIT1,0 = {1.1} 8bitData */    
241     sil_wrh_mem((VP)SMSC_SCI0_LCR, 0x03 << 8);
242
243     /* Do not use FIFO */
244     sil_wrh_mem((VP)SMSC_SCI0_FCR, 0x0000);
245
246     /* Clear Status */
247     dummy = sil_reh_mem((VP)SMSC_SCI0_RBR);
248     dummy = sil_reh_mem((VP)SMSC_SCI0_LSR);    
249 }
250
251 /*
252  * オープンしているポートがあるか
253  */
254 BOOL
255 smsc_sci0_openflag(void)
256 {
257     return(siopcb_table[0].openflag);
258 }
259
260 /*
261  * シリアルI/Oポートのオープン
262  */
263 SIOPCB *
264 smsc_sci0_opn_por(ID siopid, VP_INT exinf)
265 {
266     SIOPCB      *siopcb;
267     const SIOPINIB  *siopinib;
268
269
270     siopcb = get_siopcb(siopid);
271     siopinib = siopcb->siopinib;
272
273     fdc37c935a_init();
274         
275     /* Enable Receive Data Interrupt */
276     sil_wrh_mem((VP)SMSC_SCI0_IER, (0x01 << 8));
277     sil_wrh_mem((VP)SMSC_SCI0_MCR, 0x08 << 8);
278
279     /*
280      * MS7729RSE01では,一度送信割込みを発生させておかないと割込み
281      * レベル16の割込みが発生してしまい正しく動作しない.
282      */
283     /* 送信割り込み要求を許可 */
284     sil_wrh_mem((VP)SMSC_SCI0_IER,
285                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) | 0x02) << 8));   
286     /* 送信割り込み要求を禁止 */        
287     sil_wrh_mem((VP)SMSC_SCI0_IER,
288                 (((sil_reh_mem((VP)SMSC_SCI0_IER) >> 8) & ~0x02) << 8));   
289
290     siopcb->exinf = exinf;
291     siopcb->getready = siopcb->putready = FALSE;
292     siopcb->openflag = TRUE;
293
294     return(siopcb);
295 }
296
297 /*
298  *  シリアルI/Oポートのクローズ
299  */
300 void
301 smsc_sci0_cls_por(SIOPCB *siopcb)
302 {
303     sil_wrh_mem((VP)SMSC_SCI0_IER, 0x00);      /* 割込みの禁止 */
304     siopcb->openflag = FALSE;
305 }
306
307 /*
308  * シリアルI/Oポートへのポーリングでの出力
309  */
310 void
311 fdc37c935a_pol_putc(char c)
312 {
313     while(((sil_reh_mem((VP)SMSC_SCI0_LSR) >> 8) & 0x60) == 0)
314         ;
315
316     sil_wrh_mem((VP)SMSC_SCI0_THR, c << 8);
317 }
318
319 /*
320  *  シリアルI/Oポートへの文字送信
321  */
322 BOOL
323 smsc_sci0_snd_chr(SIOPCB *siopcb, char c)
324 {
325     if (smsc_sci0_putready(siopcb)){
326         smsc_sci0_putchar(siopcb, c);
327         return(TRUE);
328     }
329     return(FALSE);
330 }
331
332 /*
333  *  シリアルI/Oポートからの文字受信
334  */
335 INT
336 smsc_sci0_rcv_chr(SIOPCB *siopcb)
337 {
338     if (smsc_sci0_getready(siopcb)) {
339         return((INT)(UB) smsc_sci0_getchar(siopcb));
340     }
341     return(-1);
342 }
343
344
345 /*
346  *  シリアルI/Oポートからのコールバックの許可
347  */
348 void
349 smsc_sci0_ena_cbr(SIOPCB *siopcb, UINT cbrtn)
350 {
351
352     switch (cbrtn) {
353         case SIO_ERDY_SND:
354             smsc_sci0_enable_send(siopcb);
355             break;
356         case SIO_ERDY_RCV:
357             smsc_sci0_enable_rcv(siopcb);
358             break;
359     }
360 }
361
362 /*
363  *  シリアルI/Oポートからのコールバックの禁止
364  */
365 void
366 smsc_sci0_dis_cbr(SIOPCB *siopcb, UINT cbrtn)
367 {
368     switch (cbrtn) {
369         case SIO_ERDY_SND:
370             smsc_sci0_disable_send(siopcb);
371             break;
372         case SIO_ERDY_RCV:
373             smsc_sci0_disable_rcv(siopcb);
374             break;
375     }
376 }
377
378 /*
379  *  シリアルI/Oポートに対する割込み処理
380  */
381 static void
382 smsc_sci0_isr_siop(SIOPCB *siopcb)
383 {
384     if (smsc_sci0_getready(siopcb)) {
385         /*
386          *  受信通知コールバックルーチンを呼び出す.
387          */
388         smsc_sci0_ierdy_rcv(siopcb->exinf);
389     }
390     if (smsc_sci0_putready(siopcb)) {
391         /*
392          *  送信可能コールバックルーチンを呼び出す.
393          */
394         smsc_sci0_ierdy_snd(siopcb->exinf);
395     }
396 }
397
398 /*
399  *  SIOの割込みサービスルーチン
400  */
401 void
402 smsc_sci0_isr()
403 {
404     smsc_sci0_isr_siop(&(siopcb_table[0]));
405 }