- Timestamp:
- May 22, 2019, 4:09:18 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
asp3_tinet_ecnl_rx/trunk/asp3_dcre/target/gr_citrus_gcc/target_serial.c
r374 r387 3 3 * Toyohashi Open Platform for Embedded Real-Time Systems/ 4 4 * Advanced Standard Profile Kernel 5 * 6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory 7 * Toyohashi Univ. of Technology, JAPAN 8 * Copyright (C) 2003-2004 by Naoki Saito 9 * Nagoya Municipal Industrial Research Institute, JAPAN 10 * Copyright (C) 2003-2004 by Platform Development Center 11 * RICOH COMPANY,LTD. JAPAN 12 * Copyright (C) 2008-2010 by Witz Corporation, JAPAN 13 * Copyright (C) 2013 by Mitsuhiro Matsuura 14 * 5 * 6 * Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory 7 * Graduate School of Information Science, Nagoya Univ., JAPAN 8 * 15 9 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ 16 10 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 … … 35 29 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを 36 30 * 免責すること. 37 * 31 * 38 32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 39 33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 … … 41 35 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ 42 36 * の責任を負わない. 43 * 37 * 44 38 * @(#) $Id$ 45 39 */ 46 40 47 41 /* 48 * RX630 UART用シリアルI/Oモジュール 49 */ 50 #include "kernel_impl.h" 51 #include <sil.h> 42 * シリアルインタフェースドライバのターゲット依存部(GR-CITRUS用) 43 */ 44 45 #include "gr_citrus.h" 46 #include <t_stddef.h> 47 #include <t_syslog.h> 48 #include <errno.h> 49 #include <unistd.h> 50 #include <fcntl.h> 51 #include <termios.h> 52 52 #include "target_serial.h" 53 #include "hal/serial_api.h" 54 #include "target_syssvc.h" 55 #include "syssvc/serial.h" 56 57 /* 58 * シリアルI/Oポート初期化ブロックの定義 53 #include "syssvc/siofd.h" 54 55 /* 56 * SIOポート初期化ブロックの定義 59 57 */ 60 58 typedef struct sio_port_initialization_block { 61 PinName tx; 62 PinName rx; 59 char *path; /* ファイルのパス名 */ 63 60 } SIOPINIB; 64 61 65 62 /* 66 * シリアルI/Oポート管理ブロックの定義63 * SIOポート管理ブロックの定義 67 64 */ 68 65 struct sio_port_control_block { 69 const SIOPINIB *p_siopinib; 70 intptr_t exinf; 71 bool_t openflag; 72 serial_t serial; 66 const SIOPINIB *p_siopinib; /* SIOポート初期化ブロック */ 67 intptr_t exinf; /* 拡張情報 */ 68 bool_t opened; /* オープン済みフラグ */ 69 struct termios saved_term; /* 元の端末制御情報 */ 70 71 int_t read_fd; /* 読出し用ファイルディスクリプタ */ 72 bool_t rcv_flag; /* 受信文字バッファ有効フラグ */ 73 char rcv_buf; /* 受信文字バッファ */ 74 bool_t rcv_rdy; /* 受信通知コールバック許可フラグ */ 75 76 int_t write_fd; /* 書込み用ファイルディスクリプタ */ 77 bool_t snd_flag; /* 送信文字バッファ有効フラグ */ 78 char snd_buf; /* 送信文字バッファ */ 79 bool_t snd_rdy; /* 送信通知コールバック許可フラグ */ 73 80 }; 74 81 75 82 /* 76 * シリアルI/Oポート管理ブロックのエリア 77 */ 78 SIOPCB siopcb_table[TNUM_PORT]; 79 80 static const SIOPINIB siopinib_table[TNUM_SIOP] = 81 { 82 { P20, P21 }, 83 #if TNUM_SIOP > 1 84 { P50, P52 }, 85 #endif 86 #if TNUM_SIOP > 2 87 { P32, P33 }, 88 #endif 89 #if TNUM_SIOP > 3 90 { PC7, PC6 }, 91 #endif 92 #if TNUM_SIOP > 4 93 { P26, P30 }, 94 #endif 95 #if TNUM_SIOP > 5 96 { PB5, P25 }, 97 #endif 98 #if TNUM_SIOP > 6 99 { PA0, PC2 }, 100 #endif 83 * SIOポート初期化ブロック 84 */ 85 const SIOPINIB siopinib_table[TNUM_SIOP] = { 86 { NULL } 101 87 }; 102 88 103 89 /* 104 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ 105 */ 106 #define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1)) 107 #define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)])) 108 #define get_siopinib(siopid) (&(siopinib_table[INDEX_SIOP(siopid)])) 109 110 static void mbed_serial_irq_handler(uint32_t id, SerialIrq event); 90 * SIOポート管理ブロックのエリア 91 */ 92 SIOPCB siopcb_table[TNUM_SIOP]; 93 94 /* 95 * SIOポートIDから管理ブロックを取り出すためのマクロ 96 */ 97 #define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1)) 98 #define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)])) 111 99 112 100 /* … … 120 108 121 109 /* 122 * シリアルI/Oポート管理ブロックの初期化110 * SIOポート管理ブロックの初期化 123 111 */ 124 for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) { 112 for (i = 0; i < TNUM_SIOP; i++) { 113 p_siopcb = &(siopcb_table[i]); 125 114 p_siopcb->p_siopinib = &(siopinib_table[i]); 126 p_siopcb->openflag = false; 127 } 128 } 129 130 /* 131 * シリアルI/Oポートのオープン 115 p_siopcb->opened = false; 116 } 117 } 118 119 /* 120 * SIOドライバの終了処理 121 */ 122 void 123 sio_terminate(intptr_t exinf) 124 { 125 uint_t i; 126 127 /* 128 * オープンされているSIOポートのクローズ 129 */ 130 for (i = 0; i < TNUM_SIOP; i++) { 131 sio_cls_por(&(siopcb_table[i])); 132 } 133 } 134 135 /* 136 * SIOポートのオープン 132 137 */ 133 138 SIOPCB * 134 139 sio_opn_por(ID siopid, intptr_t exinf) 135 140 { 136 SIOPCB *p_siopcb = NULL; 137 ER ercd; 138 serial_t *serial; 139 140 if ((siopid <= 0) || (siopid > (sizeof(siopcb_table) / sizeof(siopcb_table[0])))) 141 return NULL; 141 SIOPCB *p_siopcb; 142 const SIOPINIB *p_siopinib; 143 int_t fd; 144 struct termios term; 145 142 146 p_siopcb = get_siopcb(siopid); 143 144 if (p_siopcb->openflag) 145 return NULL; 146 p_siopcb->openflag = true; 147 p_siopcb->exinf = exinf; 148 149 serial = &p_siopcb->serial; 150 serial_init(serial, p_siopcb->p_siopinib->tx, p_siopcb->p_siopinib->rx); 151 serial_baud(serial, UART_BAUDRATE); 152 serial_format(serial, 8, ParityNone, 1); 153 154 serial_irq_handler(serial, mbed_serial_irq_handler, siopid); 155 156 return p_siopcb; 157 } 158 159 /* 160 * シリアルI/Oポートのクローズ 147 p_siopinib = p_siopcb->p_siopinib; 148 149 if (!(p_siopcb->opened)) { 150 if (p_siopinib->path != NULL) { 151 fd = siofd_open(p_siopinib->path, O_RDWR, 0777); 152 assert(fd >= 0); 153 p_siopcb->read_fd = fd; 154 p_siopcb->write_fd = fd; 155 } 156 else { 157 fd = STDIN_FILENO; /* 標準入出力を使う */ 158 p_siopcb->read_fd = STDIN_FILENO; 159 p_siopcb->write_fd = STDOUT_FILENO; 160 } 161 siofd_fcntl(fd, F_SETOWN, getpid()); 162 siofd_fcntl(fd, F_SETFL, (O_NONBLOCK | O_ASYNC)); 163 164 siofd_tcgetattr(fd, &(p_siopcb->saved_term)); 165 term = p_siopcb->saved_term; 166 term.c_lflag &= ~(ECHO | ICANON); 167 siofd_tcsetattr(fd, TCSAFLUSH, &term); 168 169 p_siopcb->exinf = exinf; 170 p_siopcb->rcv_flag = false; 171 p_siopcb->rcv_rdy = false; 172 p_siopcb->snd_flag = false; 173 p_siopcb->snd_rdy = false; 174 p_siopcb->opened = true; 175 } 176 return(p_siopcb); 177 } 178 179 /* 180 * SIOポートのクローズ 161 181 */ 162 182 void 163 183 sio_cls_por(SIOPCB *p_siopcb) 164 184 { 165 ER ercd; 166 serial_t *serial = &p_siopcb->serial; 167 168 /* 169 * デバイス依存のクローズ処理. 170 */ 171 serial_free(serial); 172 p_siopcb->openflag = false; 173 } 174 175 /* 176 * シリアルI/Oポートへの文字送信 185 int_t fd; 186 187 if (p_siopcb->opened) { 188 fd = p_siopcb->read_fd; 189 siofd_tcsetattr(fd, TCSAFLUSH, &(p_siopcb->saved_term)); 190 siofd_fcntl(fd, F_SETFL, 0); 191 192 if (p_siopcb->p_siopinib->path != NULL) { 193 siofd_close(p_siopcb->read_fd); 194 } 195 196 p_siopcb->opened = false; 197 } 198 } 199 200 /* 201 * SIOの割込みサービスルーチン 202 */ 203 bool_t 204 sio_isr_snd(ID siopid) 205 { 206 SIOPCB *p_siopcb = get_siopcb(siopid); 207 int_t n; 208 209 if (p_siopcb->snd_flag) { 210 if ((n = siofd_write(p_siopcb->write_fd, &(p_siopcb->snd_buf), 1)) > 0) { 211 p_siopcb->snd_flag = false; 212 if (p_siopcb->snd_rdy) { 213 sio_irdy_snd(p_siopcb->exinf); 214 return p_siopcb->snd_rdy; 215 } 216 } 217 } 218 219 return false; 220 } 221 222 /* 223 * SIOの割込みサービスルーチン 224 */ 225 bool_t 226 sio_isr_rcv(ID siopid, char c) 227 { 228 SIOPCB *p_siopcb = get_siopcb(siopid); 229 230 if (!p_siopcb->rcv_flag) { 231 p_siopcb->rcv_buf = c; 232 p_siopcb->rcv_flag = true; 233 if (p_siopcb->rcv_rdy) { 234 sio_irdy_rcv(p_siopcb->exinf); 235 return p_siopcb->rcv_rdy; 236 } 237 } 238 239 return false; 240 } 241 242 /* 243 * SIOポートへの文字送信 177 244 */ 178 245 bool_t 179 246 sio_snd_chr(SIOPCB *p_siopcb, char c) 180 247 { 181 serial_t *serial = &p_siopcb->serial; 182 if (!serial_writable(serial)) 183 return false; 184 serial_putc(serial, c); 185 return true; 186 } 187 188 /* 189 * シリアルI/Oポートからの文字受信 248 int_t n; 249 250 if (!p_siopcb->snd_flag) { 251 if ((n = siofd_write(p_siopcb->write_fd, &c, 1)) > 0) { 252 return(true); 253 } 254 else { 255 assert(n < 0 && errno == EAGAIN); 256 p_siopcb->snd_flag = true; 257 p_siopcb->snd_buf = c; 258 return(true); 259 } 260 } 261 else { 262 return(false); 263 } 264 } 265 266 /* 267 * SIOポートからの文字受信 190 268 */ 191 269 int_t 192 270 sio_rcv_chr(SIOPCB *p_siopcb) 193 271 { 194 serial_t *serial = &p_siopcb->serial; 195 if (!serial_readable(serial)) 196 return -1; 197 return serial_getc(serial); 198 } 199 200 /* 201 * シリアルI/Oポートからのコールバックの許可 272 char c; 273 int_t n; 274 275 if (p_siopcb->rcv_flag) { 276 p_siopcb->rcv_flag = false; 277 return((int_t)(uint8_t)(p_siopcb->rcv_buf)); 278 } 279 else if ((n = siofd_read(p_siopcb->read_fd, &c, 1)) > 0) { 280 return((int_t)(uint8_t) c); 281 } 282 else { 283 assert(n < 0 && errno == EAGAIN); 284 return(-1); 285 } 286 } 287 288 /* 289 * SIOポートからのコールバックの許可 202 290 */ 203 291 void 204 292 sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn) 205 293 { 206 serial_t *serial = &p_siopcb->serial;207 294 switch (cbrtn) { 208 295 case SIO_RDY_SND: 209 serial_irq_set(serial, TxIrq, true);296 p_siopcb->snd_rdy = true; 210 297 break; 211 298 case SIO_RDY_RCV: 212 serial_irq_set(serial, RxIrq, true);299 p_siopcb->rcv_rdy = true; 213 300 break; 214 301 } … … 216 303 217 304 /* 218 * シリアルI/Oポートからのコールバックの禁止305 * SIOポートからのコールバックの禁止 219 306 */ 220 307 void 221 308 sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn) 222 309 { 223 serial_t *serial = &p_siopcb->serial;224 310 switch (cbrtn) { 225 311 case SIO_RDY_SND: 226 serial_irq_set(serial, TxIrq, false);312 p_siopcb->snd_rdy = false; 227 313 break; 228 314 case SIO_RDY_RCV: 229 serial_irq_set(serial, RxIrq, false);315 p_siopcb->rcv_rdy = false; 230 316 break; 231 317 } 232 318 } 233 234 /*235 * シリアルI/Oポートからの送信可能コールバック236 */237 void238 serial_irdy_snd(SIOPCB *p_siopcb)239 {240 /* 共通部(syssvc\serial.c)にあるsio_irdy_snd関数を呼び出し*/241 sio_irdy_snd(p_siopcb->exinf);242 }243 244 /*245 * シリアルI/Oポートからの受信通知コールバック246 */247 void248 serial_irdy_rcv(SIOPCB *p_siopcb)249 {250 /* 共通部(syssvc\serial.c)にあるsio_irdy_rcv関数を呼び出し*/251 sio_irdy_rcv(p_siopcb->exinf);252 }253 254 /*255 * SIOの割込みハンドラ256 */257 void258 mbed_serial_irq_handler(uint32_t siopid, SerialIrq event)259 {260 SIOPCB *p_siopcb;261 262 if ((siopid <= 0) || (siopid > (sizeof(siopcb_table) / sizeof(siopcb_table[0]))))263 return;264 p_siopcb = get_siopcb(siopid);265 266 if (!p_siopcb->openflag)267 return;268 269 switch (event) {270 case TxIrq:271 serial_irdy_snd(p_siopcb);272 break;273 case RxIrq:274 serial_irdy_rcv(p_siopcb);275 break;276 }277 }
Note:
See TracChangeset
for help on using the changeset viewer.