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

📄 mn10300_serial.c

📁 eCos操作系统源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    cr |= select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];    cr |= select_stop_bits[new_config->stop];    cr |= select_parity[new_config->parity];    cr |= LCR_RXE | LCR_TXE;        // enable Rx and Tx    #ifdef CYGPKG_HAL_MN10300_AM31    if( mn10300_chan->is_serial2 )    {        // AM31 has an extra TX interrupt enable bit for serial 2.        DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);    }#endif            // Write CR into hardware    HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr);        sr = mn10300_read_sr(mn10300_chan);    if (new_config != &chan->config) {        chan->config = *new_config;    }    return true;}//-------------------------------------------------------------------------// Function to initialize the device.  Called at bootstrap time.bool mn10300_serial_init(struct cyg_devtab_entry *tab){    serial_channel *chan = (serial_channel *)tab->priv;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE        if (chan->out_cbuf.len != 0) {        // Install and enable the receive interrupt        cyg_drv_interrupt_create(mn10300_chan->rx_int,                                 4,                      // Priority - what goes here?                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler                                 mn10300_serial_rx_ISR,                                 mn10300_serial_rx_DSR,                                 &mn10300_chan->rx_interrupt_handle,                                 &mn10300_chan->rx_interrupt);        cyg_drv_interrupt_attach(mn10300_chan->rx_interrupt_handle);        cyg_drv_interrupt_unmask(mn10300_chan->rx_int);        // Install and enable the transmit interrupt        cyg_drv_interrupt_create(mn10300_chan->tx_int,                                 4,                      // Priority - what goes here?                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler                                 mn10300_serial_tx_ISR,                                 mn10300_serial_tx_DSR,                                 &mn10300_chan->tx_interrupt_handle,                                 &mn10300_chan->tx_interrupt);        cyg_drv_interrupt_attach(mn10300_chan->tx_interrupt_handle);        cyg_drv_interrupt_mask(mn10300_chan->tx_int);    }#endif        mn10300_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 mn10300_serial_lookup(struct cyg_devtab_entry **tab,                   struct cyg_devtab_entry *sub_tab,                  const char *name){    serial_channel *chan = (serial_channel *)(*tab)->priv;    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices    return ENOERR;}//-------------------------------------------------------------------------// Return 'true' if character is sent to deviceboolmn10300_serial_putc(serial_channel *chan, unsigned char c){    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint8 sr = mn10300_read_sr( mn10300_chan);    if( (sr & SR_TBF) == 0 )    {        HAL_WRITE_UINT8( mn10300_chan->base+SERIAL_TXB, c );        return true;    }    else return false;}//-------------------------------------------------------------------------unsigned char mn10300_serial_getc(serial_channel *chan){    unsigned char c;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    do    {        cyg_uint8 sr = mn10300_read_sr( mn10300_chan );        if( (sr & SR_RBF) != 0 )        {            HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );            break;        }            } while(1);        return c;}//-------------------------------------------------------------------------static Cyg_ErrNomn10300_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 != mn10300_serial_config_port(chan, config, false) )            return -EINVAL;      }      break;    default:        return -EINVAL;    }    return ENOERR;}//-------------------------------------------------------------------------// Enable the transmitter on the devicestatic voidmn10300_serial_start_xmit(serial_channel *chan){#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE        mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint16 cr;    HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );    ENABLE_TRANSMIT_INTERRUPT(mn10300_chan);        HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );    cyg_drv_interrupt_unmask(mn10300_chan->tx_int);        (chan->callbacks->xmt_char)(chan);#endif    }//-------------------------------------------------------------------------// Disable the transmitter on the devicestatic void mn10300_serial_stop_xmit(serial_channel *chan){#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE        mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint16 cr;    cyg_uint16 sr;    // Wait until the transmitter has actually stopped before turning it off.        do    {        sr = mn10300_read_sr( mn10300_chan );            } while( sr & SR_TXF );        HAL_READ_UINT16( mn10300_chan->base+SERIAL_CTR, cr );    DISABLE_TRANSMIT_INTERRUPT(mn10300_chan);        HAL_WRITE_UINT16( mn10300_chan->base+SERIAL_CTR, cr );    cyg_drv_interrupt_mask(mn10300_chan->tx_int);    #endif    }//-------------------------------------------------------------------------// Serial I/O - low level interrupt handlers (ISR)#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFO// This version of the RX ISR implements a simple receive FIFO. The// MN10300 serial devices do not have hardware FIFOs (as found in// 16550s for example), and it can be difficult at times to keep up// with higher baud rates without overrunning. This ISR implements a// software equivalent of the hardware FIFO, placing recieved// characters into the FIFO as soon as they arrive. Whenever the DSR// is run, it collects all the pending characters from the FIFO for// delivery to the application. Neither the ISR or DSR disable// interrupts, instead we rely on being able to write the head and// tail pointers atomically, to implement lock-free synchronization.static cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint8 sr = mn10300_read_sr( mn10300_chan);    while( (sr & SR_RBF) != 0 )    {        register cyg_int32 head = mn10300_chan->fifo_head;        cyg_uint8 c;        int i;        HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, c );        mn10300_chan->fifo[head++] = c;        if( head >= sizeof(mn10300_chan->fifo) )            head = 0;        mn10300_chan->fifo_head = head;        sr = mn10300_read_sr( mn10300_chan);    }    cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);        return CYG_ISR_CALL_DSR;  // Cause DSR to be run}#elsestatic cyg_uint32 mn10300_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;     cyg_drv_interrupt_mask(mn10300_chan->rx_int);    cyg_drv_interrupt_acknowledge(mn10300_chan->rx_int);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}#endifstatic cyg_uint32 mn10300_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(mn10300_chan->tx_int);    cyg_drv_interrupt_acknowledge(mn10300_chan->tx_int);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}#endif//-------------------------------------------------------------------------// Serial I/O - high level interrupt handler (DSR)#ifndef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE#ifdef CYG_HAL_MN10300_SERIAL_RX_FIFOstatic void       mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    register cyg_int32 head = mn10300_chan->fifo_head;    register cyg_int32 tail = mn10300_chan->fifo_tail;        while( head != tail )    {        cyg_uint8 c = mn10300_chan->fifo[tail++];        if( tail >= sizeof(mn10300_chan->fifo) ) tail = 0;        (chan->callbacks->rcv_char)(chan, c);    }    mn10300_chan->fifo_tail = tail;}#elsestatic void       mn10300_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint8 sr = mn10300_read_sr( mn10300_chan);    if( (sr & SR_RBF) != 0 )    {        cyg_uint8 rxb;        HAL_READ_UINT8( mn10300_chan->base+SERIAL_RXB, rxb );        (chan->callbacks->rcv_char)(chan, rxb);    }    cyg_drv_interrupt_unmask(mn10300_chan->rx_int);}#endifstatic void       mn10300_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint8 sr = mn10300_read_sr( mn10300_chan);    if( (sr & SR_TBF) == 0 )    {        (chan->callbacks->xmt_char)(chan);    }        cyg_drv_interrupt_unmask(mn10300_chan->tx_int);}#endif#endif // CYGPKG_IO_SERIAL_MN10300//-------------------------------------------------------------------------// EOF mn10300.c

⌨️ 快捷键说明

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