source: rubycfg_asp/trunk/asp_dcre/pdic/rx600/rx630_uart.c@ 313

Last change on this file since 313 was 313, checked in by coas-nagasima, 7 years ago

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 13.6 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) 2008-2010 by Witz Corporation, JAPAN
7 * Copyright (C) 2013 by Mitsuhiro Matsuura
8 *
9 * 上記著作権者
10は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再é…
19å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
20å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
21 * 者
22マニュアルなど)に,上記の著作権表示,この利用条件および下記
23 * の無保証規定を掲載すること.
24 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
25 * 用できない形で再é…
26å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
27 * と.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (b) 再é…
33å¸ƒã®å½¢æ…
34‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
35 * 報告すること.
36 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37 * 害からも,上記著作権者
38およびTOPPERSプロジェクトをå…
39è²¬ã™ã‚‹ã“と.
40 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
41 * 由に基づく請求からも,上記著作権者
42およびTOPPERSプロジェクトを
43 * å…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51 * の責任を負わない.
52 *
53 * @(#) $Id: rx630_uart.c 313 2017-07-23 04:50:32Z coas-nagasima $
54 */
55
56
57/*
58 * UART用 簡易SIOドライバ
59 */
60
61#include <sil.h>
62#include <kernel.h>
63#include <t_syslog.h>
64#include "target_syssvc.h"
65#include "rx630_uart.h"
66
67/* シリアルモードレジスタ(SMR) */
68#define CKS UINT_C(0x03)
69#define STOP UINT_C(0x08)
70#define PM UINT_C(0x10)
71#define PE UINT_C(0x20)
72#define CHR UINT_C(0x40)
73#define CM UINT_C(0x80)
74#define ASYNC_7BIT UINT_C(0x00)
75#define ASYNC_8BIT UINT_C(0x40)
76
77/* シリアルコントロールレジスタ(SCR) */
78#define CKE UINT_C(0x03)
79#define TEIE UINT_C(0x04)
80#define RE UINT_C(0x10)
81#define TE UINT_C(0x20)
82#define RIE UINT_C(0x40)
83#define TIE UINT_C(0x80)
84
85/* シリアルステータスレジスタ(SSR) */
86#define TEND UINT_C(0x04)
87#define PER UINT_C(0x08)
88#define FER UINT_C(0x10)
89#define ORER UINT_C(0x20)
90
91/* シリアル拡張モードレジスタ(SEMR) */
92#define ACS0 UINT_C(0x01)
93#define ABCS UINT_C(0x10)
94
95#define SCI_SCR_FLG_ENABLE (RE | TE)
96#define SCI_SMR_FLG_ENABLE (STOP | PM | PE | CHR | CM)
97
98/*
99 * シリアルI/Oポート初期化ブロックの定義
100 */
101typedef struct sio_port_initialization_block {
102 volatile uint8_t *ctlreg; /* シリアルコントロールレジスタ(SCR) */
103 volatile uint8_t *modereg; /* シリアルモードレジスタ(SMR) */
104 volatile uint8_t *extmodereg; /* シリアル拡張モードレジスタ(SEMR) */
105 volatile uint8_t *statusreg; /* シリアルステータスレジスタ(SSR) */
106 volatile uint8_t *tdreg; /* トランスミットデータレジスタ(TDR)*/
107 volatile uint8_t *rdreg; /* レシーブデータレジスタ(RDR) */
108 volatile uint8_t *bitratereg; /* ビットレートレジスタ(BRR) */
109 volatile uint32_t *mstpcrreg; /* モジュールストップコントロールレジスタ(MSTPCR) */
110 volatile uint8_t *ssrreg; /* ステータスレジスタ */
111 volatile uint8_t *rxiirreg; /* RXI用割込み要求レジスタ */
112 uint8_t tx_intno; /* 送信(データエンプティ)割り込み番号 */
113 uint8_t rx_intno; /* 受信(データフル)割り込み番号 */
114 uint8_t te_intno; /* 送信(終了)割り込み番号 */
115 uint8_t sci_no; /* SCIの番号(SCI0~SCI6) */
116 uint32_t mstpcr_offset; /* MSTPCRの対応するビットオフセット */
117} SIOPINIB;
118
119/*
120 * シリアルI/Oポート管理ブロックの定義
121 */
122struct sio_port_control_block {
123 const SIOPINIB *p_siopinib; /* シリアルI/Oポート初期化ブロック */
124 intptr_t exinf; /* 拡張情
125å ± */
126 bool_t openflag; /* オープン済みフラグ */
127 bool_t sendflag; /* 送信割込みイネーブルフラグ */
128 bool_t getready; /* 文字を受信した状æ…
129‹ */
130 bool_t putready; /* 文字を送信できる状æ…
131‹ */
132 bool_t is_initialized; /* デバイス初期化済みフラグ */
133};
134
135/*
136 * シリアルI/Oポート管理ブロックのエリア
137 */
138static SIOPCB siopcb_table[TNUM_SIOP];
139
140/* レジスタテーブル */
141static const SIOPINIB siopinib_table[TNUM_SIOP] =
142{
143 {
144 (volatile uint8_t *)SCI0_SCR_ADDR,
145 (volatile uint8_t *)SCI0_SMR_ADDR,
146 (volatile uint8_t *)SCI0_SEMR_ADDR,
147 (volatile uint8_t *)SCI0_SSR_ADDR,
148 (volatile uint8_t *)SCI0_TDR_ADDR,
149 (volatile uint8_t *)SCI0_RDR_ADDR,
150 (volatile uint8_t *)SCI0_BRR_ADDR,
151 (volatile uint32_t *)SYSTEM_MSTPCRB_ADDR,
152 (volatile uint8_t *)SCI0_SSR_ADDR,
153 (volatile uint8_t *)ICU_IR215_ADDR,
154 INT_SCI0_TXI,
155 INT_SCI0_RXI,
156 INT_SCI0_TEI,
157 0,
158 SYSTEM_MSTPCRB_MSTPB31_BIT,
159 } , /* UART0 */
160#if TNUM_SIOP > 1
161 {
162 (volatile uint8_t *)SCI2_SCR_ADDR,
163 (volatile uint8_t *)SCI2_SMR_ADDR,
164 (volatile uint8_t *)SCI2_SEMR_ADDR,
165 (volatile uint8_t *)SCI2_SSR_ADDR,
166 (volatile uint8_t *)SCI2_TDR_ADDR,
167 (volatile uint8_t *)SCI2_RDR_ADDR,
168 (volatile uint8_t *)SCI2_BRR_ADDR,
169 (volatile uint32_t *)SYSTEM_MSTPCRB_ADDR,
170 (volatile uint8_t *)SCI2_SSR_ADDR,
171 (volatile uint8_t *)ICU_IR223_ADDR,
172 INT_SCI2_TXI,
173 INT_SCI2_RXI,
174 INT_SCI2_TEI,
175 2,
176 SYSTEM_MSTPCRB_MSTPB29_BIT,
177 } , /* UART2 */
178#endif
179};
180
181/*
182 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
183 */
184#define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1))
185#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
186#define get_siopinib(siopid) (&(siopinib_table[INDEX_SIOP(siopid)]))
187
188
189/*
190 * SIOドライバのシリアルモードレジスタ(SMR)
191 */
192static void
193rx630_uart_setmode(const SIOPINIB *p_siopinib, uint8_t bitrate, uint8_t clksrc)
194{
195 volatile uint8_t i;
196
197 /*
198 * SCIドライバの初期化ルーチン
199 */
200
201 /*
202 * 割り込み要求å…
203ˆãƒ¬ã‚¸ã‚¹ã‚¿ã®è¨­å®š(ISELRi)
204 *
205 * リセット値と同じ値を設定することになるため,
206 * 処理は省略する.
207 */
208
209 /*
210 * モジュールストップ機能の設定
211 */
212 sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502); /* 書込み許可 */
213 sil_wrw_mem(p_siopinib->mstpcrreg,
214 sil_rew_mem(p_siopinib->mstpcrreg) & ~p_siopinib->mstpcr_offset);
215 sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500); /* 書込み禁止 */
216
217 /* 送受信禁止, SCKn端子はå…
218¥å‡ºåŠ›ãƒãƒ¼ãƒˆã¨ã—て使用 */
219 sil_wrb_mem(p_siopinib->ctlreg, 0x00U);
220
221 /* クロック選択ビット(SMR.CKS[1:0]ビットを設定) */
222 sil_wrb_mem(p_siopinib->modereg,
223 sil_reb_mem(p_siopinib->modereg) | clksrc);
224
225 /* SMRに送信/ 受信フォーマットを設定) */
226 sil_wrb_mem(p_siopinib->modereg,
227 sil_reb_mem(p_siopinib->modereg) & (~SCI_SMR_FLG_ENABLE));
228
229 /* ビットレートを設定 */
230 sil_wrb_mem(p_siopinib->bitratereg, bitrate);
231
232 /* ビット期間(基本クロック16サイクルの期間が1ビット期間となる) */
233 for(i = 0; i < 16; i++) { }
234
235 /* 送受信許可 */
236 sil_wrb_mem(p_siopinib->ctlreg,
237 (sil_reb_mem(p_siopinib->ctlreg) | SCI_SCR_FLG_ENABLE));
238}
239
240
241/*
242 * SIOドライバの初期化ルーチン
243 */
244void
245rx630_uart_initialize(void)
246{
247 SIOPCB *p_siopcb;
248 uint_t i;
249
250 /*
251 * シリアルI/Oポート管理ブロックの初期化
252 */
253 for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++){
254 p_siopcb->p_siopinib = &(siopinib_table[i]);
255 p_siopcb->openflag = false;
256 p_siopcb->sendflag = false;
257 }
258}
259
260/*
261 * カーネル起動時のバナー出力用の初期化
262 */
263void
264rx630_uart_init(ID siopid, uint8_t bitrate, uint8_t clksrc)
265{
266 SIOPCB *p_siopcb = get_siopcb(siopid);
267 const SIOPINIB *p_siopinib = get_siopinib(siopid);
268 /* この時点では、p_siopcb->p_siopinibは初期化されていない */
269
270 /* 二重初期化の防止 */
271 p_siopcb->is_initialized = true;
272
273 /* ハードウェアの初期化処理と送信許可 */
274 rx630_uart_setmode(p_siopinib , bitrate, clksrc);
275 sil_wrb_mem(p_siopinib->ctlreg,
276 (uint8_t)(sil_reb_mem((uint8_t *)p_siopinib->ctlreg) | TE));
277}
278
279/*
280 * シリアルI/Oポートへのポーリングでの出力
281 */
282void
283rx630_uart_pol_putc(char c, ID siopid)
284{
285 const SIOPINIB *p_siopinib;
286
287 p_siopinib = get_siopinib(siopid);
288
289 /*
290 * 送信レジスタが空になるまで待
291つ
292 */
293 while((sil_reb_mem(p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) == 0U);
294
295 sil_wrb_mem(p_siopinib->tdreg, (uint8_t)c);
296}
297
298/*
299 * シリアルI/Oポートのオープン
300 */
301SIOPCB *
302rx630_uart_opn_por
303 (ID siopid, intptr_t exinf, uint8_t bitrate, uint8_t clksrc)
304{
305 SIOPCB *p_siopcb;
306 const SIOPINIB *p_siopinib;
307
308 p_siopcb = get_siopcb(siopid);
309 p_siopinib = p_siopcb->p_siopinib;
310
311 /*
312 * ハードウェアの初期化
313 *
314 * 既に初期化している場合は, 二重に初期化しない.
315 */
316 if(!(p_siopcb->is_initialized)){
317 rx630_uart_setmode(p_siopinib, bitrate, clksrc);
318 p_siopcb->is_initialized = true;
319 }
320
321 p_siopcb->exinf = exinf;
322 p_siopcb->getready = p_siopcb->putready = false;
323 p_siopcb->openflag = true;
324
325 return (p_siopcb);
326}
327
328/*
329 * シリアルI/Oポートのクローズ
330 */
331void
332rx630_uart_cls_por(SIOPCB *p_siopcb)
333{
334 /*
335 * UART停止
336 */
337 sil_wrh_mem((volatile uint16_t *)p_siopcb->p_siopinib->ctlreg, 0x00U);
338 p_siopcb->openflag = false;
339 p_siopcb->is_initialized = false;
340}
341
342/*
343 * シリアルI/Oポートへの文字送信
344 */
345bool_t
346rx630_uart_snd_chr(SIOPCB *p_siopcb, char c)
347{
348 bool_t ercd = false;
349
350 if((sil_reb_mem(p_siopcb->p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) != 0){
351 sil_wrb_mem(p_siopcb->p_siopinib->tdreg, (uint8_t)c);
352 ercd = true;
353 }
354
355 return ercd;
356}
357
358/*
359 * シリアルI/Oポートからの文字受信
360 */
361int_t
362rx630_uart_rcv_chr(SIOPCB *p_siopcb)
363{
364 int_t c = -1;
365
366 /*
367 * 受信フラグがONのときのみ受信バッファから文字を取得する.
368 * これは, ポーリング受信に対応するためである.
369 * しかし, RX600シリーズでは受信フラグがないこと, システムサービス
370 * では受信割込みの中からしかデータを受信しに来ないことから, 常に
371 * 受信バッファから文字を取得する.
372 */
373 c = (int)(sil_reb_mem(p_siopcb->p_siopinib->rdreg));
374
375 return c;
376}
377
378/*
379 * シリアルI/Oポートからのコールバックの許可
380 */
381void
382rx630_uart_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
383{
384 switch (cbrtn) {
385 case SIO_RDY_SND:
386 sil_wrb_mem(p_siopcb->p_siopinib->ctlreg,
387 (sil_reb_mem(p_siopcb->p_siopinib->ctlreg) | SCI_SCR_TEIE_BIT));
388 break;
389 case SIO_RDY_RCV:
390 sil_wrb_mem(p_siopcb->p_siopinib->ctlreg,
391 (sil_reb_mem(p_siopcb->p_siopinib->ctlreg) | SCI_SCR_RIE_BIT));
392 break;
393 default:
394 assert(1);
395 break;
396 }
397}
398
399/*
400 * シリアルI/Oポートからのコールバックの禁止
401 */
402void
403rx630_uart_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
404{
405 switch (cbrtn) {
406 case SIO_RDY_SND:
407 sil_wrb_mem(p_siopcb->p_siopinib->ctlreg,
408 (sil_reb_mem(p_siopcb->p_siopinib->ctlreg) & (~SCI_SCR_TEIE_BIT)));
409 break;
410 case SIO_RDY_RCV:
411 sil_wrb_mem(p_siopcb->p_siopinib->ctlreg,
412 (sil_reb_mem(p_siopcb->p_siopinib->ctlreg) & (~SCI_SCR_RIE_BIT)));
413 break;
414 default:
415 assert(1);
416 break;
417 }
418}
419
420/*
421 * SIOの割込みサービスルーチン
422 */
423void
424rx630_uart_tx_isr(ID siopid)
425{
426 SIOPCB *p_siopcb = get_siopcb(siopid);
427
428 if((sil_reb_mem(
429 (void *)p_siopcb->p_siopinib->ssrreg) & SCI_SSR_TEND_BIT) != 0U){
430 /*
431 * 送信可能コールバックルーチンを呼び出す.
432 */
433 rx630_uart_irdy_snd(p_siopcb->exinf);
434 }
435}
436
437void
438rx630_uart_rx_isr(ID siopid)
439{
440 SIOPCB *p_siopcb = get_siopcb(siopid);
441
442 /*
443 * 受信フラグがONのときのみ受信通知コールバックルーチンを呼び出す.
444 * しかし, RX600シリーズでは受信フラグがないため, 常に受信通知
445 * コールバックルーチンを呼び出す.
446 * ここでは受信割込みの発生を信じる.
447 */
448 /*
449 * 受信通知コールバックルーチンを呼び出す.
450 */
451 rx630_uart_irdy_rcv(p_siopcb->exinf);
452}
453
454
455/*
456 * ポート番号から管理ブロックのå…
457ˆé ­ç•ªåœ°ã¸ã®å¤‰æ›
458 */
459SIOPCB *
460rx630_uart_get_siopcb(ID siopid) {
461 SIOPCB *p_siopcb = get_siopcb(siopid);
462 return(p_siopcb);
463}
464
465/*
466 * 管理ブロックのå…
467ˆé ­ç•ªåœ°ã‹ã‚‰å—信割込み番号への変換
468 */
469INTNO
470rx630_uart_intno_rx(SIOPCB *p_siopcb) {
471 INTNO intno = p_siopcb->p_siopinib->rx_intno;
472 return(intno);
473}
474
475/*
476 * 管理ブロックのå…
477ˆé ­ç•ªåœ°ã‹ã‚‰é€ä¿¡å‰²è¾¼ã¿ç•ªå·ã¸ã®å¤‰æ›
478 */
479INTNO
480rx630_uart_intno_tx(SIOPCB *p_siopcb) {
481 INTNO intno = p_siopcb->p_siopinib->te_intno;
482 return(intno);
483}
Note: See TracBrowser for help on using the repository browser.