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

📄 tx3904_serial.c

📁 ecos为实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
        while( n-- )    {        cyg_count32 i,j,k;        for( i = 0; i < clock_loop; i++ )            for( j = 0; j < div_loop; j++ )                for( k = 0; k < bit_time; k++ )                    continue;    }}//-------------------------------------------------------------------------static booltx3904_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init){    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint16 cr = 0;    cyg_uint16 icr = 0;    cyg_uint16 baud_divisor = select_baud[new_config->baud];    if (baud_divisor == 0)        return false;  // Invalid baud rate selected    // set up other config values:    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];    // Source transfer clock from BRG    cr |= LCR_BRG;#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE        // Enable RX interrupts only at present#ifdef CYGPKG_IO_SERIAL_TX39_JMR3904_SERIAL0    if ((chan->out_cbuf.len != 0) || (chan == &tx3904_serial_channel0)) {#else    if (chan->out_cbuf.len != 0) {#endif        icr |= ICR_RXE;    }#endif    // Avoid any interrupts while we are fiddling with the line parameters.    cyg_drv_interrupt_mask(tx3904_chan->int_num);        // In theory we should wait here for the transmitter to drain the    // FIFO so we dont change the line parameters with characters    // unsent. Unfortunately the TX39 serial devices do not allow us    // to discover when the FIFO is empty.    delay_char_time(tx3904_chan, 8);        // Disable device entirely.//    HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, 0);//    HAL_WRITE_UINT8(tx3904_chan->base+SERIAL_ICR, 0);    // Reset the FIFOs    HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 7);    HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_FCR, 0);        // Set up baud rate    HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_BRG, baud_divisor );    // Write CR into hardware    HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_CR, cr);        // Write ICR into hardware    HAL_WRITE_UINT16(tx3904_chan->base+SERIAL_ICR, icr);        // Re-enable interrupts.    cyg_drv_interrupt_unmask(tx3904_chan->int_num);    // Save current baud rate    tx3904_chan->cur_baud = new_config->baud;    if (new_config != &chan->config) {        chan->config = *new_config;    }    return true;}//-------------------------------------------------------------------------// Function to initialize the device.  Called at bootstrap time.bool tx3904_serial_init(struct cyg_devtab_entry *tab){    serial_channel *chan = (serial_channel *)tab->priv;    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices    tx3904_chan->cur_baud = CYGNUM_SERIAL_BAUD_38400;        #ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE        if (chan->out_cbuf.len != 0) {        // Install and enable the interrupt        cyg_drv_interrupt_create(tx3904_chan->int_num,                                 4,                      // Priority                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler                                 (cyg_ISR_t *)tx3904_serial_ISR,                                 tx3904_serial_DSR,                                 &tx3904_chan->interrupt_handle,                                 &tx3904_chan->interrupt);        cyg_drv_interrupt_attach(tx3904_chan->interrupt_handle);        cyg_drv_interrupt_unmask(tx3904_chan->int_num);    }#endif        tx3904_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 tx3904_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 devicebooltx3904_serial_putc(serial_channel *chan, unsigned char c){    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint16 isr;    HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );    if( isr & ISR_TXRDY )    {        HAL_WRITE_UINT8( tx3904_chan->base+SERIAL_TXB, c );        isr &= ~ISR_TXRDY;                HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );        return true;    }    else return false;}//-------------------------------------------------------------------------unsigned char tx3904_serial_getc(serial_channel *chan){    unsigned char c;    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint16 isr;    do    {        HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );        // Eliminate any RX errors        if( isr & ISR_ERROR )        {            cyg_uint16 sr = 0;                        isr &= ISR_ERROR;//            HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr );            HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, sr );                        HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );        }            } while( (isr & ISR_RXRDY) != ISR_RXRDY );        HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, c );    isr &= ~ISR_RXRDY;            HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );    return c;}//-------------------------------------------------------------------------bool tx3904_serial_set_config(serial_channel *chan, cyg_serial_info_t *config){    return tx3904_serial_config_port(chan, config, false);}//-------------------------------------------------------------------------// Enable the transmitter on the devicestatic voidtx3904_serial_start_xmit(serial_channel *chan){#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE        tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint16 icr;    HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr );    icr |= ICR_TXE;    HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr );#endif    }//-------------------------------------------------------------------------// Disable the transmitter on the devicestatic void tx3904_serial_stop_xmit(serial_channel *chan){#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODE        tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint16 icr;    HAL_READ_UINT16( tx3904_chan->base+SERIAL_ICR, icr );    icr &= ~ICR_TXE;    HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ICR, icr );#endif    }//-------------------------------------------------------------------------// Serial I/O - low level interrupt handlers (ISR)#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODEstatic cyg_uint32 tx3904_serial_ISR(cyg_vector_t vector, cyg_addrword_t data, cyg_addrword_t *regs){    serial_channel *chan = (serial_channel *)data;    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint8 isr;    cyg_uint32 result = 0;        cyg_drv_interrupt_mask(tx3904_chan->int_num);    cyg_drv_interrupt_acknowledge(tx3904_chan->int_num);    HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );    // Eliminate any RX errors    if( isr & ISR_ERROR )    {        cyg_uint16 sr = 0;                    isr &= ~ISR_ERROR;        HAL_READ_UINT16( tx3904_chan->base+SERIAL_SR, sr );                HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_SR, 0 );                }    // Check for a TX interrupt and set the flag if so.    if( isr & ISR_TXRDY )    {        isr &= ~ISR_TXRDY;        tx3904_chan->output_ready = true;        result |= CYG_ISR_CALL_DSR;  // Cause DSR to be run    }            // Check here for an RX interrupt and fetch the character. If it    // is a ^C then call into GDB stub to handle it.        if( isr & ISR_RXRDY )    {        cyg_uint8 rxb;        HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb );        isr &= ~ISR_RXRDY;        if( cyg_hal_is_break( &rxb , 1 ) )            cyg_hal_user_break( regs );        else        {            tx3904_chan->input_char = rxb;            tx3904_chan->input_char_valid = true;            result |= CYG_ISR_CALL_DSR;  // Cause DSR to be run        }    }    HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );        return result;}#endif//-------------------------------------------------------------------------// Serial I/O - high level interrupt handler (DSR)#ifndef CYGPKG_IO_SERIAL_TX39_JMR3904_POLLED_MODEstatic void       tx3904_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    tx3904_serial_info *tx3904_chan = (tx3904_serial_info *)chan->dev_priv;    cyg_uint8 isr;    HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );    if( tx3904_chan->input_char_valid )    {        (chan->callbacks->rcv_char)(chan, tx3904_chan->input_char);        tx3904_chan->input_char_valid = false;#if 0                // And while we are here, pull any further characters out of the        // FIFO. This should help to reduce the interrupt rate.        HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );            while( isr & ISR_RXRDY )        {            cyg_uint8 rxb;            HAL_READ_UINT8( tx3904_chan->base+SERIAL_RXB, rxb );            (chan->callbacks->rcv_char)(chan, rxb);                        isr &= ~ISR_RXRDY;                    HAL_WRITE_UINT16( tx3904_chan->base+SERIAL_ISR, isr );            HAL_READ_UINT16( tx3904_chan->base+SERIAL_ISR, isr );                }#endif            }    if( tx3904_chan->output_ready )    {        (chan->callbacks->xmt_char)(chan);        tx3904_chan->output_ready = false;    }        cyg_drv_interrupt_unmask(tx3904_chan->int_num);}#endif#endif // CYGPKG_IO_SERIAL_TX39_JMR3904//-------------------------------------------------------------------------// EOF tx3904_serial.c

⌨️ 快捷键说明

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