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

📄 ser_16x5x.c

📁 移植到WLIT项目的redboot源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        cyg_drv_interrupt_unmask(ser_chan->int_num);    }    serial_config_port(chan, &chan->config, true);    return true;}// This routine is called when the device is "looked" up (i.e. attached)static Cyg_ErrNo pc_serial_lookup(struct cyg_devtab_entry **tab,                  struct cyg_devtab_entry *sub_tab,                 const char *name){    serial_channel *chan = (serial_channel *)(*tab)->priv;    // Really only required for interrupt driven devices    (chan->callbacks->serial_init)(chan);    return ENOERR;}// Send a character to the device output buffer.// Return 'true' if character is sent to devicestatic boolpc_serial_putc(serial_channel *chan, unsigned char c){    cyg_uint8 _lsr;    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_addrword_t base = ser_chan->base;    HAL_READ_UINT8(base+REG_lsr, _lsr);    if (_lsr & LSR_THE) {// Transmit buffer is empty        HAL_WRITE_UINT8(base+REG_thr, c);        return true;    } else {// No space        return false;    }}// Fetch a character from the device input buffer, waiting if necessarystatic unsigned char pc_serial_getc(serial_channel *chan){    unsigned char c;    cyg_uint8 _lsr;    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_addrword_t base = ser_chan->base;    // Wait for char    do {        HAL_READ_UINT8(base+REG_lsr, _lsr);    } while ((_lsr & LSR_RSR) == 0);    HAL_READ_UINT8(base+REG_rhr, c);    return c;}// Set up the device characteristics; baud rate, etc.static Cyg_ErrNopc_serial_set_config(serial_channel *chan, cyg_uint32 key, const void *xbuf,                     cyg_uint32 *len){    switch (key) {    case CYG_IO_SET_CONFIG_SERIAL_INFO:      {        cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;        if ( *len < sizeof(cyg_serial_info_t) ) {            return -EINVAL;        }        *len = sizeof(cyg_serial_info_t);        if ( true != serial_config_port(chan, config, false) )            return -EINVAL;      }      break;#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW    case CYG_IO_SET_CONFIG_SERIAL_HW_RX_FLOW_THROTTLE:      {          cyg_uint8 _mcr;          pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;          cyg_addrword_t base = ser_chan->base;          cyg_uint8 *f = (cyg_uint8 *)xbuf;          unsigned char mask=0;          if ( *len < *f )              return -EINVAL;                    if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_RX )              mask = MCR_RTS;          if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_RX )              mask |= MCR_DTR;          HAL_READ_UINT8(base+REG_mcr, _mcr);          if (*f) // we should throttle              _mcr &= ~mask;          else // we should no longer throttle              _mcr |= mask;          HAL_WRITE_UINT8(base+REG_mcr, _mcr);      }      break;    case CYG_IO_SET_CONFIG_SERIAL_HW_FLOW_CONFIG:        // Nothing to do because we do support both RTSCTS and DSRDTR flow        // control.        // Other targets would clear any unsupported flags here.        // We just return ENOERR.      break;#endif    default:        return -EINVAL;    }    return ENOERR;}// Enable the transmitter on the devicestatic voidpc_serial_start_xmit(serial_channel *chan){    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_addrword_t base = ser_chan->base;    cyg_uint8 _ier;        HAL_READ_UINT8(base+REG_ier, _ier);    _ier |= IER_XMT;                    // Enable xmit interrupt    HAL_WRITE_UINT8(base+REG_ier, _ier);}// Disable the transmitter on the devicestatic void pc_serial_stop_xmit(serial_channel *chan){    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_addrword_t base = ser_chan->base;    cyg_uint8 _ier;    HAL_READ_UINT8(base+REG_ier, _ier);    _ier &= ~IER_XMT;                   // Disable xmit interrupt    HAL_WRITE_UINT8(base+REG_ier, _ier);}// Serial I/O - low level interrupt handler (ISR)static cyg_uint32 pc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(ser_chan->int_num);    cyg_drv_interrupt_acknowledge(ser_chan->int_num);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}// Serial I/O - high level interrupt handler (DSR)static void       pc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    pc_serial_info *ser_chan = (pc_serial_info *)chan->dev_priv;    cyg_addrword_t base = ser_chan->base;    cyg_uint8 _isr;    // Check if we have an interrupt pending - note that the interrupt    // is pending of the low bit of the isr is *0*, not 1.    HAL_READ_UINT8(base+REG_isr, _isr);    while ((_isr & ISR_nIP) == 0) {        switch (_isr&0x6) {        case ISR_Rx:        {            cyg_uint8 _lsr;            unsigned char c;            HAL_READ_UINT8(base+REG_lsr, _lsr);            while(_lsr & LSR_RSR) {                HAL_READ_UINT8(base+REG_rhr, c);                (chan->callbacks->rcv_char)(chan, c);                HAL_READ_UINT8(base+REG_lsr, _lsr);            }            break;        }        case ISR_Tx:            (chan->callbacks->xmt_char)(chan);            break;#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS        case ISR_LS:            {                cyg_serial_line_status_t stat;                cyg_uint8 _lsr;                HAL_READ_UINT8(base+REG_lsr, _lsr);                // this might look expensive, but it is rarely the case that                // more than one of these is set                stat.value = 1;                if ( _lsr & LSR_OE ) {                    stat.which = CYGNUM_SERIAL_STATUS_OVERRUNERR;                    (chan->callbacks->indicate_status)(chan, &stat );                }                if ( _lsr & LSR_PE ) {                    stat.which = CYGNUM_SERIAL_STATUS_PARITYERR;                    (chan->callbacks->indicate_status)(chan, &stat );                }                if ( _lsr & LSR_FE ) {                    stat.which = CYGNUM_SERIAL_STATUS_FRAMEERR;                    (chan->callbacks->indicate_status)(chan, &stat );                }                if ( _lsr & LSR_BI ) {                    stat.which = CYGNUM_SERIAL_STATUS_BREAK;                    (chan->callbacks->indicate_status)(chan, &stat );                }            }            break;        case ISR_MS:            {                cyg_serial_line_status_t stat;                cyg_uint8 _msr;                                HAL_READ_UINT8(base+REG_msr, _msr);#ifdef CYGOPT_IO_SERIAL_FLOW_CONTROL_HW                if ( _msr & MSR_DDSR )                    if ( chan->config.flags & CYGNUM_SERIAL_FLOW_DSRDTR_TX ) {                        stat.which = CYGNUM_SERIAL_STATUS_FLOW;                        stat.value = (0 != (_msr & MSR_DSR));                        (chan->callbacks->indicate_status)(chan, &stat );                    }                if ( _msr & MSR_DCTS )                    if ( chan->config.flags & CYGNUM_SERIAL_FLOW_RTSCTS_TX ) {                        stat.which = CYGNUM_SERIAL_STATUS_FLOW;                        stat.value = (0 != (_msr & MSR_CTS));                        (chan->callbacks->indicate_status)(chan, &stat );                    }#endif                if ( _msr & MSR_DDCD ) {                    stat.which = CYGNUM_SERIAL_STATUS_CARRIERDETECT;                    stat.value = (0 != (_msr & MSR_CD));                    (chan->callbacks->indicate_status)(chan, &stat );                }                if ( _msr & MSR_RI ) {                    stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR;                    stat.value = 1;                    (chan->callbacks->indicate_status)(chan, &stat );                }                if ( _msr & MSR_TERI ) {                    stat.which = CYGNUM_SERIAL_STATUS_RINGINDICATOR;                    stat.value = 0;                    (chan->callbacks->indicate_status)(chan, &stat );                }            }            break;#endif        }        HAL_READ_UINT8(base+REG_isr, _isr);    } // while    cyg_drv_interrupt_unmask(ser_chan->int_num);}#endif// EOF ser_16x5x.c

⌨️ 快捷键说明

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