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

📄 ebsa285_serial.c

📁 eCos1.31版
💻 C
📖 第 1 页 / 共 2 页
字号:
// ------------------------------------------------------------------------// ------------------------------------------------------------------------// Internal function to actually configure the hardware to desired baud rate, etc.static boolebsa285_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init){    int dummy, h, m, l;        // Make sure everything is off    *SA110_UART_CONTROL_REGISTER = SA110_UART_DISABLED | SA110_SIR_DISABLED;        // Read the RXStat to drain the fifo    dummy = *SA110_UART_RXSTAT;    // Set the baud rate - this also turns the uart on.    //     // Note that the ordering of these writes is critical,    // and the writes to the H_BAUD_CONTROL and CONTROL_REGISTER    // are necessary to force the UART to update its register    // contents.    l = bauds[new_config->baud].divisor_low;   // zeros in unused slots here    m = bauds[new_config->baud].divisor_high;  // and here    h = SA110_UART_BREAK_DISABLED    |              select_stop_bits[new_config->stop] |   // -1s in unused slots for these        select_parity[new_config->parity]  |   // and these        SA110_UART_FIFO_ENABLED |              // and these below        select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5];    if ( 0 != (l + m) && h >= 0 && h < 256 ) {        *SA110_UART_L_BAUD_CONTROL = l;        *SA110_UART_M_BAUD_CONTROL = m;        *SA110_UART_H_BAUD_CONTROL = h;        init = true; // AOK    }    else if ( init ) {        // put in some sensible defaults        *SA110_UART_L_BAUD_CONTROL   = 0x13; // bp->divisor_low;        *SA110_UART_M_BAUD_CONTROL   = 0x00; // bp->divisor_high;        *SA110_UART_H_BAUD_CONTROL = SA110_UART_BREAK_DISABLED    |            SA110_UART_PARITY_DISABLED   |            SA110_UART_STOP_BITS_ONE     |            SA110_UART_FIFO_ENABLED      |            SA110_UART_DATA_LENGTH_8_BITS;    }    // All set, re-enable the device:    *SA110_UART_CONTROL_REGISTER = SA110_UART_ENABLED | SA110_SIR_DISABLED;    if (init && new_config != &chan->config) {        // record the new setup        chan->config = *new_config;    }    // All done    return init;}// Function to initialize the device.  Called at bootstrap time.static bool ebsa285_serial_init(struct cyg_devtab_entry *tab){    serial_channel *chan = (serial_channel *)tab->priv;    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;#ifdef CYGDBG_IO_INIT    diag_printf("EBSA285 SERIAL init - dev: %x.%d\n", ebsa285_chan->base, ebsa285_chan->int_num);#endif    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices    if (chan->out_cbuf.len != 0) {        // first for rx        cyg_drv_interrupt_create(ebsa285_chan->rx.int_num,                                 99,                   // Priority - unused                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler                                 ebsa285_serial_rx_ISR,                                 ebsa285_serial_rx_DSR,                                 &ebsa285_chan->rx.serial_interrupt_handle,                                 &ebsa285_chan->rx.serial_interrupt);        cyg_drv_interrupt_attach(ebsa285_chan->rx.serial_interrupt_handle);        cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num);        // then for tx        cyg_drv_interrupt_create(ebsa285_chan->tx.int_num,                                 99,                   // Priority - unused                                 (cyg_addrword_t)chan, //  Data item passed to interrupt handler                                 ebsa285_serial_tx_ISR,                                 ebsa285_serial_tx_DSR,                                 &ebsa285_chan->tx.serial_interrupt_handle,                                 &ebsa285_chan->tx.serial_interrupt);        cyg_drv_interrupt_attach(ebsa285_chan->tx.serial_interrupt_handle);        // DO NOT cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);    }    (void)ebsa285_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 ebsa285_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;}// Send a character to the device output buffer.// Return 'true' if character is sent to devicestatic boolebsa285_serial_putc(serial_channel *chan, unsigned char c){    if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) == SA110_TX_FIFO_BUSY)        return false; // No space        *SA110_UART_DATA_REGISTER = c; // Transmit buffer is empty    return true;}// Fetch a character from the device input buffer, waiting if necessarystatic unsigned char ebsa285_serial_getc(serial_channel *chan){    unsigned char c;    while ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) == SA110_RX_FIFO_EMPTY)        ; // wait for char    c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);    // no error checking... no way to return the info    return c;}// Set up the device characteristics; baud rate, etc.static bool ebsa285_serial_set_config(serial_channel *chan, cyg_serial_info_t *config){    return ebsa285_serial_config_port(chan, config, false);}// Enable the transmitter on the device (nope, already in use by hal_diag)static voidebsa285_serial_start_xmit(serial_channel *chan){    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);}// Disable the transmitter on the device (nope, remains in use by hal_diag)static void ebsa285_serial_stop_xmit(serial_channel *chan){    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num);}// Serial I/O - low level interrupt handlers (ISR)static cyg_uint32 ebsa285_serial_rx_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(ebsa285_chan->rx.int_num);    cyg_drv_interrupt_acknowledge(ebsa285_chan->rx.int_num);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}static cyg_uint32 ebsa285_serial_tx_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(ebsa285_chan->tx.int_num);    cyg_drv_interrupt_acknowledge(ebsa285_chan->tx.int_num);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}// Serial I/O - high level interrupt handlers (DSR)static void       ebsa285_serial_rx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    if ((*SA110_UART_FLAG_REGISTER & SA110_RX_FIFO_STATUS_MASK) != SA110_RX_FIFO_EMPTY) {        char c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);        int status;        c = (char)(*SA110_UART_DATA_REGISTER & 0xFF);        status = *SA110_UART_RXSTAT;        if ( 0 == (status & (SA110_UART_FRAMING_ERROR_MASK |                             SA110_UART_PARITY_ERROR_MASK  |                             SA110_UART_OVERRUN_ERROR_MASK)) )            (chan->callbacks->rcv_char)(chan, c);    }    cyg_drv_interrupt_unmask(ebsa285_chan->rx.int_num);}static void       ebsa285_serial_tx_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    ebsa285_serial_info *ebsa285_chan = (ebsa285_serial_info *)chan->dev_priv;    if ((*SA110_UART_FLAG_REGISTER & SA110_TX_FIFO_STATUS_MASK) != SA110_TX_FIFO_BUSY) {        (chan->callbacks->xmt_char)(chan);    }    cyg_drv_interrupt_unmask(ebsa285_chan->tx.int_num);}#endif // CYGPKG_IO_SERIAL_ARM_EBSA285// ------------------------------------------------------------------------// EOF ebsa285_serial.c

⌨️ 快捷键说明

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