/* * シリアルポートからの1文字受信 */ static bool_t serial_rea_chr(SPCB *p_spcb, char *p_c) { bool_t buffer_empty; ER ercd; SVC(loc_cpu(), gen_ercd_sys(p_spcb)); /* * 受信バッファから文字を取り出す. */ *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr]; INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz); p_spcb->rcv_count--; buffer_empty = (p_spcb->rcv_count == 0U); /* * STARTを送信する. */ if (p_spcb->rcv_stopped && p_spcb->rcv_count <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) { if (!serial_snd_chr(p_spcb, FC_START)) { p_spcb->rcv_fc_chr = FC_START; } p_spcb->rcv_stopped = false; } SVC(unl_cpu(), gen_ercd_sys(p_spcb)); ercd = (ER_BOOL) buffer_empty; error_exit: return(ercd); }
/* * シリアルポートへの送信 */ static BOOL serial_wri_chr(SPCB *spcb, char c) { BOOL buffer_full; /* * LF の前に CR を送信する. */ if (c == '\n' && (spcb->ioctl & IOCTL_CRLF) != 0) { if (serial_wri_chr(spcb, '\r')) { _syscall(wai_sem(spcb->spinib->snd_semid)); } } _syscall(loc_cpu()); if (spcb->snd_count == 0 && !(spcb->snd_stopped) && serial_snd_chr(spcb, c)) { /* * シリアルI/Oデバイスの送信レジスタに文字を入れるこ * とに成功した場合. */ buffer_full = FALSE; } else { /* * 送信バッファに文字を入れる. */ spcb->snd_buffer[spcb->snd_write_ptr] = c; INC_PTR(spcb->snd_write_ptr); spcb->snd_count++; buffer_full = (spcb->snd_count == SERIAL_BUFSZ); } _syscall(unl_cpu()); return(buffer_full); }
/* * シリアルポートへの1文字送信 */ static ER_BOOL serial_wri_chr(SPCB *p_spcb, char c) { bool_t buffer_full; ER ercd, rercd; /* * LFの前にCRを送信する. */ if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) { /* * 以下のコードは再帰呼出しになっているが,引数cが'\n'の場合に * 引数cを'\r'として呼び出すことから,この再帰呼出しは2回目の * 呼び出しで必ず止まる. */ SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd); if ((bool_t) rercd) { SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid), gen_ercd_wait(rercd, p_spcb)); } } SVC(loc_cpu(), gen_ercd_sys(p_spcb)); if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped) && serial_snd_chr(p_spcb, c)) { /* * シリアルI/Oデバイスの送信レジスタに文字を入れることに成功し * た場合. */ buffer_full = false; } else { /* * 送信バッファに文字を入れる. */ p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c; INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz); p_spcb->snd_count++; buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz); } SVC(unl_cpu(), gen_ercd_sys(p_spcb)); ercd = (ER_BOOL) buffer_full; error_exit: return(ercd); }
/* * シリアルポートからの受信 */ static BOOL serial_rea_chr(SPCB *spcb, char *c) { BOOL buffer_empty; _syscall(loc_cpu()); /* * 受信バッファから文字を取り出す. */ *c = spcb->rcv_buffer[spcb->rcv_read_ptr]; INC_PTR(spcb->rcv_read_ptr); spcb->rcv_count--; buffer_empty = (spcb->rcv_count == 0); /* * START を送信する. */ if (spcb->rcv_stopped && spcb->rcv_count <= BUFCNT_START) { if (!serial_snd_chr(spcb, FC_START)) { spcb->rcv_fc_chr = FC_START; } spcb->rcv_stopped = FALSE; } _syscall(unl_cpu()); /* * エコーバック処理. */ if ((spcb->ioctl & IOCTL_ECHO) != 0) { _syscall(wai_sem(spcb->spinib->snd_semid)); if (!serial_wri_chr(spcb, *c)) { _syscall(sig_sem(spcb->spinib->snd_semid)); } } return(buffer_empty); }
/* * シリアルポートからの受信通知コールバック */ void sio_irdy_rcv(intptr_t exinf) { SPCB *p_spcb; char c; p_spcb = (SPCB *) exinf; c = (char) sio_rcv_chr(p_spcb->p_siopcb); if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) { /* * 送信を一時停止する.送信中の文字はそのまま送信する. */ p_spcb->snd_stopped = true; } else if (p_spcb->snd_stopped && (c == FC_START || (p_spcb->ioctl & IOCTL_FCANY) != 0U)) { /* * 送信を再開する. */ p_spcb->snd_stopped = false; if (p_spcb->snd_count > 0U) { c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]; if (serial_snd_chr(p_spcb, c)) { INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz); if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) { if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) { p_spcb->errorflag = true; } } p_spcb->snd_count--; } } } else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) { /* * 送信に対してフロー制御している場合,START は捨てる. */ } else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) { /* * バッファフルの場合,受信した文字を捨てる. */ } else { /* * 受信した文字を受信バッファに入れる. */ p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c; INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz); if (p_spcb->rcv_count == 0U) { if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) { p_spcb->errorflag = true; } } p_spcb->rcv_count++; /* * STOPを送信する. */ if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped) && p_spcb->rcv_count >= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) { if (!serial_snd_chr(p_spcb, FC_STOP)) { p_spcb->rcv_fc_chr = FC_STOP; } p_spcb->rcv_stopped = true; } } }
/* * シリアルポートからの受信通知コールバック */ void sio_ierdy_rcv(VP_INT exinf) { SPCB *spcb; char c; spcb = (SPCB *) exinf; c = (char) sio_rcv_chr(spcb->siopcb); if ((spcb->ioctl & IOCTL_FCSND) != 0 && c == FC_STOP) { /* * 送信を一時停止する.送信中の文字はそのまま送信する. */ spcb->snd_stopped = TRUE; } else if (spcb->snd_stopped && (c == FC_START || (spcb->ioctl & IOCTL_FCANY) != 0)) { /* * 送信を再開する. */ spcb->snd_stopped = FALSE; if (spcb->snd_count > 0) { c = spcb->snd_buffer[spcb->snd_read_ptr]; if (serial_snd_chr(spcb, c)) { INC_PTR(spcb->snd_read_ptr); if (spcb->snd_count == SERIAL_BUFSZ) { _syscall(isig_sem(spcb->spinib ->snd_semid)); } spcb->snd_count--; } } } else if ((spcb->ioctl & IOCTL_FCSND) != 0 && c == FC_START) { /* * 送信に対してフロー制御している場合,START は捨てる. */ } else if (spcb->rcv_count == SERIAL_BUFSZ) { /* * バッファフルの場合,受信した文字を捨てる. */ } else { /* * 受信した文字を受信バッファに入れる. */ spcb->rcv_buffer[spcb->rcv_write_ptr] = c; INC_PTR(spcb->rcv_write_ptr); if (spcb->rcv_count == 0) { _syscall(isig_sem(spcb->spinib->rcv_semid)); } spcb->rcv_count++; /* * STOP を送信する. */ if ((spcb->ioctl & IOCTL_FCRCV) != 0 && !(spcb->rcv_stopped) && (spcb->rcv_count >= BUFCNT_STOP)) { if (!serial_snd_chr(spcb, FC_STOP)) { spcb->rcv_fc_chr = FC_STOP; } spcb->rcv_stopped = TRUE; } } }