source: ssp_rpi3/trunk/arch/arm64_gcc/bcm283x/chip_serial.c@ 386

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

modify svn:mimetype of files

  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain; charset=utf-8
File size: 7.8 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, 2019 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#include "pl011.h"
51#include "bcm2837.h"
52
53/*
54 * レジスタ設定値
55 */
56#define PORT2SIOPID(x) ((x) + 1)
57#define INDEX_PORT(x) ((x) - 1)
58#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
59
60const SIOPINIB siopinib_table[TNUM_PORT] = {
61 {
62 RPI_UART0_BASE, /* baseAddress */
63 RPI_UART_IBRD_115200, /* ibrd */
64 RPI_UART_FBRD_115200, /* fbrd */
65 UART_LCR_H_WLEN8, /* lcr_h */
66 },
67};
68
69SIOPCB siopcb_table[TNUM_PORT];
70
71/*
72 * 送信バッファに空きがあるか?
73 */
74Inline bool_t
75sio_putready(SIOPCB* siopcb)
76{
77 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_TXFF) == 0U);
78}
79
80/*
81 * 受信バッファに文字があるか?
82 */
83Inline bool_t
84sio_getready(SIOPCB* siopcb)
85{
86 return((sil_rew_mem(UART_FR(siopcb->inib->baseAddress)) & UART_FR_RXFE) == 0U);
87}
88
89/*
90 * 受信した文字の取出し
91 */
92Inline char
93sio_getchar(SIOPCB *siopcb)
94{
95 return((char) sil_rew_mem(UART_DR(siopcb->inib->baseAddress)));
96}
97
98/*
99 * 送信する文字の書込み
100 */
101Inline void
102sio_putchar(SIOPCB *siopcb, char c)
103{
104 sil_wrw_mem(UART_DR(siopcb->inib->baseAddress), (uint32_t) c);
105}
106
107/*
108 * ターゲットのシリアル初期化
109 */
110void target_low_output_init(ID siopid)
111{
112 SIOPINIB *inib;
113 volatile uint32_t __attribute__((aligned(16))) mbox[36];
114
115 inib = &siopinib_table[INDEX_PORT(siopid)];
116
117 /*
118 * disable UART
119 */
120 sil_wrw_mem(UART_CR(inib->baseAddress), 0U);
121
122 // クロックのセットアップ
123 mbox[0] = 9*4;
124 mbox[1] = MBOX_REQUEST;
125 mbox[2] = MBOX_TAG_SETCLKRATE;
126 mbox[3] = 12;
127 mbox[4] = 8;
128 mbox[5] = 2;
129 mbox[6] = 4000000; // 4MHz
130 mbox[7] = 0;
131 mbox[8] = MBOX_TAG_LAST;
132 mbox_call(MBOX_CH_PROP, mbox);
133
134 /*
135 * clear error flag
136 */
137 sil_wrw_mem(UART_ECR(inib->baseAddress), 0U);
138
139 /*
140 * clear interrupt status
141 */
142 sil_wrw_mem(UART_ICR(inib->baseAddress), 0U);
143 sil_wrw_mem(UART_RIS(inib->baseAddress), 0U);
144 sil_wrw_mem(UART_MIS(inib->baseAddress), 0U);
145
146 /*
147 * configure UART
148 */
149 sil_wrw_mem(UART_IBRD(inib->baseAddress), inib->ibrd);
150 sil_wrw_mem(UART_FBRD(inib->baseAddress), inib->fbrd);
151 sil_wrw_mem(UART_LCR_H(inib->baseAddress), inib->lcr_h);
152
153 /*
154 * enable UART
155 */
156 sil_wrw_mem(UART_CR(inib->baseAddress),
157 UART_CR_UARTEN|UART_CR_TXE|UART_CR_RXE);
158}
159
160/*
161 * SIO初期化
162 */
163void sio_initialize(intptr_t exinf)
164{
165 int i;
166
167 for (i = 0; i < TNUM_PORT; i++) {
168 siopcb_table[i].inib = &(siopinib_table[i]);
169 siopcb_table[i].exinf = 0;
170 }
171}
172
173/*
174 * シリアルオープン
175 */
176SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
177{
178 SIOPCB* siopcb;
179
180 if (siopid > TNUM_PORT) {
181 return NULL;
182 }
183
184 siopcb = GET_SIOPCB(siopid);
185 siopcb->exinf = exinf;
186
187 target_low_output_init(siopid);
188
189 // 受信コールバック許可
190 sio_ena_cbr(siopcb, SIO_RDY_RCV);
191
192 return siopcb;
193}
194
195/*
196 * シリアルクローズ
197 */
198void sio_cls_por(SIOPCB *siopcb)
199{
200 /*
201 * UARTをディスエーブル
202 */
203 sil_wrw_mem(UART_CR(siopcb->inib->baseAddress), 0U);
204}
205
206/*
207 * 割込みハンドラ
208 */
209#include "target_syssvc.h"
210void sio_isr(intptr_t exinf)
211{
212 SIOPCB* siopcb = GET_SIOPCB(exinf);
213
214 if (sio_getready(siopcb)) {
215 /*
216 * 受信通知コールバックルーチンを呼び出す.
217 */
218 sio_irdy_rcv(siopcb->exinf);
219 }
220 if (sio_putready(siopcb)) {
221 /*
222 * 送信可能コールバックルーチンを呼び出す.
223 */
224 sio_irdy_snd(siopcb->exinf);
225 }
226}
227
228/*
229 * 1文字送信
230 */
231bool_t sio_snd_chr(SIOPCB *siopcb, char c)
232{
233 if (sio_putready(siopcb)){
234 sio_putchar(siopcb, c);
235 return(true);
236 }
237 return(false);
238}
239
240/*
241 * 1文字受信
242 */
243int_t sio_rcv_chr(SIOPCB *siopcb)
244{
245 if (sio_getready(siopcb)) {
246 return((int_t)(uint8_t) sio_getchar(siopcb));
247 }
248 return(-1);
249}
250
251/*
252 * コールバックの許可
253 */
254void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
255{
256 SIOPINIB *inib;
257 uint32_t reg;
258
259 inib = siopcb->inib;
260 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
261
262 switch (cbrtn) {
263 case SIO_RDY_SND:
264 reg |= UART_IMSC_TXIM;
265 break;
266 case SIO_RDY_RCV:
267 reg |= UART_IMSC_RXIM;
268 break;
269 }
270 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
271}
272
273/*
274 * コールバックの禁止
275 */
276void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
277{
278 SIOPINIB *inib;
279 uint32_t reg;
280
281 inib = siopcb -> inib;
282 reg = sil_rew_mem(UART_IMSC(inib->baseAddress));
283
284 switch (cbrtn) {
285 case SIO_RDY_SND:
286 reg &= ~UART_IMSC_TXIM;
287 break;
288 case SIO_RDY_RCV:
289 reg &= ~UART_IMSC_RXIM;
290 break;
291 }
292 sil_wrw_mem(UART_IMSC(inib->baseAddress), reg);
293}
294
295/*
296 * 1文字出力(ポーリングでの出力)
297 */
298void sio_pol_snd_chr(char c, ID siopid)
299{
300 SIOPCB *siopcb = GET_SIOPCB(siopid);
301
302 if(c == '\n'){
303 while(!sio_snd_chr(siopcb, '\r'));
304 }
305 while(!sio_snd_chr(siopcb, c));
306}
Note: See TracBrowser for help on using the repository browser.