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

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

set svn:mime-type to files

  • Property svn:mime-type set to text/plain; charset=utf-8
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 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
32 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 */
42
43/*
44 * シリアルドライバ
45 */
46
47#include <sil.h>
48#include "target_serial.h"
49#include "target_syssvc.h"
50
51/*
52 * レジスタ設定値
53 */
54#define PORT2SIOPID(x) ((x) + 1)
55#define INDEX_PORT(x) ((x) - 1)
56#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
57
58const SIOPINIB siopinib_table[TNUM_PORT] = {
59 {
60 VIRT_UART0_BASE, /* baseAddress */
61 VIRT_UART_IBRD_38400, /* ibrd */
62 VIRT_UART_FBRD_38400, /* fbrd */
63 UART_LCR_H_WLEN8, /* lcr_h */
64 },
65};
66
67SIOPCB siopcb_table[TNUM_PORT];
68
69/*
70 * 送信バッファに空きがあるか?
71 */
72Inline bool_t
73sio_putready(SIOPCB* siopcb)
74{
75 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_TXFF) == 0U);
76}
77
78/*
79 * 受信バッファに文字があるか?
80 */
81Inline bool_t
82sio_getready(SIOPCB* siopcb)
83{
84 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_RXFE) == 0U);
85}
86
87/*
88 * 受信した文字の取出し
89 */
90Inline char
91sio_getchar(SIOPCB *siopcb)
92{
93 return((char) sil_rew_mem(UART_DR(siopcb->inib->baseAddress)));
94}
95
96/*
97 * 送信する文字の書込み
98 */
99Inline void
100sio_putchar(SIOPCB *siopcb, char c)
101{
102 sil_wrw_mem(UART_DR(siopcb->inib->baseAddress), (uint32_t) c);
103}
104
105
106/*
107 * ターゲットのシリアル初期化
108 */
109void target_low_output_init(ID siopid)
110{
111 SIOPCB *siopcb = GET_SIOPCB(siopid);
112 SIOPINIB *inib;
113
114 inib = siopcb -> inib;
115
116 /*
117 * UARTをディスエーブル
118 */
119 sil_wrw_mem(UART_CR(inib->baseAddress), 0U);
120
121 /*
122 * エラーフラグをクリア
123 */
124 sil_wrw_mem(UART_ECR(inib->baseAddress), 0U);
125
126 /*
127 * 割込みステータスをクリア
128 */
129 sil_wrw_mem(UART_ICR(inib->baseAddress), 0U);
130 sil_wrw_mem(UART_RIS(inib->baseAddress), 0U);
131 sil_wrw_mem(UART_MIS(inib->baseAddress), 0U);
132
133 /*
134 * FIFOを空にする
135 */
136 while (sio_getready(siopcb)) {
137 (void) sio_getchar(siopcb);
138 }
139
140 /*
141 * ボーレートと通信規格を設定
142 */
143 sil_wrw_mem(UART_IBRD(inib->baseAddress), inib->ibrd);
144 sil_wrw_mem(UART_FBRD(inib->baseAddress), inib->fbrd);
145 sil_wrw_mem(UART_LCR_H(inib->baseAddress), inib->lcr_h);
146
147 /*
148 * UARTをイネーブル
149 */
150 sil_wrw_mem(UART_CR(inib->baseAddress),
151 UART_CR_UARTEN|UART_CR_TXE|UART_CR_RXE);
152}
153
154/*
155 * SIO初期化
156 */
157void sio_initialize(intptr_t exinf)
158{
159 int i;
160
161 for (i = 0; i < TNUM_PORT; i++) {
162 siopcb_table[i].inib = &(siopinib_table[i]);
163 siopcb_table[i].exinf = 0;
164 }
165}
166
167/*
168 * シリアルオープン
169 */
170SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
171{
172 SIOPCB* siopcb;
173
174 if (siopid > TNUM_PORT) {
175 return NULL;
176 }
177
178 siopcb = GET_SIOPCB(siopid);
179 siopcb->exinf = exinf;
180
181 target_low_output_init(siopid);
182
183 // 受信コールバック許可
184 sio_ena_cbr(siopcb, SIO_RDY_RCV);
185
186 return siopcb;
187}
188
189/*
190 * シリアルクローズ
191 */
192void sio_cls_por(SIOPCB *siopcb)
193{
194 /*
195 * UARTをディスエーブル
196 */
197 sil_wrw_mem(UART_CR(siopcb->inib->baseAddress), 0U);
198}
199
200/*
201 * 割込みハンドラ
202 */
203void sio_isr(intptr_t exinf)
204{
205 SIOPCB* siopcb = GET_SIOPCB(exinf);
206
207 if (sio_getready(siopcb)) {
208 /*
209 * 受信通知コールバックルーチンを呼び出す.
210 */
211 sio_irdy_rcv(siopcb->exinf);
212 }
213 if (sio_putready(siopcb)) {
214 /*
215 * 送信可能コールバックルーチンを呼び出す.
216 */
217 sio_irdy_snd(siopcb->exinf);
218 }
219}
220
221/*
222 * 1文字送信
223 */
224bool_t sio_snd_chr(SIOPCB *siopcb, char c)
225{
226 if (sio_putready(siopcb)){
227 sio_putchar(siopcb, c);
228 return(true);
229 }
230 return(false);
231}
232
233/*
234 * 1文字受信
235 */
236int_t sio_rcv_chr(SIOPCB *siopcb)
237{
238 if (sio_getready(siopcb)) {
239 return((int_t)(uint8_t) sio_getchar(siopcb));
240 }
241 return(-1);
242}
243
244/*
245 * コールバックの許可
246 */
247void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
248{
249 SIOPINIB *inib;
250 uint32_t reg;
251
252 inib = siopcb->inib;
253 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
254
255 switch (cbrtn) {
256 case SIO_RDY_SND:
257 reg |= UART_IMSC_TXIM;
258 break;
259 case SIO_RDY_RCV:
260 reg |= UART_IMSC_RXIM;
261 break;
262 }
263 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
264}
265
266/*
267 * コールバックの禁止
268 */
269void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
270{
271 SIOPINIB *inib;
272 uint32_t reg;
273
274 inib = siopcb -> inib;
275 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
276
277 switch (cbrtn) {
278 case SIO_RDY_SND:
279 reg &= ~UART_IMSC_TXIM;
280 break;
281 case SIO_RDY_RCV:
282 reg &= ~UART_IMSC_RXIM;
283 break;
284 }
285 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
286}
287
288/*
289 * 1文字出力(ポーリングでの出力)
290 */
291void sio_pol_snd_chr(char c, ID siopid)
292{
293 SIOPCB *siopcb = GET_SIOPCB(siopid);
294
295 if(c == '\n'){
296 while(!sio_snd_chr(siopcb, '\r'));
297 }
298 while(!sio_snd_chr(siopcb, c));
299}
Note: See TracBrowser for help on using the repository browser.