source: rtos_arduino/trunk/asp_1.9.2/pdic/upd72001/upd72001.c@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 12.4 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * @(#) $Id: upd72001.c 2254 2011-10-07 08:28:12Z ertl-hiro $
56 */
57
58/*
59 * μPD72001用 簡易SIOドライバ
60 */
61
62#include <sil.h>
63#include "target_syssvc.h"
64#include "upd72001.h"
65
66/*
67 * デバイスレジスタのアクセス間隔時間(nsec単位)
68 *
69 * 200という値にあまり根拠はない.
70 */
71#define UPD72001_DELAY 200U
72
73/*
74 * μPD72001のレジスタの番号
75 */
76#define UPD72001_CR0 0x00U /* コントロールレジスタ */
77#define UPD72001_CR1 0x01U
78#define UPD72001_CR2 0x02U
79#define UPD72001_CR3 0x03U
80#define UPD72001_CR4 0x04U
81#define UPD72001_CR5 0x05U
82#define UPD72001_CR10 0x0aU
83#define UPD72001_CR12 0x0cU
84#define UPD72001_CR14 0x0eU
85#define UPD72001_CR15 0x0fU
86
87#define UPD72001_SR0 0x00U /* ステータスレジスタ */
88
89/*
90 * コントロールレジスタの設定値
91 */
92#define CR_RESET 0x18U /* ポートリセットコマンド */
93
94#define CR0_EOI 0x38U /* EOI(End of Interrupt)*/
95
96#define CR1_DOWN 0x00U /* å…
97¨å‰²è¾¼ã¿ã‚’禁止 */
98#define CR1_RECV 0x10U /* 受信割込み許可ビット */
99#define CR1_SEND 0x02U /* 送信割込み許可ビット */
100
101#define CR3_DEF 0xc1U /* データ 8bit,受信イネーブル */
102#define CR4_DEF 0x44U /* ストップビット 1bit,パリティなし */
103#define CR5_DEF 0xeaU /* データ 8bit,送信イネーブル */
104
105#define CR10_DEF 0x00U /* NRZ */
106#define CR14_DEF 0x07U /* ボーレートジェネレータイネーブル */
107#define CR15_DEF 0x56U /* ボーレートジェネレータ使用 */
108
109#define SR0_RECV 0x01U /* 受信通知ビット */
110#define SR0_SEND 0x04U /* 送信可能ビット */
111
112/*
113 * シリアルI/Oポート初期化ブロックの定義
114 */
115typedef struct sio_port_initialization_block {
116 void *data; /* データレジスタの番地 */
117 void *ctrl; /* コントロールレジスタの番地 */
118
119 uint8_t cr3_def; /* CR3の設定値(受信ビット数)*/
120 uint8_t cr4_def; /* CR4の設定値(ストップビット,パリティ)*/
121 uint8_t cr5_def; /* CR5の設定値(送信ビット数)*/
122 uint8_t brg1_def; /* ボーレート上位の設定値 */
123 uint8_t brg2_def; /* ボーレート下位の設定値 */
124} SIOPINIB;
125
126/*
127 * シリアルI/Oポート管理ブロックの定義
128 */
129struct sio_port_control_block {
130 const SIOPINIB *p_siopinib; /* シリアルI/Oポート初期化ブロック */
131 intptr_t exinf; /* 拡張情
132å ± */
133 bool_t openflag; /* オープン済みフラグ */
134 uint8_t cr1; /* CR1の設定値(割込み許可)*/
135 bool_t getready; /* 文字を受信した状æ…
136‹ */
137 bool_t putready; /* 文字を送信できる状æ…
138‹ */
139};
140
141/*
142 * シリアルI/Oポート初期化ブロック
143 */
144const SIOPINIB siopinib_table[TNUM_SIOP] = {
145 { (void *) TADR_UPD72001_DATAA, (void *) TADR_UPD72001_CTRLA,
146 CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF },
147 { (void *) TADR_UPD72001_DATAB, (void *) TADR_UPD72001_CTRLB,
148 CR3_DEF, CR4_DEF, CR5_DEF, BRG1_DEF, BRG2_DEF }
149};
150
151/*
152 * シリアルI/Oポート管理ブロックのエリア
153 */
154SIOPCB siopcb_table[TNUM_SIOP];
155
156/*
157 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
158 */
159#define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1))
160#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
161
162/*
163 * デバイスレジスタへのアクセス関数
164 */
165Inline uint8_t
166upd72001_read_reg(void *addr)
167{
168 uint8_t val;
169
170 val = upd72001_reb_reg(addr);
171 sil_dly_nse(UPD72001_DELAY);
172 return(val);
173}
174
175Inline void
176upd72001_write_reg(void *addr, uint8_t val)
177{
178 upd72001_wrb_reg(addr, val);
179 sil_dly_nse(UPD72001_DELAY);
180}
181
182Inline uint8_t
183upd72001_read_ctrl(void *addr, uint8_t reg)
184{
185 upd72001_write_reg(addr, reg);
186 return(upd72001_read_reg(addr));
187}
188
189Inline void
190upd72001_write_ctrl(void *addr, uint8_t reg, uint8_t val)
191{
192 upd72001_write_reg(addr, reg);
193 upd72001_write_reg(addr, val);
194}
195
196Inline void
197upd72001_write_brg(void *addr, uint8_t reg, uint8_t val,
198 uint8_t brg2, uint8_t brg1)
199{
200 upd72001_write_reg(addr, reg);
201 upd72001_write_reg(addr, val);
202 upd72001_write_reg(addr, brg2);
203 upd72001_write_reg(addr, brg1);
204 (void) upd72001_read_reg(addr); /* ダミーリード */
205}
206
207/*
208 * 状æ…
209‹ã®èª­å‡ºã—(SR0の読出し)
210 *
211 * μPD72001は,状æ…
212‹ï¼ˆSR0)を一度読むと受信通知ビットが落ちてしまうた
213 * め,状æ…
214‹ã‚’読み出す関数を設け,シリアルI/Oポート管理ブロック中の
215 * getreadyに受信通知状æ…
216‹ï¼Œputreadyに送信可能状æ…
217‹ã‚’保存している(送信
218 * 可能状æ…
219‹ã®ä¿å­˜ã¯ä¸è¦ã‹ã‚‚しれない).
220 * 状æ…
221‹ãƒ¬ã‚¸ã‚¹ã‚¿ã‚’読んでも受信通知ビットが落ちないデバイス(こちらが普
222 * 通と思われる)では,この関数は必
223要ない.
224 */
225static void
226upd72001_get_stat(SIOPCB *p_siopcb)
227{
228 uint8_t sr0;
229
230 sr0 = upd72001_read_ctrl(p_siopcb->p_siopinib->ctrl, UPD72001_SR0);
231 if ((sr0 & SR0_RECV) != 0) {
232 p_siopcb->getready = true;
233 }
234 if ((sr0 & SR0_SEND) != 0) {
235 p_siopcb->putready = true;
236 }
237}
238
239/*
240 * 文字を受信できるか?
241 */
242Inline bool_t
243upd72001_getready(SIOPCB *p_siopcb)
244{
245 upd72001_get_stat(p_siopcb);
246 return(p_siopcb->getready);
247}
248
249/*
250 * 文字を送信できるか?
251 */
252Inline bool_t
253upd72001_putready(SIOPCB *p_siopcb)
254{
255 upd72001_get_stat(p_siopcb);
256 return(p_siopcb->putready);
257}
258
259/*
260 * 受信した文字の取出し
261 */
262Inline char
263upd72001_getchar(SIOPCB *p_siopcb)
264{
265 p_siopcb->getready = false;
266 return((char) upd72001_read_reg(p_siopcb->p_siopinib->data));
267}
268
269/*
270 * 送信する文字の書込み
271 */
272Inline void
273upd72001_putchar(SIOPCB *p_siopcb, char c)
274{
275 p_siopcb->putready = false;
276 upd72001_write_reg(p_siopcb->p_siopinib->data, (uint8_t) c);
277}
278
279/*
280 * EOI(End Of Interrupt)発行
281 */
282Inline void
283upd72001_eoi(void)
284{
285 upd72001_write_ctrl((void *) TADR_UPD72001_CTRLA, UPD72001_CR0, CR0_EOI);
286}
287
288/*
289 * SIOドライバの初期化
290 */
291void
292upd72001_initialize(void)
293{
294 SIOPCB *p_siopcb;
295 uint_t i;
296
297 /*
298 * シリアルI/Oポート管理ブロックの初期化
299 */
300 for (i = 0; i < TNUM_SIOP; i++) {
301 p_siopcb = &(siopcb_table[i]);
302 p_siopcb->p_siopinib = &(siopinib_table[i]);
303 p_siopcb->openflag = false;
304 }
305}
306
307/*
308 * オープンしているポートがあるか?
309 */
310bool_t
311upd72001_openflag(void)
312{
313 return(siopcb_table[0].openflag || siopcb_table[1].openflag);
314}
315
316/*
317 * シリアルI/Oポートのオープン
318 */
319SIOPCB *
320upd72001_opn_por(ID siopid, intptr_t exinf)
321{
322 SIOPCB *p_siopcb;
323 const SIOPINIB *p_siopinib;
324
325 p_siopcb = get_siopcb(siopid);
326 p_siopinib = p_siopcb->p_siopinib;
327
328 upd72001_write_reg(p_siopinib->ctrl, CR_RESET);
329 if (!upd72001_openflag()) {
330 upd72001_write_ctrl((void *) TADR_UPD72001_CTRLA, UPD72001_CR2, 0x18);
331 upd72001_write_ctrl((void *) TADR_UPD72001_CTRLB, UPD72001_CR2, 0x00);
332 }
333 p_siopcb->cr1 = CR1_DOWN;
334 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR1, p_siopcb->cr1);
335 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR4, p_siopinib->cr4_def);
336 upd72001_write_brg(p_siopinib->ctrl, UPD72001_CR12, 0x01U,
337 p_siopinib->brg2_def, p_siopinib->brg1_def);
338 upd72001_write_brg(p_siopinib->ctrl, UPD72001_CR12, 0x02U,
339 p_siopinib->brg2_def, p_siopinib->brg1_def);
340 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR15, CR15_DEF);
341 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR14, CR14_DEF);
342 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR10, CR10_DEF);
343 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR3, p_siopinib->cr3_def);
344 upd72001_write_ctrl(p_siopinib->ctrl, UPD72001_CR5, p_siopinib->cr5_def);
345 p_siopcb->exinf = exinf;
346 p_siopcb->getready = false;
347 p_siopcb->putready = false;
348 p_siopcb->openflag = true;
349 return(p_siopcb);
350}
351
352/*
353 * シリアルI/Oポートのクローズ
354 */
355void
356upd72001_cls_por(SIOPCB *p_siopcb)
357{
358 upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl, UPD72001_CR1, CR1_DOWN);
359 p_siopcb->openflag = false;
360}
361
362/*
363 * シリアルI/Oポートへの文字送信
364 */
365bool_t
366upd72001_snd_chr(SIOPCB *p_siopcb, char c)
367{
368 if (upd72001_putready(p_siopcb)) {
369 upd72001_putchar(p_siopcb, c);
370 return(true);
371 }
372 return(false);
373}
374
375/*
376 * シリアルI/Oポートからの文字受信
377 */
378int_t
379upd72001_rcv_chr(SIOPCB *p_siopcb)
380{
381 if (upd72001_getready(p_siopcb)) {
382 return((int_t)(uint8_t) upd72001_getchar(p_siopcb));
383 }
384 return(-1);
385}
386
387/*
388 * シリアルI/Oポートからのコールバックの許可
389 */
390void
391upd72001_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
392{
393 uint8_t cr1_bit;
394
395 switch (cbrtn) {
396 case SIO_RDY_SND:
397 cr1_bit = CR1_SEND;
398 break;
399 case SIO_RDY_RCV:
400 cr1_bit = CR1_RECV;
401 break;
402 default:
403 cr1_bit = 0U;
404 break;
405 }
406 p_siopcb->cr1 |= cr1_bit;
407 upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl,
408 UPD72001_CR1, p_siopcb->cr1);
409}
410
411/*
412 * シリアルI/Oポートからのコールバックの禁止
413 */
414void
415upd72001_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
416{
417 uint8_t cr1_bit;
418
419 switch (cbrtn) {
420 case SIO_RDY_SND:
421 cr1_bit = CR1_SEND;
422 break;
423 case SIO_RDY_RCV:
424 cr1_bit = CR1_RECV;
425 break;
426 default:
427 cr1_bit = 0U;
428 break;
429 }
430 p_siopcb->cr1 &= ~cr1_bit;
431 upd72001_write_ctrl(p_siopcb->p_siopinib->ctrl,
432 UPD72001_CR1, p_siopcb->cr1);
433}
434
435/*
436 * シリアルI/Oポートに対する割込み処理
437 */
438static void
439upd72001_isr_siop(SIOPCB *p_siopcb)
440{
441 if ((p_siopcb->cr1 & CR1_RECV) != 0U) {
442 if (upd72001_getready(p_siopcb)) {
443 /*
444 * 受信通知コールバックルーチンを呼び出す.
445 */
446 upd72001_irdy_rcv(p_siopcb->exinf);
447 }
448 }
449 if ((p_siopcb->cr1 & CR1_SEND) != 0U) {
450 if (upd72001_putready(p_siopcb)) {
451 /*
452 * 送信可能コールバックルーチンを呼び出す.
453 */
454 upd72001_irdy_snd(p_siopcb->exinf);
455 }
456 }
457}
458
459/*
460 * SIOの割込みサービスルーチン
461 */
462void
463upd72001_isr(void)
464{
465 if (siopcb_table[0].openflag) {
466 upd72001_isr_siop(&(siopcb_table[0]));
467 }
468 if (siopcb_table[1].openflag) {
469 upd72001_isr_siop(&(siopcb_table[1]));
470 }
471 upd72001_eoi();
472}
Note: See TracBrowser for help on using the repository browser.