⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serial_saa9730.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 3 页
字号:
 *  --------------- *  'OK' = 0x00:                 character read into user variable *  'ERROR_SERIAL_NO_CHARACTER': no character present on channel *  'ERROR_SERIAL_COMM_ERROR':   communication error detected *  'ERROR_SERIAL_COMM_BREAK':   'BREAK' detected * * ************************************************************************/staticINT32 SERIAL_SAA9730_read(          UINT32 major,          /* IN: major device number             */          UINT32 minor,          /* IN: minor device number             */          UINT8  *p_param )      /* OUT: character been read            */{    UINT32 rc ;    UINT32 lstat ;    UINT16 *getptr ;    /* check for device initialization */    if (phy_lsr == NULL)    {        return( ERROR_SERIAL_UNKNOWN_DEVICE )  ;    }    SERIAL_SAA9730_irqpoll(); /* service UART */    getptr= recv_getptr ;    if (getptr == recv_putptr)        return( ERROR_SERIAL_NO_CHARACTER ) ;    if (poll_retcode != OK)    {        poll_retcode = OK ;        /* flush receive buffer up to the last received ctrl/c or break */        getptr = recv_flushptr;        /* always read CTRL/C in case of 'break' or ctrl/c */        lstat = (*getptr & 0xff00) | CTRL_C;                rc = ERROR_SERIAL_COMM_BREAK;    }    else    {        lstat = *getptr;        rc = OK;    }    *p_param = lstat ;    uart_statistics.ua_rx_bytes++ ;    /* check for errors */    if (lstat & ((SERIAL_LSR_OE<<8) |                 (SERIAL_LSR_PE<<8) |                 (SERIAL_LSR_FE<<8)))    {        if (rc == OK) rc = ERROR_SERIAL_COMM_ERROR ;        if (lstat & (SERIAL_LSR_OE<<8)) uart_statistics.ua_rx_overrun++ ;        if (lstat & (SERIAL_LSR_PE<<8)) uart_statistics.ua_rx_parity++ ;        if (lstat & (SERIAL_LSR_FE<<8)) uart_statistics.ua_rx_framing++ ;    }    if (++getptr >= &recv_buffer[POLLSIZE])        getptr= &recv_buffer[0] ;    recv_getptr = getptr ;    /* compute room in buffer */    if ( (shadow_mcr & SERIAL_MCR_RTS) == 0 &&         (((UINT32)getptr - (UINT32)recv_putptr) &                ((POLLSIZE - 1) * sizeof(*getptr)))                               >= HW_LIMIT_START * sizeof(*getptr) )    {        shadow_mcr |= SERIAL_MCR_RTS;        *phy_mcr = shadow_mcr;    }    return( rc ) ;}/************************************************************************ * *                          SERIAL_SAA9730_irqpoll *  Description : *  ------------- *  Disabling of interrupts around call of SERIAL_SAA9730_irq() * ************************************************************************/staticUINT32 SERIAL_SAA9730_irqpoll( void ){    UINT32 lstat;    if (sys_disable_int())    {        lstat = SERIAL_SAA9730_irq( 0 );        sys_enable_int();    }    else        lstat = SERIAL_SAA9730_irq( 0 );    return lstat;}/************************************************************************ * *                          SERIAL_SAA9730_irq *  Description : *  ------------- *  This service empties the UART's FIFO buffer and puts the chars into *  the cyclic receive buffer. * *  This routine is called in both polled and interrupt mode. *    and requires interrupts to be disabled. * *  static variables written: *  poll_retcode  BREAK or CTRL/C has been read *  recv_putptr   pointer to next free position in cyclic queue. * * *  static variables read: *  phy_lsr       pointer to UART line status register *  phy_rbr       pointer to UART receive data register *  recv_getptr   pointer to first unread position in cyclic queue. *  recv_flushptr pointer to position of last read break or ctrl/c * ************************************************************************/staticUINT32 SERIAL_SAA9730_irq( UINT32 in_intrpt ){    UINT32 lstat ; /* LSR_OE, LSR_PE, LSR_FE and LSR_BI are clear on read */    UINT8  rdata ;    UINT16 *putptr ;    UINT32 room ;    putptr= recv_putptr ;    /* empty FIFO*/    for (lstat = *phy_lsr; lstat & SERIAL_LSR_DR; lstat = *phy_lsr)    {        rdata = *phy_rbr & 0xff;        uart_statistics.ua_rx_irqs += in_intrpt;        if (lstat & SERIAL_LSR_BI)        {            rdata = CTRL_C;            uart_statistics.ua_rx_break++;        }        /* compute room left in buffer, AFTER this byte has been put */        room = ((UINT32)recv_getptr - (UINT32)putptr - 1) &                             ((POLLSIZE - 1) * sizeof(*putptr));        if (room <= HW_LIMIT_STOP * sizeof(*putptr) && shadow_flow != 0)        {            shadow_mcr &= ~SERIAL_MCR_RTS;            *phy_mcr = shadow_mcr;        }        if (room == 0)        {            lstat |= SERIAL_LSR_OE;  /* overrun */            /* overwrite previous char (overflow anyway) */            if (--putptr < &recv_buffer[0])                putptr= &recv_buffer[POLLSIZE-1] ;        }        *putptr = (lstat << 8) | rdata;        if (rdata == CTRL_C)        {            poll_retcode = ERROR_SERIAL_COMM_BREAK ;            recv_flushptr = putptr;        }        /* increase putptr to its future position */        if (++putptr >= &recv_buffer[POLLSIZE])            putptr= &recv_buffer[0] ;    }    recv_putptr = putptr ;    return lstat;}/************************************************************************ * *                          SERIAL_SAA9730_write *  Description : *  ------------- *  This service writes a character on the specified channel * * *  Parameters : *  ------------ * *  'major',     IN,    major device number *  'minor',     IN,    minor device number for multi device drivers *  'p_param',   IN,    pointer to character to write * * *  Return values : *  --------------- *  'OK' = 0x00:                 character has been written on channel * * ************************************************************************/staticINT32 SERIAL_SAA9730_write(          UINT32 major,          /* IN: major device number             */          UINT32 minor,          /* IN: minor device number             */          UINT8  *p_param )      /* IN: pointer to character to write   */{    UINT32 lstat ;    /* check for device initialization */    if (phy_lsr == NULL)    {      return( ERROR_SERIAL_UNKNOWN_DEVICE )  ;    }    /* check modem status: not necessary at auto-flow *//*    {        UINT8 mstat ;        do         {            mstat = *phy_msr ;        }        while (!(mstat & SERIAL_MSR_CTS));    }*/    /* check line status */    do     {        /* OBS: LSR_OE, LSR_PE, LSR_FE and LSR_BI are cleared on read */        lstat = SERIAL_SAA9730_irqpoll() ;    }    while (!(lstat & SERIAL_LSR_THRE)) ;    /* write character */    *phy_thr = *p_param ;    uart_statistics.ua_tx_bytes++ ;    return( OK ) ;}/************************************************************************ * *                          SERIAL_SAA9730_ctrl *  Description : *  ------------- *  This service performs the actions defined by t_SERIAL_ctrl_command_ids *  on the specified channel. * * *  Parameters : *  ------------ * *  'major',     IN,    major device number *  'minor',     IN,    minor device number for multi device drivers *  'p_param',   INOUT, IOCTL structure * * *  Return values : *  --------------- *  'OK' = 0x00:                 normal return *  ERROR_SERIAL_COMM_BREAK:     break or ctrl/c received  *  ERROR_SERIAL_COMM_ERROR:     receive error, characters lost * * ************************************************************************/staticINT32 SERIAL_SAA9730_ctrl(          UINT32 major,          /* IN: major device number             */          UINT32 minor,          /* IN: minor device number             */          t_SERIAL_ctrl_descriptor *p_param ) /* INOUT: IOCTL structure */{    UINT32 rcode ;    /* check for device initialization */    if (phy_lsr == NULL)    {      return( ERROR_SERIAL_UNKNOWN_DEVICE )  ;    }    if (p_param == NULL)    {      return( ERROR_SERIAL_INVALID_ARGUMENT ) ;    }    rcode = OK ;    switch( p_param->sc_command )    {      case SERIAL_CTRL_POLL_BREAK:        SERIAL_SAA9730_irqpoll(); /* service UART */        if( (rcode = poll_retcode) != OK )        {            /* flush read buffer */            rcode = SERIAL_SAA9730_read( major, minor, (UINT8 *)&rcode );        }      break ;      case SERIAL_CTRL_GET_STATISTICS:        memcpy((UINT8*)&p_param->sc_arg.sc_statistics,                (UINT8 *)&uart_statistics,               sizeof(uart_statistics)) ;      break ;      case SERIAL_CTRL_GET_LSR:        p_param->sc_arg.sc_linestat = SERIAL_SAA9730_irqpoll();      break ;      case SERIAL_CTRL_RCV_IRQ:        /* acknowledge to Philips Event Monitor */        *(evm_base + EVM_SAA9730_SECISR_OFS) = EVM_SAA9730_SECIER_UART1;        SERIAL_SAA9730_irq( 1 );      break ;      case SERIAL_CTRL_RCV_IRQ_ON:        *(evm_base + EVM_SAA9730_IER_OFS)    |= EVM_SAA9730_IER_MASTER;        *(evm_base + EVM_SAA9730_IERSW_OFS)  |= EVM_SAA9730_IER_MASTER;        *(evm_base + EVM_SAA9730_SECIER_OFS) |= EVM_SAA9730_SECIER_UART1;        *phy_ier   =         shadow_ier = SERIAL_IER_RCVEN;      break ;      case SERIAL_CTRL_RCV_IRQ_OFF:        *(evm_base + EVM_SAA9730_SECIER_OFS) &= ~EVM_SAA9730_SECIER_UART1;        shadow_ier =        *phy_ier   = 0;      break ;      case SERIAL_CTRL_FORCE_DTR:         if (p_param->sc_arg.sc_dtr == 0)             shadow_mcr &= ~SERIAL_MCR_DTR;         else             shadow_mcr |=  SERIAL_MCR_DTR;         *phy_mcr = shadow_mcr;      break ;      case SERIAL_CTRL_GET_MSR:         p_param->sc_arg.sc_msr = *phy_msr & ~(SERIAL_MSR_DSR | SERIAL_MSR_RI);         if ((*(evm_base + EVM_SAA9730_IMR_OFS) & EVM_SAA9730_GPIO0) == 0)             p_param->sc_arg.sc_msr |= SERIAL_MSR_RI;         if ((*(evm_base + EVM_SAA9730_IMR_OFS) & EVM_SAA9730_GPIO1) == 0)             p_param->sc_arg.sc_msr |= SERIAL_MSR_DSR;      break ;      case SERIAL_CTRL_SEND_BREAK:         /* the normal LCR_BREAK bit does not function porperly */         *phy_cfg |= SERIAL_CFG_BREAK;         sys_wait_ms(250);         *phy_cfg &= ~SERIAL_CFG_BREAK;      break ;      default:        rcode = ERROR_SERIAL_INVALID_ARGUMENT ;    }    return( rcode ) ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -