source: anotherchoice/tags/jsp-1.4.4-full-UTF8/pdic/simple_sio/lpc2388uart.c@ 26

Last change on this file since 26 was 26, checked in by ykominami, 12 years ago

initial

File size: 16.6 KB
RevLine 
[26]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 * 上記著作権者
10は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によってå…
12¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
16 * 利用と呼ぶ)することを無償で許諾する.
17 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
18 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * スコード中に含まれていること.
20 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
21 * 用できる形で再é…
22å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
23å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
24 * 者
25マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 * の無保証規定を掲載すること.
27 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28 * 用できない形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
30 * と.
31 * (a) 再é…
32å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
33マニュアルなど)に,上記の著
34 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
35 * (b) 再é…
36å¸ƒã®å½¢æ…
37‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
38 * 報告すること.
39 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
40 * 害からも,上記著作権者
41およびTOPPERSプロジェクトをå…
42è²¬ã™ã‚‹ã“と.
43 *
44 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
45お
46 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
47 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
48 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
49 *
50 */
51
52/*
53 * CQ-FRK-NXP-ARM UART用 簡易SIOドライバ
54 *
55 * このファイルは、TOPPERS/JSP 1.4.2の pdic/simple_sio/st16c2550.cを
56 * リネームし、内
57部の識別子を変更したものである。
58 */
59#include <s_services.h>
60#include "lpc2388uart.h"
61
62/*
63 * 8250, 16450, 16550各レジスタのアドレス・オフセット。UART_RHRを基点とする。
64 * システムごとに異なるのでUART_BOUNDARYによってレジスタのé…
65ç½®å¢ƒç•Œã‚’指定する。
66 * たとえばすべてのレジスタが8ビット境界でé…
67ç½®ã•ã‚Œã¦ã„るなら、UART_BOUNDARYは1,
68 * 16bit境界なら2, 32ビット境界なら4を指定する。
69 * UART_BOUNDARYはsys_config.hで定義する。
70 */
71
72
73#define UART_RBR (0x00 * UART_BOUNDARY) /* 受信バッファレジスタ */
74#define UART_THR (0x00 * UART_BOUNDARY) /* 送信データ・ホールド・レジスタ */
75#define UART_DLL (0x00 * UART_BOUNDARY) /* 分周レジスタ下位バイト */
76#define UART_IER (0x01 * UART_BOUNDARY) /* 割込みイネーブルレジスタ */
77#define UART_DLM (0x01 * UART_BOUNDARY) /* 分周レジスタ上位バイト */
78#define UART_IIR (0x02 * UART_BOUNDARY) /* 割込み識別レジスタ */
79#define UART_FCR (0x02 * UART_BOUNDARY) /* FIFO制御レジスタ */
80#define UART_LCR (0x03 * UART_BOUNDARY) /* ライン制御レジスタ */
81#define UART_MCR (0x04 * UART_BOUNDARY) /* モデム制御レジスタ */
82#define UART_LSR (0x05 * UART_BOUNDARY) /* ライン・ステータス・レジスタ */
83#define UART_MSR (0x06 * UART_BOUNDARY) /* モデム・ステータス・レジスタ */
84#define UART_SCR (0x07 * UART_BOUNDARY) /* スクラッチ・パッド・レジスタ */
85#define UART_GCTL (0x09 * UART_BOUNDARY) /* Blackfinのみ。グローバル制御レジスタ */
86
87/*
88 * レジスタのビットマスク。特殊機能を追加しない限り、書き換えなくてよい。
89 */
90
91#define ISR_TX 0x02 /* 送信割り込み発生 */
92#define IER_TX 0x02 /* 送信割り込み許可 */
93#define ISR_RX 0x01 /* 受信割り込み発生 */
94#define IER_RX 0x01 /* 受信割り込み許可 */
95
96#define LCR_DL_MODE 0x80 /* Divisor Enable */
97#define LCR_NP_8_1 0x03 /* 8bit,1stop,Noparity,No break */
98#define FCR_FIFO_DISABLE 0x00
99
100#define LSR_RX_DATA_READY 0x01
101#define LSR_TX_EMPTY 0x20
102
103#define MCR_INT_ENABLE 0x08
104
105#define GCTL_UCEN 0x01 /* Blackfinのみ */
106
107
108/*
109 * TNUM_SIOP_UART, UART0_ADDRESS, UART0_DIVISOR はsys_config.hで定義する。
110 * TNUM_SIOP_UART : PDICが管理するUARTの個数
111 * 以下、PDICが管理する最初のUARTの情
112å ±
113 * UART0_ADDRESS : THRのアドレス
114 * UART0_DIVISOR : DLM, DLLの初期値(16bit表記)
115 * UART0_14550_FIFO : 14550互換のFIFOを持つときにマクロを宣言する
116 * UART0_BLACKFIN_UCEN : Blackfin専用。マクロを宣言すると初期化コードがUART_GCTLのUCENを1にする。
117 * 二つ目以降のUARTがあるなら以下のように続ける。
118 * UART1_ADDRESS : THRのアドレス
119 * UART1_DIVISOR : DLM, DLLの初期値(16bit表記)
120 * UART1_14550_FIFO : 14550互換のFIFOを持つときにマクロを宣言する
121 * UART1_BLACKFIN_UCEN : Blackfin専用。マクロを宣言すると初期化コードがUART_GCTLのUCENを1にする。
122 * ...
123 */
124
125
126/******************************************************************************************
127 * シリアルI/Oポート初期化ブロック
128 */
129#if TNUM_SIOP_UART == 0
130#error "If you don't use UART, please remove this file from your make file"
131#endif
132
133#if TNUM_SIOP_UART > 3
134#error "Only TNUM_SIOP_UART < 4 is supported"
135#endif /* TNUM_SIOP_UART >= 2 */
136
137/* ディバイザ計算マクロ */
138#define DLM(divisor) (divisor/256)
139#define DLL(divisor) (divisor%256)
140
141const SIOPINIB siopinib_table[TNUM_SIOP_UART] = {
142/*-----------------------------------------------------------------
143 * PDICが管理する最初のUARTの初期化パラメータ
144 */
145 {UART0_ADDRESS, DLM(UART0_DIVISOR), DLL(UART0_DIVISOR),
146#ifdef UART0_BLACKFIN_UCEN
147 1 /* マクロUART0_BLACKFIN_UCENが定義されていたら、GCTLのUCENを1にしてクロックを動かす */
148#else
149 0
150#endif
151 }
152
153/*-----------------------------------------------------------------
154 * PDICが管理する2番目のUARTの初期化パラメータ
155 */
156
157#if TNUM_SIOP_UART > 1
158 ,{UART1_ADDRESS, DLM(UART1_DIVISOR), DLL(UART1_DIVISOR),
159#ifdef UART1_BLACKFIN_UCEN
160 1 /* マクロUART1_BLACKFIN_UCENが定義されていたら、GCTLのUCENを1にしてクロックを動かす */
161#else
162 0
163#endif
164
165
166 }
167#endif /* if TNUM_SIOP_UART > 1*/
168
169/*-----------------------------------------------------------------
170 * PDICが管理する3番目のUARTの初期化パラメータ
171 */
172#if TNUM_SIOP_UART > 2
173 ,{UART2_ADDRESS, DLM(UART2_DIVISOR), DLL(UART2_DIVISOR),
174#ifdef UART2_BLACKFIN_UCEN
175 1 /* マクロUART2_BLACKFIN_UCENが定義されていたら、GCTLのUCENを1にしてクロックを動かす */
176#else
177 0
178#endif
179
180
181 }
182#endif /* if TNUM_SIOP_UART > 2*/
183
184};
185
186/*
187 * シリアルI/Oポート初期化ブロックここまで。
188 ******************************************************************************************/
189
190
191
192/*
193 * シリアルI/Oポート初期化ブロックの取出し
194 */
195#define INDEX_SIOPINIB(siopid) ((UINT)((siopid) - 1))
196#define get_siopinib(siopid) (&(siopinib_table[INDEX_SIOPINIB(siopid)]))
197
198
199/*
200 * シリアルI/Oポート管理ブロックのエリア
201 */
202SIOPCB siopcb_table[TNUM_SIOP_UART];
203
204/*
205 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
206 */
207#define INDEX_SIOP(siopid) ((UINT)((siopid) - 1))
208#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
209
210Inline void
211uart_write(UW addr, UW offset, UB val)
212{
213#ifdef UART_IOP_ACCESS
214 sil_wrb_iop((VP)(addr + offset),val);
215#else
216 sil_wrb_mem((VP)(addr + offset),val);
217#endif
218}
219
220Inline UB
221uart_read(UW addr, UW offset)
222{
223#ifdef UART_IOP_ACCESS
224 return(sil_reb_iop((VP)(addr + offset)));
225#else
226 return(sil_reb_mem((VP)(addr + offset)));
227#endif
228}
229
230
231/*
232 * 文字を受信したか?
233 */
234Inline BOOL
235uart_getready(SIOPCB *siopcb)
236{
237 UH status;
238
239 status = uart_read(siopcb->siopinib->reg_base, UART_LSR);
240
241 return((status & LSR_RX_DATA_READY));
242}
243
244/*
245 * 文字を送信できるか?
246 */
247Inline BOOL
248uart_putready(SIOPCB *siopcb)
249{
250 UH status;
251
252 status = uart_read(siopcb->siopinib->reg_base, UART_LSR);
253
254 return (status & LSR_TX_EMPTY);
255}
256
257/*
258 * 受信した文字の取り出し
259 */
260Inline UB
261uart_getchar(SIOPCB *siopcb)
262{
263 return(uart_read(siopcb->siopinib->reg_base,UART_RBR));
264}
265
266/*
267 * 送信する文字の書き込み
268 */
269Inline void
270uart_putchar(SIOPCB *siopcb, UB c)
271{
272 uart_write(siopcb->siopinib->reg_base, UART_THR, c);
273}
274
275/*
276 * 送信割込み許可
277 */
278Inline void
279uart_enable_send(SIOPCB *siopcb)
280{
281 uart_write(siopcb->siopinib->reg_base, UART_IER,
282 (uart_read(siopcb->siopinib->reg_base,UART_IER) | IER_TX));
283}
284
285/*
286 * 送信割込み禁止
287 */
288Inline void
289uart_disable_send(SIOPCB *siopcb)
290{
291 uart_write(siopcb->siopinib->reg_base, UART_IER,
292 (uart_read(siopcb->siopinib->reg_base, UART_IER) & ~IER_TX));
293
294}
295
296/*
297 * 受信割込み許可
298 */
299Inline void
300uart_enable_rcv(SIOPCB *siopcb)
301{
302 uart_write(siopcb->siopinib->reg_base, UART_IER,
303 (uart_read(siopcb->siopinib->reg_base,UART_IER) | IER_RX));
304}
305
306/*
307 * 受信割込み禁止
308 */
309Inline void
310uart_disable_rcv(SIOPCB *siopcb)
311{
312 uart_write(siopcb->siopinib->reg_base, UART_IER,
313 (uart_read(siopcb->siopinib->reg_base, UART_IER) & ~IER_RX));
314
315}
316
317
318/*
319 * SIOドライバの初期化ルーチン
320 */
321void
322uart_initialize()
323{
324 SIOPCB *siopcb;
325 UINT i;
326
327 /*
328 * シリアルI/Oポート管理ブロックの初期化
329 */
330 for (siopcb = siopcb_table, i = 0; i < TNUM_SIOP_UART; siopcb++, i++) {
331 siopcb->siopinib = &(siopinib_table[i]);
332 siopcb->openflag = FALSE;
333 siopcb->sendflag = FALSE;
334 }
335}
336
337
338/*
339 *
340 */
341void
342uart_init_siopinib(const SIOPINIB *siopinib)
343{
344
345 /*
346 * Blackfin ADSP-BF531/2/3, BF534/6/7, BF561の内
347蔵UARTに固有の作業。
348 * Power Downモードの解除。
349 */
350 if ( siopinib->set_ucen )
351 uart_write(siopinib->reg_base, UART_GCTL,
352 (uart_read(siopinib->reg_base, UART_GCTL) | GCTL_UCEN ));
353 /*
354 * 分周比の設定
355 */
356 /* Divisor Enable */
357 uart_write(siopinib->reg_base, UART_LCR,
358 (uart_read(siopinib->reg_base, UART_LCR) | LCR_DL_MODE));
359 uart_write(siopinib->reg_base, UART_DLL, siopinib->dll_val);
360 uart_write(siopinib->reg_base, UART_DLM, siopinib->dlm_val);
361 /* Divisor Disable */
362 uart_write(siopinib->reg_base, UART_LCR,
363 (uart_read(siopinib->reg_base, UART_LCR) & ~LCR_DL_MODE));
364
365 /* モード設定, パリティ無し 8bit data, 1 stop bit */
366 uart_write(siopinib->reg_base, UART_LCR, LCR_NP_8_1);
367
368 /* 割込み禁止 */
369 uart_write(siopinib->reg_base, UART_IER, 0x00);
370}
371
372
373/*
374 * カーネル起動時のバナー出力用の初期化
375 */
376void
377uart_init(void)
378{
379 int i;
380 /*
381 * すべてのuartを初期化する。id は1からTNUM_SIOP_UARTまで。
382 */
383 for ( i=1; i<=TNUM_SIOP_UART; i++ )
384 uart_init_siopinib(get_siopinib(i));
385}
386
387/*
388 * オープンしているポートがあるか
389 */
390BOOL
391uart_openflag(void)
392{
393 int i;
394
395 /*
396 * 開いているポートがあれば0を返す。なければ0を返す。
397 */
398 for ( i=0; i<TNUM_SIOP_UART; i++ )
399 if (siopcb_table[0].openflag)
400 return( 1 );
401 return( 0 );
402}
403
404
405/*
406 * シリアルI/Oポートのオープン
407 */
408SIOPCB *
409uart_opn_por(ID siopid, VP_INT exinf)
410{
411 SIOPCB *siopcb;
412 const SIOPINIB *siopinib;
413
414 siopcb = get_siopcb(siopid);
415 siopinib = siopcb->siopinib;
416
417 /*
418 * 初期化
419 */
420 uart_init_siopinib(siopcb->siopinib);
421
422 /* 受信割込み許可 */
423 uart_write(siopcb->siopinib->reg_base, UART_IER, IER_RX);
424
425 /* 割込み線をイネーブル */
426 uart_write(siopcb->siopinib->reg_base, UART_MCR, MCR_INT_ENABLE);
427
428 siopcb->exinf = exinf;
429 siopcb->getready = siopcb->putready = FALSE;
430 siopcb->openflag = TRUE;
431
432 return(siopcb);
433}
434
435/*
436 * シリアルI/Oポートのクローズ
437 */
438void
439uart_cls_por(SIOPCB *siopcb)
440{
441 /* 割込み禁止 */
442 uart_write(siopcb->siopinib->reg_base, UART_IER, 0x00);
443 siopcb->openflag = FALSE;
444}
445
446
447/*
448 * シリアルI/Oポートへのポーリングでの出力
449 */
450void
451uart_pol_putc(char c, ID siopid)
452{
453 const SIOPINIB *siopinib;
454
455 siopinib = get_siopinib(siopid);
456
457 while((uart_read(siopinib->reg_base, UART_LSR) & LSR_TX_EMPTY)
458 != LSR_TX_EMPTY)
459 ;
460 uart_write(siopinib->reg_base, UART_THR, c);
461}
462
463
464/*
465 * シリアルI/Oポートへの文字送信
466 */
467BOOL
468uart_snd_chr(SIOPCB *siopcb, char c)
469{
470 if (uart_putready(siopcb)){
471 uart_putchar(siopcb, c);
472 return(TRUE);
473 }
474 return(FALSE);
475}
476
477/*
478 * シリアルI/Oポートからの文字受信
479 */
480INT
481uart_rcv_chr(SIOPCB *siopcb)
482{
483 if (uart_getready(siopcb)) {
484 return((INT)(UB) uart_getchar(siopcb));
485 }
486 return(-1);
487}
488
489
490
491
492
493/*
494 * シリアルI/Oポートからのコールバックの許可
495 */
496void
497uart_ena_cbr(SIOPCB *siopcb, UINT cbrtn)
498{
499
500 switch (cbrtn) {
501 case SIO_ERDY_SND:
502 uart_enable_send(siopcb);
503 break;
504 case SIO_ERDY_RCV:
505 uart_enable_rcv(siopcb);
506 break;
507 }
508}
509
510/*
511 * シリアルI/Oポートからのコールバックの禁止
512 */
513void
514uart_dis_cbr(SIOPCB *siopcb, UINT cbrtn)
515{
516 switch (cbrtn) {
517 case SIO_ERDY_SND:
518 uart_disable_send(siopcb);
519 break;
520 case SIO_ERDY_RCV:
521 uart_disable_rcv(siopcb);
522 break;
523 }
524}
525
526/*
527 * シリアルI/Oポートに対する割込み処理
528 */
529static void
530uart_rx_isr_siop(SIOPCB *siopcb)
531{
532 if (uart_getready(siopcb)) {
533 /*
534 * 受信通知コールバックルーチンを呼び出す.
535 */
536 uart_ierdy_rcv(siopcb->exinf);
537 }
538}
539
540static void
541uart_tx_isr_siop(SIOPCB *siopcb)
542{
543 if (uart_putready(siopcb)) {
544 /*
545 * 送信可能コールバックルーチンを呼び出す.
546 */
547 uart_ierdy_snd(siopcb->exinf);
548 }
549}
550
551/*
552 * SIOの割込みサービスルーチン
553 * ADSP-BF533の内
554蔵UARTは送受に別々
555の割込み要求を出すため、
556 * ISRも分けている。また、ADSP-BF537のように二つ以上の
557 * UARTを持つ場合を考æ…
558®ã—て、uart0のようにポート番号を
559 * 名前にハードコードしている。
560 * ただし、このポート番号とは、SIOのポート番号であって、
561 * ハードウェアのUART番号と同じだとは限らない。
562 */
563
564/*
565 ***** UART0
566 */
567void
568uart0_rx_isr()
569{
570 /* 下位の受信処理を呼ぶ */
571 uart_rx_isr_siop(&(siopcb_table[0]));
572}
573
574void
575uart0_tx_isr()
576{
577 /* 下位の送信処理を呼ぶ */
578 uart_tx_isr_siop(&(siopcb_table[0]));
579}
580
581/*
582 ***** UART1
583 */
584void
585uart1_rx_isr()
586{
587 /* 下位の受信処理を呼ぶ */
588 uart_rx_isr_siop(&(siopcb_table[1]));
589}
590
591void
592uart1_tx_isr()
593{
594 /* 下位の送信処理を呼ぶ */
595 uart_tx_isr_siop(&(siopcb_table[1]));
596}
597
598/*
599 ***** UART2
600 */
601void
602uart2_rx_isr()
603{
604 /* 下位の受信処理を呼ぶ */
605 uart_rx_isr_siop(&(siopcb_table[2]));
606}
607
608void
609uart2_tx_isr()
610{
611 /* 下位の送信処理を呼ぶ */
612 uart_tx_isr_siop(&(siopcb_table[2]));
613}
614
615
616
617
618
619/*
620 * UARTの送受で割込みをå…
621±æœ‰ã™ã‚‹å ´åˆï¼ˆã“ちらのほうが一般的)は、
622 * 上のルーチンではなくこちらを割込みサービスルーチンとして使う。
623 */
624void
625uart0_isr()
626{
627 /* 下位の受信処理を呼ぶ */
628 uart_rx_isr_siop(&(siopcb_table[0]));
629 /* 下位の送信処理を呼ぶ */
630 uart_tx_isr_siop(&(siopcb_table[0]));
631}
632
633void
634uart1_isr()
635{
636 /* 下位の受信処理を呼ぶ */
637 uart_rx_isr_siop(&(siopcb_table[1]));
638 /* 下位の送信処理を呼ぶ */
639 uart_tx_isr_siop(&(siopcb_table[1]));
640}
641
642void
643uart2_isr()
644{
645 /* 下位の受信処理を呼ぶ */
646 uart_rx_isr_siop(&(siopcb_table[2]));
647 /* 下位の送信処理を呼ぶ */
648 uart_tx_isr_siop(&(siopcb_table[2]));
649}
Note: See TracBrowser for help on using the repository browser.