source: ssp_aarch64/trunk/qemu_virt_gcc/target_serial.c@ 353

Last change on this file since 353 was 353, checked in by nmir-saito, 6 years ago

initial import

File size: 7.7 KB
Line 
1/*
2 * TOPPERS/SSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2012 by Meika Sugimoto
9 * Copyright (C) 2015 by Naoki Saito
10 * Nagoya Municipal Industrial Research Institute, JAPAN
11 *
12 * 上記著作権者
13は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
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およびTOPPERSプロジェクトを
46 * å…
47è²¬ã™ã‚‹ã“と.
48 *
49 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
50お
51 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
52 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
53 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
54 * の責任を負わない.
55 *
56 */
57
58/*
59 * シリアルドライバ
60 */
61
62#include <sil.h>
63#include "target_serial.h"
64#include "target_syssvc.h"
65
66/*
67 * レジスタ設定値
68 */
69#define PORT2SIOPID(x) ((x) + 1)
70#define INDEX_PORT(x) ((x) - 1)
71#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
72
73const SIOPINIB siopinib_table[TNUM_PORT] = {
74 {
75 VIRT_UART0_BASE, /* baseAddress */
76 VIRT_UART_IBRD_38400, /* ibrd */
77 VIRT_UART_FBRD_38400, /* fbrd */
78 UART_LCR_H_WLEN8, /* lcr_h */
79 },
80};
81
82SIOPCB siopcb_table[TNUM_PORT];
83
84/*
85 * 送信バッファに空きがあるか?
86 */
87Inline bool_t
88sio_putready(SIOPCB* siopcb)
89{
90 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_TXFF) == 0U);
91}
92
93/*
94 * 受信バッファに文字があるか?
95 */
96Inline bool_t
97sio_getready(SIOPCB* siopcb)
98{
99 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_RXFE) == 0U);
100}
101
102/*
103 * 受信した文字の取出し
104 */
105Inline char
106sio_getchar(SIOPCB *siopcb)
107{
108 return((char) sil_rew_mem(UART_DR(siopcb->inib->baseAddress)));
109}
110
111/*
112 * 送信する文字の書込み
113 */
114Inline void
115sio_putchar(SIOPCB *siopcb, char c)
116{
117 sil_wrw_mem(UART_DR(siopcb->inib->baseAddress), (uint32_t) c);
118}
119
120
121/*
122 * ターゲットのシリアル初期化
123 */
124void target_low_output_init(ID siopid)
125{
126 SIOPCB *siopcb = GET_SIOPCB(siopid);
127 SIOPINIB *inib;
128
129 inib = siopcb -> inib;
130
131 /*
132 * UARTをディスエーブル
133 */
134 sil_wrw_mem(UART_CR(inib->baseAddress), 0U);
135
136 /*
137 * エラーフラグをクリア
138 */
139 sil_wrw_mem(UART_ECR(inib->baseAddress), 0U);
140
141 /*
142 * 割込みステータスをクリア
143 */
144 sil_wrw_mem(UART_ICR(inib->baseAddress), 0U);
145 sil_wrw_mem(UART_RIS(inib->baseAddress), 0U);
146 sil_wrw_mem(UART_MIS(inib->baseAddress), 0U);
147
148 /*
149 * FIFOを空にする
150 */
151 while (sio_getready(siopcb)) {
152 (void) sio_getchar(siopcb);
153 }
154
155 /*
156 * ボーレートと通信規格を設定
157 */
158 sil_wrw_mem(UART_IBRD(inib->baseAddress), inib->ibrd);
159 sil_wrw_mem(UART_FBRD(inib->baseAddress), inib->fbrd);
160 sil_wrw_mem(UART_LCR_H(inib->baseAddress), inib->lcr_h);
161
162 /*
163 * UARTをイネーブル
164 */
165 sil_wrw_mem(UART_CR(inib->baseAddress),
166 UART_CR_UARTEN|UART_CR_TXE|UART_CR_RXE);
167}
168
169/*
170 * SIO初期化
171 */
172void sio_initialize(intptr_t exinf)
173{
174 int i;
175
176 for (i = 0; i < TNUM_PORT; i++) {
177 siopcb_table[i].inib = &(siopinib_table[i]);
178 siopcb_table[i].exinf = 0;
179 }
180}
181
182/*
183 * シリアルオープン
184 */
185SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
186{
187 SIOPCB* siopcb;
188
189 if (siopid > TNUM_PORT) {
190 return NULL;
191 }
192
193 siopcb = GET_SIOPCB(siopid);
194 siopcb->exinf = exinf;
195
196 target_low_output_init(siopid);
197
198 // 受信コールバック許可
199 sio_ena_cbr(siopcb, SIO_RDY_RCV);
200
201 return siopcb;
202}
203
204/*
205 * シリアルクローズ
206 */
207void sio_cls_por(SIOPCB *siopcb)
208{
209 /*
210 * UARTをディスエーブル
211 */
212 sil_wrw_mem(UART_CR(siopcb->inib->baseAddress), 0U);
213}
214
215/*
216 * 割込みハンドラ
217 */
218void sio_isr(intptr_t exinf)
219{
220 SIOPCB* siopcb = GET_SIOPCB(exinf);
221
222 if (sio_getready(siopcb)) {
223 /*
224 * 受信通知コールバックルーチンを呼び出す.
225 */
226 sio_irdy_rcv(siopcb->exinf);
227 }
228 if (sio_putready(siopcb)) {
229 /*
230 * 送信可能コールバックルーチンを呼び出す.
231 */
232 sio_irdy_snd(siopcb->exinf);
233 }
234}
235
236/*
237 * 1文字送信
238 */
239bool_t sio_snd_chr(SIOPCB *siopcb, char c)
240{
241 if (sio_putready(siopcb)){
242 sio_putchar(siopcb, c);
243 return(true);
244 }
245 return(false);
246}
247
248/*
249 * 1文字受信
250 */
251int_t sio_rcv_chr(SIOPCB *siopcb)
252{
253 if (sio_getready(siopcb)) {
254 return((int_t)(uint8_t) sio_getchar(siopcb));
255 }
256 return(-1);
257}
258
259/*
260 * コールバックの許可
261 */
262void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
263{
264 SIOPINIB *inib;
265 uint32_t reg;
266
267 inib = siopcb->inib;
268 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
269
270 switch (cbrtn) {
271 case SIO_RDY_SND:
272 reg |= UART_IMSC_TXIM;
273 break;
274 case SIO_RDY_RCV:
275 reg |= UART_IMSC_RXIM;
276 break;
277 }
278 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
279}
280
281/*
282 * コールバックの禁止
283 */
284void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
285{
286 SIOPINIB *inib;
287 uint32_t reg;
288
289 inib = siopcb -> inib;
290 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
291
292 switch (cbrtn) {
293 case SIO_RDY_SND:
294 reg &= ~UART_IMSC_TXIM;
295 break;
296 case SIO_RDY_RCV:
297 reg &= ~UART_IMSC_RXIM;
298 break;
299 }
300 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
301}
302
303/*
304 * 1文字出力(ポーリングでの出力)
305 */
306void sio_pol_snd_chr(char c, ID siopid)
307{
308 SIOPCB *siopcb = GET_SIOPCB(siopid);
309
310 if(c == '\n'){
311 while(!sio_snd_chr(siopcb, '\r'));
312 }
313 while(!sio_snd_chr(siopcb, c));
314}
Note: See TracBrowser for help on using the repository browser.