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

📄 mn10300_serial.c

📁 ecos为实时嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
// And finally, the device table entries:#ifndef CYG_HAL_MN10300_STDEVAL1#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL0// On the standard eval board serial0 is not connected. If enabled, it// generates continuous frame error and overrun interrupts. Hence we do// not touch it.DEVTAB_ENTRY(mn10300_serial_io0,              CYGDAT_IO_SERIAL_MN10300_SERIAL0_NAME,             0,                     // Does not depend on a lower level interface             &serial_devio,              mn10300_serial_init,              mn10300_serial_lookup,     // Serial driver may need initializing             &mn10300_serial_channel0    );#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL0#endif#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL1DEVTAB_ENTRY(mn10300_serial_io1,              CYGDAT_IO_SERIAL_MN10300_SERIAL1_NAME,             0,                     // Does not depend on a lower level interface             &serial_devio,              mn10300_serial_init,              mn10300_serial_lookup,     // Serial driver may need initializing             &mn10300_serial_channel1    );#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL1#ifdef CYGPKG_IO_SERIAL_MN10300_SERIAL2DEVTAB_ENTRY(mn10300_serial_io2,              CYGDAT_IO_SERIAL_MN10300_SERIAL2_NAME,             0,                     // Does not depend on a lower level interface             &serial_devio,              mn10300_serial_init,              mn10300_serial_lookup,     // Serial driver may need initializing             &mn10300_serial_channel2    );#endif // CYGPKG_IO_SERIAL_MN10300_SERIAL2//-------------------------------------------------------------------------// Read the serial line's status register. Serial 2 has an 8 bit status// register while serials 0 and 1 have 16 bit registers. This function// uses the correct size access, but passes back a 16 bit quantity for// both.static cyg_uint16 mn10300_read_sr( mn10300_serial_info *mn10300_chan ){    cyg_uint16 sr = 0;    if( mn10300_chan->is_serial2 )    {        cyg_uint8 sr8;        HAL_READ_UINT8(mn10300_chan->base+SERIAL_STR, sr8);        sr = sr8;    }    else    {        HAL_READ_UINT16(mn10300_chan->base+SERIAL_STR, sr);            }    return sr;}//-------------------------------------------------------------------------static boolmn10300_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init){    mn10300_serial_info *mn10300_chan = (mn10300_serial_info *)chan->dev_priv;    cyg_uint16 cr = 0;#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)    // If we are using CYGMON, do not reinitialize serial 2 at this    // point, since it appears to upset GDB.    if( mn10300_chan->is_serial2 ) return true;#endif            // Disable device entirely.    HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, 0);    HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_ICR, 0);    // Set up baud rate    if( mn10300_chan->is_serial2 )    {        // Serial 2 is a bit different from 0 and 1 in the way that the        // baud rate is controlled.        cyg_uint8 baud_divisor = select_baud_2[new_config->baud].timer2_val;                if (baud_divisor == 0)            return false; // Invalid baud rate selected                HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);        HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 );        baud_divisor = select_baud_2[new_config->baud].serial2_val;        HAL_WRITE_UINT8(mn10300_chan->base+SERIAL_TIM, baud_divisor);                cr |= 0x0001;   // Source clock from timer 2    }    else    {        cyg_uint8 baud_divisor = select_baud_01[new_config->baud];                if (baud_divisor == 0)            return false; // Invalid baud rate selected        HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_BR, baud_divisor);        HAL_WRITE_UINT8(mn10300_chan->timer_base+TIMER_MD, 0x80 );        cr |= 0x0004;   // Source clock from timer 0 or 1    }    HAL_WRITE_UINT8( PORT3_MD, 0x01 );        // 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];#ifdef CYGPKG_IO_SERIAL_MN10300_POLLED_MODE    // enable RX and TX    cr |= LCR_RXE | LCR_TXE;#else    // Enable RX only    cr |= LCR_RXE;#endif        // Write CR into hardware    HAL_WRITE_UINT16(mn10300_chan->base+SERIAL_CTR, cr);        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;#if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)    // If we are using CYGMON, do not reinitialize serial 2. If we do then we    // will steal the receive interrupt and disable Ctrl-C handling.    if( mn10300_chan->is_serial2 ) return true;#endif            (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;}//-------------------------------------------------------------------------bool mn10300_serial_set_config(serial_channel *chan, cyg_serial_info_t *config){    return mn10300_serial_config_port(chan, config, false);}//-------------------------------------------------------------------------// 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 );    cr |= LCR_TXE;    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 );    cr &= ~LCR_TXE;    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_MODEstatic 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}static 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_MODEstatic 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);}static 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 + -