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

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

initial

File size: 11.9 KB
Line 
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 * @(#) $Id: upd72001.c,v 1.4 2003/12/13 06:21:49 hiro Exp $
51 */
52
53/*
54 * μPD72001用 簡易SIOドライバ
55 */
56
57#include <s_services.h>
58#include <upd72001.h>
59
60/*
61 * デバイスレジスタのアクセス間隔時間(nsec単位)
62 *
63 * 200という値にあまり根拠はない.
64 */
65#define UPD72001_DELAY 200
66
67/*
68 * μPD72001のレジスタの番号
69 */
70#define UPD72001_CR0 0x00u /* コントロールレジスタ */
71#define UPD72001_CR1 0x01u
72#define UPD72001_CR2 0x02u
73#define UPD72001_CR3 0x03u
74#define UPD72001_CR4 0x04u
75#define UPD72001_CR5 0x05u
76#define UPD72001_CR10 0x0au
77#define UPD72001_CR12 0x0cu
78#define UPD72001_CR14 0x0eu
79#define UPD72001_CR15 0x0fu
80
81#define UPD72001_SR0 0x00u /* ステータスレジスタ */
82
83/*
84 * コントロールレジスタの設定値
85 */
86#define CR_RESET 0x18u /* ポートリセットコマンド */
87
88#define CR0_EOI 0x38u /* EOI(End of Interrupt)*/
89
90#define CR1_DOWN 0x00u /* å…
91¨å‰²è¾¼ã¿ã‚’禁止 */
92#define CR1_RECV 0x10u /* 受信割込み許可ビット */
93#define CR1_SEND 0x02u /* 送信割込み許可ビット */
94
95#define CR3_DEF 0xc1u /* データ 8bit,受信イネーブル */
96#define CR4_DEF 0x44u /* ストップビット 1bit,パリティなし */
97#define CR5_DEF 0xeau /* データ 8bit,送信イネーブル */
98
99#define CR10_DEF 0x00u /* NRZ */
100#define CR14_DEF 0x07u /* ボーレートジェネレータイネーブル */
101#define CR15_DEF 0x56u /* ボーレートジェネレータ使用 */
102
103#define SR0_RECV 0x01u /* 受信通知ビット */
104#define SR0_SEND 0x04u /* 送信可能ビット */
105
106/*
107 * シリアルI/Oポート初期化ブロックの定義
108 */
109typedef struct sio_port_initialization_block {
110 VP data; /* データレジスタの番地 */
111 VP ctrl; /* コントロールレジスタの番地 */
112
113 UB cr3_def; /* CR3の設定値(受信ビット数)*/
114 UB cr4_def; /* CR4の設定値(ストップビット,パリティ)*/
115 UB cr5_def; /* CR5の設定値(送信ビット数)*/
116 UB brg1_def; /* ボーレート上位の設定値 */
117 UB brg2_def; /* ボーレート下位の設定値 */
118} SIOPINIB;
119
120/*
121 * シリアルI/Oポート管理ブロックの定義
122 */
123struct sio_port_control_block {
124 const SIOPINIB *siopinib; /* シリアルI/Oポート初期化ブロック */
125 VP_INT exinf; /* 拡張情
126å ± */
127 BOOL openflag; /* オープン済みフラグ */
128 UB cr1; /* CR1の設定値(割込み許可)*/
129 BOOL getready; /* 文字を受信した状æ…
130‹ */
131 BOOL putready; /* 文字を送信できる状æ…
132‹ */
133};
134
135/*
136 * シリアルI/Oポート初期化ブロック
137 *
138 * ID = 1 をポートB,ID = 2 をポートAに対応させている.
139 */
140const SIOPINIB siopinib_table[TNUM_SIOP] = {
141 { (VP) TADR_UPD72001_DATAB, (VP) TADR_UPD72001_CTRLB,
142 CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
143#if TNUM_SIOP >= 2
144 { (VP) TADR_UPD72001_DATAA, (VP) TADR_UPD72001_CTRLA,
145 CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
146#endif /* TNUM_SIOP >= 2 */
147};
148
149/*
150 * シリアルI/Oポート管理ブロックのエリア
151 */
152SIOPCB siopcb_table[TNUM_SIOP];
153
154/*
155 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
156 */
157#define INDEX_SIOP(siopid) ((UINT)((siopid) - 1))
158#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
159
160/*
161 * デバイスレジスタへのアクセス関数
162 */
163Inline UB
164upd72001_read_reg(VP addr)
165{
166 UB val;
167
168 val = (UB) upd72001_reb_reg(addr);
169 sil_dly_nse(UPD72001_DELAY);
170 return(val);
171}
172
173Inline void
174upd72001_write_reg(VP addr, UB val)
175{
176 upd72001_wrb_reg(addr, (VB) val);
177 sil_dly_nse(UPD72001_DELAY);
178}
179
180Inline UB
181upd72001_read_ctrl(VP addr, UB reg)
182{
183 upd72001_write_reg(addr, reg);
184 return(upd72001_read_reg(addr));
185}
186
187Inline void
188upd72001_write_ctrl(VP addr, UB reg, UB val)
189{
190 upd72001_write_reg(addr, reg);
191 upd72001_write_reg(addr, val);
192}
193
194Inline void
195upd72001_write_brg(VP addr, UB reg, UB val, UB brg2, UB brg1)
196{
197 upd72001_write_reg(addr, reg);
198 upd72001_write_reg(addr, val);
199 upd72001_write_reg(addr, brg2);
200 upd72001_write_reg(addr, brg1);
201 (void) upd72001_read_reg(addr); /* ダミーリード */
202}
203
204/*
205 * 状æ…
206‹ã®èª­å‡ºã—(SR0の読出し)
207 *
208 * μPD72001は,状æ…
209‹ï¼ˆSR0)を一度読むと受信通知ビットが落ちてしまうた
210 * め,状æ…
211‹ã‚’読み出す関数を設け,シリアルI/Oポート管理ブロック中の
212 * getready に受信通知状æ…
213‹ï¼Œputready に送信可能状æ…
214‹ã‚’保存している(送
215 * 信可能状æ…
216‹ã®ä¿å­˜ã¯ä¸è¦ã‹ã‚‚しれない).
217 * 状æ…
218‹ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’読んでも受信通知ビットが落ちないデバイス(こちらが普
219 * 通と思われる)では,この関数は必
220要ない.
221 */
222static void
223upd72001_get_stat(SIOPCB *siopcb)
224{
225 UB sr0;
226
227 sr0 = upd72001_read_ctrl(siopcb->siopinib->ctrl, UPD72001_SR0);
228 if ((sr0 & SR0_RECV) != 0) {
229 siopcb->getready = TRUE;
230 }
231 if ((sr0 & SR0_SEND) != 0) {
232 siopcb->putready = TRUE;
233 }
234}
235
236/*
237 * 文字を受信できるか?
238 */
239Inline BOOL
240upd72001_getready(SIOPCB *siopcb)
241{
242 upd72001_get_stat(siopcb);
243 return(siopcb->getready);
244}
245
246/*
247 * 文字を送信できるか?
248 */
249Inline BOOL
250upd72001_putready(SIOPCB *siopcb)
251{
252 upd72001_get_stat(siopcb);
253 return(siopcb->putready);
254}
255
256/*
257 * 受信した文字の取出し
258 */
259Inline char
260upd72001_getchar(SIOPCB *siopcb)
261{
262 siopcb->getready = FALSE;
263 return((char) upd72001_read_reg(siopcb->siopinib->data));
264}
265
266/*
267 * 送信する文字の書込み
268 */
269Inline void
270upd72001_putchar(SIOPCB *siopcb, char c)
271{
272 siopcb->putready = FALSE;
273 upd72001_write_reg(siopcb->siopinib->data, (UB) c);
274}
275
276/*
277 * EOI(End Of Interrupt)発行
278 */
279Inline void
280upd72001_eoi()
281{
282 upd72001_write_ctrl((VP) TADR_UPD72001_CTRLA, UPD72001_CR0, CR0_EOI);
283}
284
285/*
286 * SIOドライバの初期化ルーチン
287 */
288void
289upd72001_initialize()
290{
291 SIOPCB *siopcb;
292 UINT i;
293
294 /*
295 * シリアルI/Oポート管理ブロックの初期化
296 */
297 for (siopcb = siopcb_table, i = 0; i < TNUM_SIOP; siopcb++, i++) {
298 siopcb->siopinib = &(siopinib_table[i]);
299 siopcb->openflag = FALSE;
300 }
301}
302
303/*
304 * オープンしているポートがあるか?
305 */
306BOOL
307upd72001_openflag(void)
308{
309#if TNUM_SIOP < 2
310 return(siopcb_table[0].openflag);
311#else /* TNUM_SIOP < 2 */
312 return(siopcb_table[0].openflag || siopcb_table[1].openflag);
313#endif /* TNUM_SIOP < 2 */
314}
315
316/*
317 * シリアルI/Oポートのオープン
318 */
319SIOPCB *
320upd72001_opn_por(ID siopid, VP_INT exinf)
321{
322 SIOPCB *siopcb;
323 const SIOPINIB *siopinib;
324
325 siopcb = get_siopcb(siopid);
326 siopinib = siopcb->siopinib;
327
328 upd72001_write_reg(siopinib->ctrl, CR_RESET);
329 if (!upd72001_openflag()) {
330 upd72001_write_ctrl((VP) TADR_UPD72001_CTRLA,
331 UPD72001_CR2, 0x18);
332 upd72001_write_ctrl((VP) TADR_UPD72001_CTRLB,
333 UPD72001_CR2, 0x00);
334 }
335 siopcb->cr1 = CR1_DOWN;
336 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
337 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR4, siopinib->cr4_def);
338 upd72001_write_brg(siopinib->ctrl, UPD72001_CR12,
339 0x01, siopinib->brg2_def, siopinib->brg1_def);
340 upd72001_write_brg(siopinib->ctrl, UPD72001_CR12,
341 0x02, siopinib->brg2_def, siopinib->brg1_def);
342 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR15, CR15_DEF);
343 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR14, CR14_DEF);
344 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR10, CR10_DEF);
345 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR3, siopinib->cr3_def);
346 upd72001_write_ctrl(siopinib->ctrl, UPD72001_CR5, siopinib->cr5_def);
347 siopcb->exinf = exinf;
348 siopcb->getready = siopcb->putready = FALSE;
349 siopcb->openflag = TRUE;
350 return(siopcb);
351}
352
353/*
354 * シリアルI/Oポートのクローズ
355 */
356void
357upd72001_cls_por(SIOPCB *siopcb)
358{
359 upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, CR1_DOWN);
360 siopcb->openflag = FALSE;
361}
362
363/*
364 * シリアルI/Oポートへの文字送信
365 */
366BOOL
367upd72001_snd_chr(SIOPCB *siopcb, char c)
368{
369 if (upd72001_putready(siopcb)) {
370 upd72001_putchar(siopcb, c);
371 return(TRUE);
372 }
373 return(FALSE);
374}
375
376/*
377 * シリアルI/Oポートからの文字受信
378 */
379INT
380upd72001_rcv_chr(SIOPCB *siopcb)
381{
382 if (upd72001_getready(siopcb)) {
383 return((INT)(UB) upd72001_getchar(siopcb));
384 }
385 return(-1);
386}
387
388/*
389 * シリアルI/Oポートからのコールバックの許可
390 */
391void
392upd72001_ena_cbr(SIOPCB *siopcb, UINT cbrtn)
393{
394 UB cr1_bit = 0;
395
396 switch (cbrtn) {
397 case SIO_ERDY_SND:
398 cr1_bit = CR1_SEND;
399 break;
400 case SIO_ERDY_RCV:
401 cr1_bit = CR1_RECV;
402 break;
403 }
404 siopcb->cr1 |= cr1_bit;
405 upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
406}
407
408/*
409 * シリアルI/Oポートからのコールバックの禁止
410 */
411void
412upd72001_dis_cbr(SIOPCB *siopcb, UINT cbrtn)
413{
414 UB cr1_bit = 0;
415
416 switch (cbrtn) {
417 case SIO_ERDY_SND:
418 cr1_bit = CR1_SEND;
419 break;
420 case SIO_ERDY_RCV:
421 cr1_bit = CR1_RECV;
422 break;
423 }
424 siopcb->cr1 &= ~cr1_bit;
425 upd72001_write_ctrl(siopcb->siopinib->ctrl, UPD72001_CR1, siopcb->cr1);
426}
427
428/*
429 * シリアルI/Oポートに対する割込み処理
430 */
431static void
432upd72001_isr_siop(SIOPCB *siopcb)
433{
434 if ((siopcb->cr1 & CR1_RECV) != 0 && upd72001_getready(siopcb)) {
435 /*
436 * 受信通知コールバックルーチンを呼び出す.
437 */
438 upd72001_ierdy_rcv(siopcb->exinf);
439 }
440 if ((siopcb->cr1 & CR1_SEND) != 0 && upd72001_putready(siopcb)) {
441 /*
442 * 送信可能コールバックルーチンを呼び出す.
443 */
444 upd72001_ierdy_snd(siopcb->exinf);
445 }
446}
447
448/*
449 * SIOの割込みサービスルーチン
450 */
451void
452upd72001_isr()
453{
454 if (siopcb_table[0].openflag) {
455 upd72001_isr_siop(&(siopcb_table[0]));
456 }
457#if TNUM_SIOP >= 2
458 if (siopcb_table[1].openflag) {
459 upd72001_isr_siop(&(siopcb_table[1]));
460 }
461#endif /* TNUM_SIOP >= 2 */
462 upd72001_eoi();
463}
Note: See TracBrowser for help on using the repository browser.