/* * シリアルポートのオープン */ ER serial_opn_por(ID portid) { SPCB *spcb; ER ercd; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); _syscall(loc_cpu()); if (spcb->openflag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * 変数の初期化 */ spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV); spcb->rcv_read_ptr = spcb->rcv_write_ptr = 0; spcb->rcv_count = 0; spcb->rcv_fc_chr = '\0'; spcb->rcv_stopped = FALSE; spcb->snd_read_ptr = spcb->snd_write_ptr = 0; spcb->snd_count = 0; spcb->snd_stopped = FALSE; /* * ハードウェア依存のオープン処理 */ spcb->siopcb = sio_opn_por(portid, (VP_INT) spcb); /* * 受信通知コールバックを許可する. */ sio_ena_cbr(spcb->siopcb, SIO_ERDY_RCV); spcb->openflag = TRUE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd); }
/* * シリアルI/Oポートへの非同期文字出力 */ void sio_asnd_chr( INT c ) { SIOPCB* siopcb ; UH uhBase ; int i ; /* * CPUロック状態にする */ BOOL bLocked ; if ( sns_loc() ) bLocked = TRUE ; else { bLocked = FALSE ; if ( sns_ctx() ) iloc_cpu() ; else loc_cpu() ; } /* * 非同期用ポートを開く */ if ( ( siopcb = sio_opn_por( LOGTASK_PORTID, siopcb_table[LOGTASK_PORTID-1].vpiExinf ) ) != NULL ) { uhBase = siopcb->uhBase ; /* * LFならまずCRを送出 */ if ( c == '\n' ) { for ( i = 0 ; i < TXREADY_TIMEOUT ; i++ ) { if ( __SFR(uhBase) & __UxCR_TXEMPTY ) break ; } if ( i < TXREADY_TIMEOUT ) { __SFRW(uhBase+4) = __UxTX_STOPBIT | '\r' ; } } /* * データ送出 */ for ( i = 0 ; i < TXREADY_TIMEOUT ; i++ ) { if ( __SFR(uhBase) & __UxCR_TXEMPTY ) break ; } if ( i < TXREADY_TIMEOUT ) { __SFRW(uhBase+4) = __UxTX_STOPBIT | c ; } } /* * CPUロックを元に戻す */ if ( !bLocked ) { if ( sns_ctx() ) iunl_cpu() ; else unl_cpu() ; } }
/* * シリアルI/Oポートからの非同期文字入力 */ INT sio_arcv_chr( void ) { SIOPCB* siopcb ; UH uhBase ; INT c = -1 ; /* * タスクコンテキストからのみ使用可 */ if ( sns_ctx() || sns_loc() || sns_dsp() ) return -1 ; /* * CPUロック状態にする */ loc_cpu() ; /* * 非同期用ポートを開く */ if ( ( siopcb = sio_opn_por( LOGTASK_PORTID, siopcb_table[LOGTASK_PORTID-1].vpiExinf ) ) != NULL ) { uhBase = siopcb->uhBase ; /* * 受信待ち */ while(1) { if ( __SFR(uhBase) & __UxCR_RXREADY ) { c = __SFRW(uhBase+2) & 0xff ; if ( c == '\r' ) { c = '\n' ; siopcb->bLastIsCr = TRUE ; } else { if ( c == '\n' && siopcb->bLastIsCr ) c = -1 ; siopcb->bLastIsCr = FALSE ; } } if ( c != -1 ) break ; unl_cpu() ; dly_tsk( 50 ) ; loc_cpu() ; } } /* * CPUロックを解除 */ unl_cpu() ; return c ; }
/* * シリアルポートのオープン(サービスコール) */ ER serial_opn_por(ID portid) { SPCB *p_spcb; ER ercd; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); SVC(dis_dsp(), gen_ercd_sys(p_spcb)); if (p_spcb->openflag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * 変数の初期化 */ p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV); p_spcb->rcv_read_ptr = 0U; p_spcb->rcv_write_ptr = 0U; p_spcb->rcv_count = 0U; p_spcb->rcv_fc_chr = '\0'; p_spcb->rcv_stopped = false; p_spcb->snd_read_ptr = 0U; p_spcb->snd_write_ptr = 0U; p_spcb->snd_count = 0U; p_spcb->snd_stopped = false; /* * これ以降,割込みを禁止する. */ if (loc_cpu() < 0) { ercd = E_SYS; goto error_exit_enadsp; } /* * ハードウェア依存のオープン処理 */ p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb); /* * 受信通知コールバックを許可する. */ sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV); p_spcb->openflag = true; p_spcb->errorflag = false; if (unl_cpu() < 0) { p_spcb->errorflag = true; ercd = E_SYS; goto error_exit_enadsp; } ercd = E_OK; } error_exit_enadsp: SVC(ena_dsp(), gen_ercd_sys(p_spcb)); error_exit: return(ercd); }