source: UsbWattMeter/trunk/asp_dcre/syssvc/serial.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 8 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 19.4 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) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
12 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
13 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
14 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
15 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
16 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
17 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
18 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
19ƒƒ“ƒgi—˜—p
20 * ŽÒƒ}ƒjƒ…
21ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
22 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
23 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
24 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
25 * ‚ƁD
26 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
27ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
28ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
29 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
30 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
31 * •ñ‚·‚邱‚ƁD
32 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
33 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
34 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
35 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
36 * –Ɛӂ·‚邱‚ƁD
37 *
38 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
39 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
40 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
41 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
42 * ‚̐ӔC‚𕉂í‚È‚¢D
43 *
44 * @(#) $Id: serial.c 164 2016-03-07 11:33:50Z coas-nagasima $
45 */
46
47/*
48 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo
49 */
50
51#include <kernel.h>
52#include <t_syslog.h>
53#include "target_syssvc.h"
54#include "target_serial.h"
55#include "serial.h"
56#include "kernel_cfg.h"
57
58/*
59 * ƒoƒbƒtƒ@ƒTƒCƒY‚̃fƒtƒHƒ‹ƒg’l‚ƃoƒbƒtƒ@‚Ì’è‹`
60 */
61#ifndef SERIAL_RCV_BUFSZ1
62#define SERIAL_RCV_BUFSZ1 256 /* ƒ|[ƒg1‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
63#endif /* SERIAL_RCV_BUFSZ1 */
64
65#ifndef SERIAL_SND_BUFSZ1
66#define SERIAL_SND_BUFSZ1 256 /* ƒ|[ƒg1‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
67#endif /* SERIAL_SND_BUFSZ1 */
68
69static char rcv_buffer1[SERIAL_RCV_BUFSZ1];
70static char snd_buffer1[SERIAL_SND_BUFSZ1];
71
72#if TNUM_PORT >= 2 /* ƒ|[ƒg2‚ÉŠÖ‚·‚é’è‹` */
73
74#ifndef SERIAL_RCV_BUFSZ2
75#define SERIAL_RCV_BUFSZ2 256 /* ƒ|[ƒg2‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
76#endif /* SERIAL_RCV_BUFSZ2 */
77
78#ifndef SERIAL_SND_BUFSZ2
79#define SERIAL_SND_BUFSZ2 256 /* ƒ|[ƒg2‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
80#endif /* SERIAL_SND_BUFSZ2 */
81
82static char rcv_buffer2[SERIAL_RCV_BUFSZ2];
83static char snd_buffer2[SERIAL_SND_BUFSZ2];
84
85#endif /* TNUM_PORT >= 2 */
86
87#if TNUM_PORT >= 3 /* ƒ|[ƒg3‚ÉŠÖ‚·‚é’è‹` */
88
89#ifndef SERIAL_RCV_BUFSZ3
90#define SERIAL_RCV_BUFSZ3 256 /* ƒ|[ƒg3‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
91#endif /* SERIAL_RCV_BUFSZ3 */
92
93#ifndef SERIAL_SND_BUFSZ3
94#define SERIAL_SND_BUFSZ3 256 /* ƒ|[ƒg3‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
95#endif /* SERIAL_SND_BUFSZ3 */
96
97static char rcv_buffer3[SERIAL_RCV_BUFSZ3];
98static char snd_buffer3[SERIAL_SND_BUFSZ3];
99
100#endif /* TNUM_PORT >= 3 */
101
102#if TNUM_PORT >= 4 /* ƒ|[ƒg4‚ÉŠÖ‚·‚é’è‹` */
103
104#ifndef SERIAL_RCV_BUFSZ4
105#define SERIAL_RCV_BUFSZ4 256 /* ƒ|[ƒg4‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
106#endif /* SERIAL_RCV_BUFSZ4 */
107
108#ifndef SERIAL_SND_BUFSZ4
109#define SERIAL_SND_BUFSZ4 256 /* ƒ|[ƒg4‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
110#endif /* SERIAL_SND_BUFSZ4 */
111
112static char rcv_buffer4[SERIAL_RCV_BUFSZ4];
113static char snd_buffer4[SERIAL_SND_BUFSZ4];
114
115#endif /* TNUM_PORT >= 4 */
116
117#if TNUM_PORT >= 5 /* ƒ|[ƒg5‚ÉŠÖ‚·‚é’è‹` */
118
119#ifndef SERIAL_RCV_BUFSZ5
120#define SERIAL_RCV_BUFSZ5 256 /* ƒ|[ƒg5‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
121#endif /* SERIAL_RCV_BUFSZ5 */
122
123#ifndef SERIAL_SND_BUFSZ5
124#define SERIAL_SND_BUFSZ5 256 /* ƒ|[ƒg5‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
125#endif /* SERIAL_SND_BUFSZ5 */
126
127static char rcv_buffer5[SERIAL_RCV_BUFSZ5];
128static char snd_buffer5[SERIAL_SND_BUFSZ5];
129
130#endif /* TNUM_PORT >= 5 */
131
132#if TNUM_PORT >= 6 /* ƒ|[ƒg6‚ÉŠÖ‚·‚é’è‹` */
133
134#ifndef SERIAL_RCV_BUFSZ6
135#define SERIAL_RCV_BUFSZ6 256 /* ƒ|[ƒg6‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
136#endif /* SERIAL_RCV_BUFSZ6 */
137
138#ifndef SERIAL_SND_BUFSZ6
139#define SERIAL_SND_BUFSZ6 256 /* ƒ|[ƒg6‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
140#endif /* SERIAL_SND_BUFSZ6 */
141
142static char rcv_buffer6[SERIAL_RCV_BUFSZ6];
143static char snd_buffer6[SERIAL_SND_BUFSZ6];
144
145#endif /* TNUM_PORT >= 6 */
146
147#if TNUM_PORT >= 7
148#error Serial interface driver supports up to 6 ports.
149#endif /* TNUM_PORT >= 7 */
150
151/*
152 * ƒtƒ[§Œä‚ÉŠÖ˜A‚·‚é’萔‚ƃ}ƒNƒ
153 */
154#define FC_STOP '\023' /* ƒRƒ“ƒgƒ[ƒ‹-S */
155#define FC_START '\021' /* ƒRƒ“ƒgƒ[ƒ‹-Q */
156
157#define BUFCNT_STOP(bufsz) ((bufsz) * 3 / 4) /* STOP‚ð‘—‚éŠî€•¶Žš” */
158#define BUFCNT_START(bufsz) ((bufsz) / 2) /* START‚ð‘—‚éŠî€•¶Žš” */
159
160/*
161 * ƒVƒŠƒAƒ‹ƒ|[ƒg‰Šú‰»ƒuƒƒbƒN
162 */
163typedef struct serial_port_initialization_block {
164 ID rcv_semid; /* ŽóMƒoƒbƒtƒ@ŠÇ——pƒZƒ}ƒtƒH‚ÌID */
165 ID snd_semid; /* ‘—Mƒoƒbƒtƒ@ŠÇ——pƒZƒ}ƒtƒH‚ÌID */
166 uint_t rcv_bufsz; /* ŽóMƒoƒbƒtƒ@ƒTƒCƒY */
167 char *rcv_buffer; /* ŽóMƒoƒbƒtƒ@ */
168 uint_t snd_bufsz; /* ‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
169 char *snd_buffer; /* ‘—Mƒoƒbƒtƒ@ */
170} SPINIB;
171
172static const SPINIB spinib_table[TNUM_PORT] = {
173 { SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
174 SERIAL_RCV_BUFSZ1, rcv_buffer1,
175 SERIAL_SND_BUFSZ1, snd_buffer1 },
176#if TNUM_PORT >= 2
177 { SERIAL_RCV_SEM2, SERIAL_SND_SEM2,
178 SERIAL_RCV_BUFSZ2, rcv_buffer2,
179 SERIAL_SND_BUFSZ2, snd_buffer2 },
180#endif /* TNUM_PORT >= 2 */
181#if TNUM_PORT >= 3
182 { SERIAL_RCV_SEM3, SERIAL_SND_SEM3,
183 SERIAL_RCV_BUFSZ3, rcv_buffer3,
184 SERIAL_SND_BUFSZ3, snd_buffer3 },
185#endif /* TNUM_PORT >= 3 */
186#if TNUM_PORT >= 4
187 { SERIAL_RCV_SEM4, SERIAL_SND_SEM4,
188 SERIAL_RCV_BUFSZ4, rcv_buffer4,
189 SERIAL_SND_BUFSZ4, snd_buffer4 },
190#endif /* TNUM_PORT >= 4 */
191};
192
193/*
194 * ƒVƒŠƒAƒ‹ƒ|[ƒgŠÇ—ƒuƒƒbƒN
195 */
196typedef struct serial_port_control_block {
197 const SPINIB *p_spinib; /* ƒVƒŠƒAƒ‹ƒ|[ƒg‰Šú‰»ƒuƒƒbƒN */
198 SIOPCB *p_siopcb; /* ƒVƒŠƒAƒ‹I/Oƒ|[ƒgŠÇ—ƒuƒƒbƒN */
199 bool_t openflag; /* ƒI[ƒvƒ“Ï‚݃tƒ‰ƒO */
200 bool_t errorflag; /* ƒGƒ‰[ƒtƒ‰ƒO */
201 uint_t ioctl; /* “®ì§Œä‚̐ݒè’l */
202
203 uint_t rcv_read_ptr; /* ŽóMƒoƒbƒtƒ@“Ǐo‚µƒ|ƒCƒ“ƒ^ */
204 uint_t rcv_write_ptr; /* ŽóMƒoƒbƒtƒ@‘ž‚݃|ƒCƒ“ƒ^ */
205 uint_t rcv_count; /* ŽóMƒoƒbƒtƒ@’†‚Ì•¶Žš” */
206 char rcv_fc_chr; /* ‘—‚é‚ׂ«START/STOP */
207 bool_t rcv_stopped; /* STOP‚ð‘—‚Á‚½ó‘Ô‚©H */
208
209 uint_t snd_read_ptr; /* ‘—Mƒoƒbƒtƒ@“Ǐo‚µƒ|ƒCƒ“ƒ^ */
210 uint_t snd_write_ptr; /* ‘—Mƒoƒbƒtƒ@‘ž‚݃|ƒCƒ“ƒ^ */
211 uint_t snd_count; /* ‘—Mƒoƒbƒtƒ@’†‚Ì•¶Žš” */
212 bool_t snd_stopped; /* STOP‚ðŽó‚¯Žæ‚Á‚½ó‘Ô‚©H */
213} SPCB;
214
215static SPCB spcb_table[TNUM_PORT];
216
217/*
218 * ƒVƒŠƒAƒ‹ƒ|[ƒgID‚©‚çƒVƒŠƒAƒ‹ƒ|[ƒgŠÇ—ƒuƒƒbƒN‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
219 */
220#define INDEX_PORT(portid) ((uint_t)((portid) - 1))
221#define get_spcb(portid) (&(spcb_table[INDEX_PORT(portid)]))
222
223/*
224 * ƒ|ƒCƒ“ƒ^‚̃Cƒ“ƒNƒŠƒƒ“ƒg
225 */
226#define INC_PTR(ptr, bufsz) do { \
227 if (++(ptr) == (bufsz)) { \
228 (ptr) = 0; \
229 } \
230} while(false)
231
232/*
233 * ƒT[ƒrƒXƒR[ƒ‹ŒÄo‚µƒ}ƒNƒ
234 *
235 * ƒT[ƒrƒXƒR[ƒ‹ŒÄo‚µ‚ðŠÜ‚ÞŽ®exp‚ð•]‰¿‚µC•Ô’l‚ªƒGƒ‰[i•‰‚Ì’lj‚̏ê
236 * ‡‚ɂ́Cerc‚Éercd_exp‚ð•]‰¿‚µ‚½’l‚ð‘ã“ü‚µCerror_exit‚Égoto‚·‚éD
237 */
238#define SVC(exp, ercd_exp) do { \
239 if ((exp) < 0) { \
240 ercd = (ercd_exp); \
241 goto error_exit; \
242 } \
243} while(false)
244
245/*
246 * E_SYSƒGƒ‰[‚̐¶¬
247 */
248static ER
249gen_ercd_sys(SPCB *p_spcb)
250{
251 p_spcb->errorflag = true;
252 return(E_SYS);
253}
254
255/*
256 * ‘Ò‚¿‚É“ü‚éƒT[ƒrƒXƒR[ƒ‹‚©‚ç‚̃Gƒ‰[‚Ì•ÏŠ·
257 */
258static ER
259gen_ercd_wait(ER rercd, SPCB *p_spcb)
260{
261 switch (MERCD(rercd)) {
262 case E_RLWAI:
263 case E_DLT:
264 return(rercd);
265 default:
266 p_spcb->errorflag = true;
267 return(E_SYS);
268 }
269}
270
271/*
272 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo‚̏‰Šú‰»ƒ‹[ƒ`ƒ“
273 */
274void
275serial_initialize(intptr_t exinf)
276{
277 uint_t i;
278 SPCB *p_spcb;
279
280 for (i = 0; i < TNUM_PORT; i++) {
281 p_spcb = &(spcb_table[i]);
282 p_spcb->p_spinib = &(spinib_table[i]);
283 p_spcb->openflag = false;
284 }
285}
286
287/*
288 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̃I[ƒvƒ“iƒT[ƒrƒXƒR[ƒ‹j
289 */
290ER
291serial_opn_por(ID portid)
292{
293 SPCB *p_spcb;
294 ER ercd;
295
296 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
297 return(E_CTX);
298 }
299 if (!(1 <= portid && portid <= TNUM_PORT)) {
300 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
301 }
302 p_spcb = get_spcb(portid);
303
304 SVC(dis_dsp(), gen_ercd_sys(p_spcb));
305 if (p_spcb->openflag) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
306 ercd = E_OBJ;
307 }
308 else {
309 /*
310 * •Ï”‚̏‰Šú‰»
311 */
312 p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
313
314 p_spcb->rcv_read_ptr = 0U;
315 p_spcb->rcv_write_ptr = 0U;
316 p_spcb->rcv_count = 0U;
317 p_spcb->rcv_fc_chr = '\0';
318 p_spcb->rcv_stopped = false;
319
320 p_spcb->snd_read_ptr = 0U;
321 p_spcb->snd_write_ptr = 0U;
322 p_spcb->snd_count = 0U;
323 p_spcb->snd_stopped = false;
324
325 /*
326 * ‚±‚êˆÈ~CŠ„ž‚Ý‚ð‹ÖŽ~‚·‚éD
327 */
328 if (loc_cpu() < 0) {
329 ercd = E_SYS;
330 goto error_exit_enadsp;
331 }
332
333 /*
334 * ƒn[ƒhƒEƒFƒAˆË‘¶‚̃I[ƒvƒ“ˆ—
335 */
336 p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
337
338 /*
339 * ŽóM’Ê’mƒR[ƒ‹ƒoƒbƒN‚ð‹–‰Â‚·‚éD
340 */
341 sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
342 p_spcb->openflag = true;
343 p_spcb->errorflag = false;
344
345 if (unl_cpu() < 0) {
346 p_spcb->errorflag = true;
347 ercd = E_SYS;
348 goto error_exit_enadsp;
349 }
350 ercd = E_OK;
351 }
352
353 error_exit_enadsp:
354 SVC(ena_dsp(), gen_ercd_sys(p_spcb));
355
356 error_exit:
357 return(ercd);
358}
359
360/*
361 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̃Nƒ[ƒYiƒT[ƒrƒXƒR[ƒ‹j
362 */
363ER
364serial_cls_por(ID portid)
365{
366 SPCB *p_spcb;
367 ER ercd;
368 bool_t eflag = false;
369
370 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
371 return(E_CTX);
372 }
373 if (!(1 <= portid && portid <= TNUM_PORT)) {
374 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
375 }
376 p_spcb = get_spcb(portid);
377
378 SVC(dis_dsp(), gen_ercd_sys(p_spcb));
379 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
380 ercd = E_OBJ;
381 }
382 else {
383 /*
384 * ƒn[ƒhƒEƒFƒAˆË‘¶‚̃Nƒ[ƒYˆ—
385 */
386 if (loc_cpu() < 0) {
387 eflag = true;
388 }
389 sio_cls_por(p_spcb->p_siopcb);
390 p_spcb->openflag = false;
391 if (unl_cpu() < 0) {
392 eflag = true;
393 }
394
395 /*
396 * ƒZƒ}ƒtƒH‚̏‰Šú‰»
397 */
398 if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
399 eflag = true;
400 }
401 if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
402 eflag = true;
403 }
404
405 /*
406 * ƒGƒ‰[ƒR[ƒh‚̐ݒè
407 */
408 if (eflag) {
409 ercd = gen_ercd_sys(p_spcb);
410 }
411 else {
412 ercd = E_OK;
413 }
414 }
415 SVC(ena_dsp(), gen_ercd_sys(p_spcb));
416
417 error_exit:
418 return(ercd);
419}
420
421/*
422 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì•¶Žš‘—M
423 *
424 * p_spcb‚ÅŽw’肳‚ê‚éƒVƒŠƒAƒ‹I/Oƒ|[ƒg‚ɑ΂µ‚āC•¶Žšc‚𑗐M‚·‚éD•¶Žš
425 * ‚𑗐MƒŒƒWƒXƒ^‚É‚¢‚ꂽê‡‚É‚Ítrue‚ð•Ô‚·D‚»‚¤‚Å‚È‚¢ê‡‚ɂ́C‘—M
426 * ƒŒƒWƒXƒ^‚ª‹ó‚¢‚½‚±‚Æ‚ð’Ê’m‚·‚éƒR[ƒ‹ƒoƒbƒNŠÖ”‚ð‹–‰Â‚µCfalse‚ð•Ô‚·D
427 * ‚±‚̊֐”‚́CCPUƒƒbƒNó‘ԂŌĂяo‚³‚ê‚éD
428 */
429Inline bool_t
430serial_snd_chr(SPCB *p_spcb, char c)
431{
432 if (sio_snd_chr(p_spcb->p_siopcb, c)) {
433 return(true);
434 }
435 else {
436 sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
437 return(false);
438 }
439}
440
441/*
442 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì1•¶Žš‘—M
443 */
444static ER_BOOL
445serial_wri_chr(SPCB *p_spcb, char c)
446{
447 bool_t buffer_full;
448 ER ercd, rercd;
449
450 /*
451 * LF‚Ì‘O‚ÉCR‚𑗐M‚·‚éD
452 */
453 if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
454 /*
455 * ˆÈ‰º‚̃R[ƒh‚͍ċAŒÄo‚µ‚É‚È‚Á‚Ä‚¢‚邪Cˆø”c‚ª'\n'‚̏ꍇ‚É
456 * ˆø”c‚ð'\r'‚Æ‚µ‚ČĂяo‚·‚±‚Æ‚©‚çC‚±‚̍ċAŒÄo‚µ‚Í2‰ñ–Ú‚Ì
457 * ŒÄ‚яo‚µ‚Å•K‚¸Ž~‚Ü‚éD
458 */
459 SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
460 if ((bool_t) rercd) {
461 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
462 gen_ercd_wait(rercd, p_spcb));
463 }
464 }
465
466 SVC(loc_cpu(), gen_ercd_sys(p_spcb));
467 if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
468 && serial_snd_chr(p_spcb, c)) {
469 /*
470 * ƒVƒŠƒAƒ‹I/OƒfƒoƒCƒX‚Ì‘—MƒŒƒWƒXƒ^‚É•¶Žš‚ð“ü‚ê‚邱‚Ƃɐ¬Œ÷‚µ
471 * ‚½ê‡D
472 */
473 buffer_full = false;
474 }
475 else {
476 /*
477 * ‘—Mƒoƒbƒtƒ@‚É•¶Žš‚ð“ü‚ê‚éD
478 */
479 p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
480 INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
481 p_spcb->snd_count++;
482 buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
483 }
484
485 SVC(unl_cpu(), gen_ercd_sys(p_spcb));
486 ercd = (ER_BOOL) buffer_full;
487
488 error_exit:
489 return(ercd);
490}
491
492/*
493 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì•¶Žš—ñ‘—MiƒT[ƒrƒXƒR[ƒ‹j
494 */
495ER_UINT
496serial_wri_dat(ID portid, const char *buf, uint_t len)
497{
498 SPCB *p_spcb;
499 bool_t buffer_full;
500 uint_t wricnt = 0U;
501 ER ercd, rercd;
502
503 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
504 return(E_CTX);
505 }
506 if (!(1 <= portid && portid <= TNUM_PORT)) {
507 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
508 }
509
510 p_spcb = get_spcb(portid);
511 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
512 return(E_OBJ);
513 }
514 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
515 return(E_SYS);
516 }
517
518 buffer_full = true; /* ƒ‹[ƒv‚Ì1‰ñ‚ß‚Íwai_sem‚·‚é */
519 while (wricnt < len) {
520 if (buffer_full) {
521 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
522 gen_ercd_wait(rercd, p_spcb));
523 }
524 SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
525 wricnt++;
526 buffer_full = (bool_t) rercd;
527 }
528 if (!buffer_full) {
529 SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
530 }
531 ercd = E_OK;
532
533 error_exit:
534 return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
535}
536
537/*
538 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì1•¶ŽšŽóM
539 */
540static bool_t
541serial_rea_chr(SPCB *p_spcb, char *p_c)
542{
543 bool_t buffer_empty;
544 ER ercd;
545
546 SVC(loc_cpu(), gen_ercd_sys(p_spcb));
547
548 /*
549 * ŽóMƒoƒbƒtƒ@‚©‚當Žš‚ðŽæ‚èo‚·D
550 */
551 *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
552 INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
553 p_spcb->rcv_count--;
554 buffer_empty = (p_spcb->rcv_count == 0U);
555
556 /*
557 * START‚𑗐M‚·‚éD
558 */
559 if (p_spcb->rcv_stopped && p_spcb->rcv_count
560 <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
561 if (!serial_snd_chr(p_spcb, FC_START)) {
562 p_spcb->rcv_fc_chr = FC_START;
563 }
564 p_spcb->rcv_stopped = false;
565 }
566
567 SVC(unl_cpu(), gen_ercd_sys(p_spcb));
568 ercd = (ER_BOOL) buffer_empty;
569
570 error_exit:
571 return(ercd);
572}
573
574/*
575 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì•¶Žš—ñŽóMiƒT[ƒrƒXƒR[ƒ‹j
576 */
577ER_UINT
578serial_rea_dat(ID portid, char *buf, uint_t len)
579{
580 SPCB *p_spcb;
581 bool_t buffer_empty;
582 uint_t reacnt = 0U;
583 char c = '\0'; /* ƒRƒ“ƒpƒCƒ‰‚ÌŒx‚ð—}Ž~‚·‚邽‚߂ɏ‰Šú‰»‚·‚é */
584 ER ercd, rercd;
585
586 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
587 return(E_CTX);
588 }
589 if (!(1 <= portid && portid <= TNUM_PORT)) {
590 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
591 }
592
593 p_spcb = get_spcb(portid);
594 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
595 return(E_OBJ);
596 }
597 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
598 return(E_SYS);
599 }
600
601 buffer_empty = true; /* ƒ‹[ƒv‚Ì1‰ñ‚ß‚Íwai_sem‚·‚é */
602 while (reacnt < len) {
603 if (buffer_empty) {
604 SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
605 gen_ercd_wait(rercd, p_spcb));
606 }
607 SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
608 *buf++ = c;
609 reacnt++;
610 buffer_empty = (bool_t) rercd;
611
612 /*
613 * ƒGƒR[ƒoƒbƒNˆ—D
614 */
615 if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
616 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
617 gen_ercd_wait(rercd, p_spcb));
618 SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
619 if (!((bool_t) rercd)) {
620 SVC(sig_sem(p_spcb->p_spinib->snd_semid),
621 gen_ercd_sys(p_spcb));
622 }
623 }
624 }
625 if (!buffer_empty) {
626 SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
627 }
628 ercd = E_OK;
629
630 error_exit:
631 return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
632}
633
634/*
635 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̐§ŒäiƒT[ƒrƒXƒR[ƒ‹j
636 */
637ER
638serial_ctl_por(ID portid, uint_t ioctl)
639{
640 SPCB *p_spcb;
641
642 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
643 return(E_CTX);
644 }
645 if (!(1 <= portid && portid <= TNUM_PORT)) {
646 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
647 }
648
649 p_spcb = get_spcb(portid);
650 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
651 return(E_OBJ);
652 }
653 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
654 return(E_SYS);
655 }
656
657 p_spcb->ioctl = ioctl;
658 return(E_OK);
659}
660
661/*
662 * ƒVƒŠƒAƒ‹ƒ|[ƒgó‘Ô‚ÌŽQÆiƒT[ƒrƒXƒR[ƒ‹j
663 */
664ER
665serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
666{
667 SPCB *p_spcb;
668
669 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
670 return(E_CTX);
671 }
672 if (!(1 <= portid && portid <= TNUM_PORT)) {
673 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
674 }
675
676 p_spcb = get_spcb(portid);
677 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
678 return(E_OBJ);
679 }
680 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
681 return(E_SYS);
682 }
683
684 pk_rpor->reacnt = p_spcb->rcv_count;
685 pk_rpor->wricnt = p_spcb->snd_count;
686 return(E_OK);
687}
688
689/*
690 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì‘—M‰Â”\ƒR[ƒ‹ƒoƒbƒN
691 */
692void
693sio_irdy_snd(intptr_t exinf)
694{
695 SPCB *p_spcb;
696
697 p_spcb = (SPCB *) exinf;
698 if (p_spcb->rcv_fc_chr != '\0') {
699 /*
700 * START/STOP ‚𑗐M‚·‚éD
701 */
702 (void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
703 p_spcb->rcv_fc_chr = '\0';
704 }
705 else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
706 /*
707 * ‘—Mƒoƒbƒtƒ@’†‚©‚當Žš‚ðŽæ‚èo‚µ‚Ä‘—M‚·‚éD
708 */
709 (void) sio_snd_chr(p_spcb->p_siopcb,
710 p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
711 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
712 if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
713 if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
714 p_spcb->errorflag = true;
715 }
716 }
717 p_spcb->snd_count--;
718 }
719 else {
720 /*
721 * ‘—M‚·‚ׂ«•¶Žš‚ª‚È‚¢ê‡‚́C‘—M‰Â”\ƒR[ƒ‹ƒoƒbƒN‚ð‹ÖŽ~‚·‚éD
722 */
723 sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
724 }
725}
726
727/*
728 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚ÌŽóM’Ê’mƒR[ƒ‹ƒoƒbƒN
729 */
730void
731sio_irdy_rcv(intptr_t exinf)
732{
733 SPCB *p_spcb;
734 char c;
735
736 p_spcb = (SPCB *) exinf;
737 c = (char) sio_rcv_chr(p_spcb->p_siopcb);
738 if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
739 /*
740 * ‘—M‚ðˆêŽž’âŽ~‚·‚éD‘—M’†‚Ì•¶Žš‚Í‚»‚Ì‚Ü‚Ü‘—M‚·‚éD
741 */
742 p_spcb->snd_stopped = true;
743 }
744 else if (p_spcb->snd_stopped && (c == FC_START
745 || (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
746 /*
747 * ‘—M‚ðÄŠJ‚·‚éD
748 */
749 p_spcb->snd_stopped = false;
750 if (p_spcb->snd_count > 0U) {
751 c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
752 if (serial_snd_chr(p_spcb, c)) {
753 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
754 if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
755 if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
756 p_spcb->errorflag = true;
757 }
758 }
759 p_spcb->snd_count--;
760 }
761 }
762 }
763 else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
764 /*
765 * ‘—M‚ɑ΂µ‚ătƒ[§Œä‚µ‚Ä‚¢‚éê‡CSTART ‚ÍŽÌ‚Ä‚éD
766 */
767 }
768 else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
769 /*
770 * ƒoƒbƒtƒ@ƒtƒ‹‚̏ꍇCŽóM‚µ‚½•¶Žš‚ðŽÌ‚Ä‚éD
771 */
772 }
773 else {
774 /*
775 * ŽóM‚µ‚½•¶Žš‚ðŽóMƒoƒbƒtƒ@‚É“ü‚ê‚éD
776 */
777 p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
778 INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
779 if (p_spcb->rcv_count == 0U) {
780 if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
781 p_spcb->errorflag = true;
782 }
783 }
784 p_spcb->rcv_count++;
785
786 /*
787 * STOP‚𑗐M‚·‚éD
788 */
789 if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
790 && p_spcb->rcv_count
791 >= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
792 if (!serial_snd_chr(p_spcb, FC_STOP)) {
793 p_spcb->rcv_fc_chr = FC_STOP;
794 }
795 p_spcb->rcv_stopped = true;
796 }
797 }
798}
799
800/*
801 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo‚©‚ç‚Ì–¢‘—M•¶Žš‚ÌŽæo‚µ
802 */
803bool_t
804serial_get_chr(ID portid, char *p_c)
805{
806 SPCB *p_spcb;
807
808 if (1 <= portid && portid <= TNUM_PORT) { /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
809 p_spcb = get_spcb(portid);
810 if (p_spcb->openflag) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
811 if (p_spcb->snd_count > 0U) {
812 *p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
813 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
814 p_spcb->snd_count--;
815 return(true);
816 }
817 }
818 }
819 return(false);
820}
Note: See TracBrowser for help on using the repository browser.