source: rtos_arduino/trunk/asp_1.9.2/target/arduino_m0_gcc/target_serial.c@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 11.8 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) 2015 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
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: target_serial.c 2708 2015-11-22 10:35:09Z ertl-honda $
54 */
55
56/*
57 * シリアルI/Oデバイス(SIO)ドライバ(ARDUINO_M0用)
58 */
59#include <kernel.h>
60#include <t_syslog.h>
61#include "arduino_m0.h"
62#include "target_serial.h"
63#include "variant.h"
64
65/*
66 * シリアルI/Oポート初期化ブロックの定義
67 */
68typedef struct sio_port_initialization_block
69{
70 Sercom* p_sercom; /* 使用するSERCOMへのポインタ */
71 uint8_t rx_pin; /* RX用PIN */
72 uint8_t tx_pin; /* TX用PIN */
73 uint8_t sample_rate; /* サンプリングレート */
74 uint8_t port; /* ポート */
75 int8_t pio; /* PIO */
76 uint8_t gcm; /* GCM */
77 uint32_t bps; /* ボーレート */
78 uint32_t pm; /* PowerManagement */
79}
80SIOPINIB;
81
82/*
83 * シリアルI/Oポート管理ブロックの定義
84 */
85struct sio_port_control_block
86{
87 const SIOPINIB* p_siopinib; /* 初期化ブロック */
88 intptr_t exinf; /* 拡張情
89å ± */
90 bool_t openflag; /* オープン済みフラグ */
91 bool_t devinitd; /* デバイス初期化済みフラグ */
92 bool_t sendflag; /* 送信割込みイネーブルフラグ */
93 bool_t getready; /* 文字を受信した状æ…
94‹ */
95 bool_t putready; /* 文字を送信できる状æ…
96‹ */
97};
98
99/*
100 * シリアルI/Oポート初期化ブロック
101 */
102const SIOPINIB siopinib_table[TNUM_SIOP] = {
103 {SERCOM5, 23u, 22u, 16u, PORTB, PIO_SERCOM_ALT, GCM_SERCOM5_CORE, 115200, PM_APBCMASK_SERCOM5}
104};
105
106/*
107 * シリアルI/Oポート管理ブロックのエリア
108 */
109SIOPCB siopcb_table[TNUM_SIOP];
110
111/*
112 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
113 */
114#define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1))
115#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
116
117
118static void
119sercom_uart_devinit(SIOPCB *p_siopcb){
120 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
121
122 /* デバイスが初期化済みならリターン */
123 if (p_siopcb->devinitd) {
124 return;
125 }
126
127 p_siopcb->devinitd = true;
128
129 /* RX Pin Initialize */
130 PORT->Group[p_siopcb->p_siopinib->port].PMUX[(p_siopcb->p_siopinib->rx_pin) >> 1].reg =
131 ((PORT->Group[p_siopcb->p_siopinib->port].PMUX[(p_siopcb->p_siopinib->rx_pin) >> 1].reg) & PORT_PMUX_PMUXE(0xF))
132 |PORT_PMUX_PMUXO(p_siopcb->p_siopinib->pio);
133 PORT->Group[p_siopcb->p_siopinib->port].PINCFG[(p_siopcb->p_siopinib->rx_pin)].reg |= PORT_PINCFG_PMUXEN;
134
135 /* TX Pin Initialize */
136 PORT->Group[p_siopcb->p_siopinib->port].PMUX[(p_siopcb->p_siopinib->tx_pin) >> 1].reg =
137 ((PORT->Group[p_siopcb->p_siopinib->port].PMUX[(p_siopcb->p_siopinib->tx_pin) >> 1].reg) & PORT_PMUX_PMUXO(0xF))
138 |PORT_PMUX_PMUXE(p_siopcb->p_siopinib->pio);
139 PORT->Group[p_siopcb->p_siopinib->port].PINCFG[(p_siopcb->p_siopinib->tx_pin)].reg |= PORT_PINCFG_PMUXEN;
140
141 /* 電源の投å…
142¥ */
143 PM->APBCMASK.reg |= p_siopcb->p_siopinib->pm;
144
145 /* Reset Uart */
146 p_sercom->USART.CTRLA.bit.SWRST = 1 ;
147 while(p_sercom->USART.CTRLA.bit.SWRST || p_sercom->USART.SYNCBUSY.bit.SWRST){};
148
149 /* Init Clock */
150 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(p_siopcb->p_siopinib->gcm)
151 | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_CLKEN ;
152 while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) {}
153
154 /* Set Baund Rate */
155 p_sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(0x01) | SERCOM_USART_CTRLA_SAMPR(p_siopcb->p_siopinib->sample_rate);
156 p_sercom->USART.BAUD.reg = 0xffff - ((0xffff * (((int)p_siopcb->p_siopinib->sample_rate * (int)p_siopcb->p_siopinib->bps)/(CORE_CLOCK_HZ/1000000))) / 1000000u);
157
158 /* Disable All Interrupt */
159 p_sercom->USART.INTENSET.reg = 0;
160
161 /* Set Frame : 8bit, 1Stop, No parity, Lsb first*/
162 p_sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM(0) |
163 (1 << SERCOM_USART_CTRLA_DORD_Pos);
164 p_sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(0) |
165 (0 << SERCOM_USART_CTRLB_SBMODE_Pos) |
166 (0 << SERCOM_USART_CTRLB_PMODE_Pos);
167
168 /* Set Pad */
169 p_sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(0x01) | SERCOM_USART_CTRLA_RXPO(0x03);
170
171 /* Tx/Rx Enable */
172 p_sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN;
173
174 /* Enable Uart */
175 p_sercom->USART.CTRLA.bit.ENABLE = 0x01;
176 while(p_sercom->USART.SYNCBUSY.bit.ENABLE){};
177}
178
179/*
180 * カーネル起動時のログ出力用の初期化
181 */
182void
183arduino_m0_init_uart(uint32_t siopid)
184{
185 SIOPCB *p_siopcb;
186
187 p_siopcb = get_siopcb(siopid);
188 p_siopcb->p_siopinib = &siopinib_table[INDEX_SIOP(siopid)];
189 sercom_uart_devinit(p_siopcb);
190}
191
192/*
193 * UARTからのポーリング出力
194 */
195void
196arduino_m0_putc(uint32_t siopid, char c)
197{
198 Sercom* p_sercom = (get_siopcb(siopid))->p_siopinib->p_sercom;
199 while(p_sercom->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
200 p_sercom->USART.DATA.reg = (uint16_t)c;
201}
202
203
204/*
205 * 文字を受信したか?
206 */
207Inline bool_t
208uart_getready(SIOPCB *p_siopcb)
209{
210 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
211 return(p_sercom->USART.INTFLAG.bit.RXC);
212}
213
214/*
215 * 文字を送信できるか?
216 */
217Inline bool_t
218uart_putready(SIOPCB *p_siopcb)
219{
220 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
221 return(p_sercom->USART.INTFLAG.bit.DRE == SERCOM_USART_INTFLAG_DRE);
222}
223
224/*
225 * 受信した文字の取り出し
226 */
227Inline uint8_t
228uart_getchar(SIOPCB *p_siopcb)
229{
230 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
231 return p_sercom->USART.DATA.bit.DATA;
232}
233
234/*
235 * 送信する文字の書き込み
236 */
237Inline void
238uart_putchar(SIOPCB *p_siopcb, uint8_t c)
239{
240 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
241 p_sercom->USART.DATA.reg = (uint16_t)c;
242}
243
244/*
245 * 送信割込み許可
246 */
247Inline void
248uart_enable_send(SIOPCB *p_siopcb)
249{
250 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
251 p_sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_TXC;
252}
253
254/*
255 * 送信割込み禁止
256 */
257Inline void
258uart_disable_send(SIOPCB *p_siopcb)
259{
260 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
261 p_sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_TXC;
262}
263
264
265/*
266 * 受信割込み許可
267 */
268Inline void
269uart_enable_rcv(SIOPCB *p_siopcb)
270{
271 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
272 p_sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC;
273}
274
275/*
276 * 受信割込み禁止
277 */
278Inline void
279uart_disable_rcv(SIOPCB *p_siopcb)
280{
281 Sercom* p_sercom = p_siopcb->p_siopinib->p_sercom;
282 p_sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_RXC;
283}
284
285
286/*
287 * SIOドライバの初期化
288 */
289void
290sio_initialize(intptr_t exinf)
291{
292 SIOPCB *p_siopcb;
293 uint_t i;
294
295 /*
296 * シリアルI/Oポート管理ブロックの初期化
297 */
298 for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) {
299 p_siopcb->p_siopinib = &(siopinib_table[i]);
300 p_siopcb->openflag = false;
301 p_siopcb->sendflag = false;
302 }
303}
304
305/*
306 * シリアルI/Oポートのオープン
307 */
308SIOPCB *
309arduino_m0_uart_opn_por(SIOPCB *p_siopcb, intptr_t exinf)
310{
311 p_siopcb->exinf = exinf;
312 p_siopcb->getready = p_siopcb->putready = false;
313 p_siopcb->openflag = true;
314
315 sercom_uart_devinit(p_siopcb);
316
317 return(p_siopcb);
318}
319
320
321/*
322 * シリアルI/Oポートのオープン
323 */
324SIOPCB *
325sio_opn_por(ID siopid, intptr_t exinf)
326{
327 SIOPCB *p_siopcb = get_siopcb(siopid);
328 bool_t opnflg;
329 ER ercd;
330
331 /*
332 * オープンしたポートがあるかをopnflgに読んでおく.
333 */
334 opnflg = p_siopcb->openflag;
335
336 /*
337 * デバイス依存のオープン処理.
338 */
339 arduino_m0_uart_opn_por(p_siopcb, exinf);
340
341 /*
342 * シリアルI/O割込みのマスクを解除する.
343 */
344 if (!opnflg) {
345 ercd = ena_int(INTNO_SIO);
346 assert(ercd == E_OK);
347 }
348 return(p_siopcb);
349}
350
351/*
352 * シリアルI/Oポートのクローズ
353 */
354void
355sio_cls_por(SIOPCB *p_siopcb)
356{
357 /*
358 * デバイス依存のクローズ処理.
359 */
360 p_siopcb->openflag = false;
361
362 /*
363 * シリアルI/O割込みをマスクする.
364 */
365 dis_int(INTNO_SIO);
366}
367
368/*
369 * SIOの割込みハンドラ
370 */
371void
372sio_isr(intptr_t exinf)
373{
374 SIOPCB *p_siopcb = get_siopcb(exinf);
375
376 if (uart_getready(p_siopcb)) {
377 /*
378 * 受信通知コールバックルーチンを呼び出す.
379 */
380 sio_irdy_rcv(p_siopcb->exinf);
381 }
382 if (uart_putready(p_siopcb)) {
383 /*
384 * 送信可能コールバックルーチンを呼び出す.
385 */
386 sio_irdy_snd(p_siopcb->exinf);
387 }
388}
389
390
391/*
392 * シリアルI/Oポートへの文字送信
393 */
394bool_t
395sio_snd_chr(SIOPCB *siopcb, char c)
396{
397 if (uart_putready(siopcb)){
398 uart_putchar(siopcb, c);
399 return(true);
400 }
401 return(false);
402}
403
404/*
405 * シリアルI/Oポートからの文字受信
406 */
407int_t
408sio_rcv_chr(SIOPCB *siopcb)
409{
410 if (uart_getready(siopcb)) {
411 return((int_t)(uint8_t) uart_getchar(siopcb));
412 }
413 return(-1);
414}
415
416/*
417 * シリアルI/Oポートからのコールバックの許可
418 */
419void
420sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn)
421{
422 switch (cbrtn) {
423 case SIO_RDY_SND:
424 uart_enable_send(siopcb);
425 break;
426 case SIO_RDY_RCV:
427 uart_enable_rcv(siopcb);
428 break;
429 }
430}
431
432/*
433 * シリアルI/Oポートからのコールバックの禁止
434 */
435void
436sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn)
437{
438 switch (cbrtn) {
439 case SIO_RDY_SND:
440 uart_disable_send(siopcb);
441 break;
442 case SIO_RDY_RCV:
443 uart_disable_rcv(siopcb);
444 break;
445 }
446}
447
448#define UART_SERCOM SERCOM5
449
450void
451serial_ena(void){
452 UART_SERCOM->USART.INTENSET.reg |= SERCOM_USART_INTENSET_RXC;
453}
454
455void
456serial_putc(char c){
457 while(UART_SERCOM->USART.INTFLAG.bit.DRE != SERCOM_USART_INTFLAG_DRE);
458 UART_SERCOM->USART.DATA.reg = (uint16_t)c;
459}
460
461char
462serial_getc(void){
463 while(!UART_SERCOM->USART.INTFLAG.bit.RXC);
464 return UART_SERCOM->USART.DATA.bit.DATA;
465}
Note: See TracBrowser for help on using the repository browser.