OSDN Git Service

マルチプロジェクト型にレポジトリを変更するために移動した
[toppersasp4lpc/asp.git] / asp / target / cq_starm_gcc / target_serial.c
1 /*
2  *  TOPPERS/ASP 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  * 
9  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
10  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14  *      スコード中に含まれていること.
15  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18  *      の無保証規定を掲載すること.
19  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21  *      と.
22  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
24  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25  *        報告すること.
26  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30  *      免責すること.
31  * 
32  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36  *  の責任を負わない.
37  * 
38  */
39
40 /*
41  * シリアルドライバ(CQ-STARM用)
42  */
43
44 #include <kernel.h>
45 #include <sil.h>
46 #include "target_serial.h"
47 #include "target_syssvc.h"
48
49 /*
50  * レジスタ設定値
51  */
52 #define PORT2SIOPID(x)  ((x) + 1)
53 #define INDEX_PORT(x)   ((x) - 1)
54 #define GET_SIOPCB(x)   (&siopcb_table[INDEX_PORT(x)])
55
56 /*
57  * USARTレジスタ定義
58  */
59 #define USART_SR(x)             (x)
60 #define USART_DR(x)             (x + 0x04)
61 #define USART_BRR(x)    (x + 0x08)
62 #define USART_CR1(x)    (x + 0x0C)
63 #define USART_CR2(x)    (x + 0x10)
64 #define USART_CR3(x)    (x + 0x14)
65 #define USART_GTPR(x)   (x + 0x18)
66
67 #define SR_TXE                  (0x0080)
68 #define SR_RXNE                 (0x0020)
69 #define SR_ORE                  (0x0008)
70 #define SR_FE                   (0x0002)
71 #define SR_PE                   (0x0001)
72 #define CR1_UE                  (0x2000)
73 #define CR1_TXEIE               (0x0080)
74 #define CR1_RXNEIE              (0x0020)
75 #define CR1_TE                  (0x0008)
76 #define CR1_RE                  (0x0004)
77 #define CR3_EIE                 (0x0001)
78
79 /*
80  * シリアルI/Oポート管理ブロックエリア
81  */
82 SIOPCB siopcb_table[TNUM_PORT];
83
84 static const uint32_t sioreg_table[TNUM_PORT] = {
85         USART1_BASE,
86 #if (TNUM_PORT >= 2)
87         USART2_BASE
88 #endif
89 };
90
91 Inline bool_t  sio_putready(SIOPCB* siopcb)
92 {
93         return (sil_rew_mem((void*)USART_SR(siopcb->reg)) & SR_TXE) != 0;
94 }
95
96 Inline bool_t sio_getready(SIOPCB* siopcb)
97 {
98         return (sil_rew_mem((void*)USART_SR(siopcb->reg)) & SR_RXNE) != 0;
99 }
100
101 /*
102  *  ターゲットのシリアル初期化
103  */
104 void target_usart_init(ID siopid)
105 {
106         uint32_t tmp, usartdiv, fraction;
107         uint32_t reg = sioreg_table[INDEX_PORT(siopid)];
108         uint32_t src_clock;
109
110         /* USARTの無効化 */
111         sil_andw((void*)USART_CR1(reg), ~CR1_UE);
112
113         /* 1STOP BIT */
114         sil_wrw_mem((void*)USART_CR2(reg), 0);
115
116         /* 1START BIT, 8DATA bits, Parityなし */
117         sil_wrw_mem((void*)USART_CR1(reg), 0);
118
119         /* CR3初期化 */
120         sil_wrw_mem((void*)USART_CR3(reg), 0);
121
122         /* 通信速度設定 */
123         if (siopid == 1) {
124                 /* fck=72MHz */
125                 src_clock = PCLK2_CLOCK;
126         } else {
127                 /* fck=36MHz */
128                 src_clock = PCLK1_CLOCK;
129         }
130         tmp = (1000 * (src_clock / 100)) / ((BPS_SETTING / 100) * 16);
131         usartdiv = (tmp / 1000) << 4;
132         fraction = tmp - ((usartdiv >> 4) * 1000);
133         fraction = ((16 * fraction) + 500) / 1000;
134         usartdiv |= (fraction & 0x0F);
135         sil_wrw_mem((void*)USART_BRR(reg), usartdiv);
136
137         /* 送受信の有効化、エラー割込みの有効化 */
138         sil_orw((void*)USART_CR1(reg), CR1_RE | CR1_TE);
139         sil_orw((void*)USART_CR3(reg), CR3_EIE);
140
141         /* USARTの有効化 */
142         sil_orw((void*)USART_CR1(reg), CR1_UE);
143 }
144
145 /*
146  *  ターゲットのシリアル終了
147  */
148 void target_usart_term(ID siopid)
149 {
150         uint32_t reg = sioreg_table[INDEX_PORT(siopid)];
151
152         /* USARTの無効化 */
153         sil_andw((void*)USART_CR1(reg),  ~CR1_UE);
154 }
155
156 /*
157  *  SIO初期化
158  */
159 void sio_initialize(intptr_t exinf)
160 {
161         int i;
162
163         for (i = 0; i < TNUM_PORT; i++) {
164                 siopcb_table[i].port = i;
165                 siopcb_table[i].reg = sioreg_table[i];
166                 siopcb_table[i].exinf = 0;
167         }
168 }
169
170 /*
171  *  シリアルオープン
172  */
173 SIOPCB *sio_opn_por(ID siopid, intptr_t exinf)
174 {
175         SIOPCB* siopcb;
176
177         if (siopid > TNUM_PORT) {
178                 return NULL;
179         }
180
181         siopcb = GET_SIOPCB(siopid);
182         siopcb->exinf = exinf;
183
184         target_usart_init(siopid);
185
186         return siopcb;
187 }
188
189 /*
190  *  シリアルクローズ
191  */
192 void sio_cls_por(SIOPCB *p_siopcb)
193 {
194         target_usart_term(PORT2SIOPID(p_siopcb->port));
195 }
196
197 /*
198  *  割込みハンドラ
199  */
200 void sio_isr(intptr_t exinf)
201 {
202         SIOPCB* siopcb = GET_SIOPCB(exinf);
203
204         if (sio_putready(siopcb)) {
205                 sio_irdy_snd(siopcb->exinf);
206         }
207         if (sio_getready(siopcb)) {
208                 sio_irdy_rcv(siopcb->exinf);
209         }
210 }
211
212 /*
213  *  1文字送信
214  */
215 bool_t sio_snd_chr(SIOPCB *siopcb, char_t c)
216 {
217         if (sio_putready(siopcb)) {
218                 sil_wrw_mem((void*)USART_DR(siopcb->reg), c);
219
220                 return true;
221         }
222
223         return false;
224 }
225
226 /*
227  *  1文字受信
228  */
229 int_t sio_rcv_chr(SIOPCB *siopcb)
230 {
231         int_t c = -1;
232
233         if (sio_getready(siopcb)) {
234                 c = sil_rew_mem((void*)USART_DR(siopcb->reg)) & 0xFF;
235         }
236
237         return c;
238 }
239
240 /*
241  *  コールバックの許可
242  */
243 void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
244 {
245         switch (cbrtn) {
246         case SIO_RDY_SND:
247                 sil_orw((void*)USART_CR1(siopcb->reg), CR1_TXEIE);
248                 break;
249         case SIO_RDY_RCV:
250                 sil_orw((void*)USART_CR1(siopcb->reg), CR1_RXNEIE);
251                 break;
252         default:
253                 break;
254         }
255 }
256
257 /* 
258  *  コールバックの禁止
259  */
260 void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
261 {
262         switch (cbrtn) {
263         case SIO_RDY_SND:
264                 sil_andw((void*)USART_CR1(siopcb->reg), ~CR1_TXEIE);
265                 break;
266         case SIO_RDY_RCV:
267                 sil_andw((void*)USART_CR1(siopcb->reg), ~CR1_RXNEIE);
268                 break;
269         default:
270                 break;
271         }
272 }
273
274 /*
275  *  1文字出力(ポーリングでの出力)
276  */
277 void sio_pol_snd_chr(char_t c, ID siopid)
278 {
279         uint32_t reg = sioreg_table[INDEX_PORT(siopid)];
280
281         sil_wrw_mem((void*)USART_DR(reg), c);
282
283         while ((sil_rew_mem((void*)USART_SR(reg)) & SR_TXE) == 0) ;
284 }