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

📄 quicc_smc_serial.c

📁 eCos1.31版
💻 C
📖 第 1 页 / 共 3 页
字号:
    bool res;    cyg_drv_dsr_lock();  // Avoid race condition testing pointers    txbd = (struct cp_bufdesc *)((char *)eppc + smc_chan->pram->tbptr);    txfirst = txbd;    // Scan for a non-busy buffer    while (txbd->ctrl & QUICC_BD_CTL_Ready) {        // This buffer is busy, move to next one        if (txbd->ctrl & QUICC_BD_CTL_Wrap) {            txbd = smc_chan->tbase;        } else {            txbd++;        }        if (txbd == txfirst) break;  // Went all the way around    }    smc_chan->txbd = txbd;    if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == 0) {        // Transmit buffer is not full/busy        txbd->buffer[txbd->length++] = c;        if (txbd->length == smc_chan->txsize) {            // This buffer is now full, tell SMC to start processing it            quicc_smc_serial_flush(smc_chan);        }        res = true;    } else {        // No space        res = false;    }    cyg_drv_dsr_unlock();    return res;}// Fetch a character from the device input buffer, waiting if necessarystatic unsigned char quicc_smc_serial_getc(serial_channel *chan){    unsigned char c;    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;    while ((rxbd->ctrl & QUICC_BD_CTL_Ready) != 0) ;    c = rxbd->buffer[0];    rxbd->length = smc_chan->rxsize;    rxbd->ctrl |= QUICC_BD_CTL_Ready;    if (rxbd->ctrl & QUICC_BD_CTL_Wrap) {        rxbd = smc_chan->rbase;    } else {        rxbd++;    }    smc_chan->rxbd = (struct cp_bufdesc *)rxbd;    return c;}// Set up the device characteristics; baud rate, etc.static bool quicc_smc_serial_set_config(serial_channel *chan, cyg_serial_info_t *config){    bool res = quicc_smc_serial_config_port(chan, config, false);    // FIXME - The documentation says that you can't change the baud rate    // again until at least two BRG input clocks have occurred.    return res;}// Enable the transmitter (interrupt) on the devicestatic voidquicc_smc_serial_start_xmit(serial_channel *chan){    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    if (smc_chan->txbd->length == 0) {        // See if there is anything to put in this buffer, just to get it going        cyg_drv_dsr_lock();        (chan->callbacks->xmt_char)(chan);        cyg_drv_dsr_unlock();    }    if (smc_chan->txbd->length != 0) {        // Make sure it gets started        quicc_smc_serial_flush(smc_chan);    }    smc_chan->tx_enabled = true;    cyg_drv_interrupt_unmask(smc_chan->int_num);}// Disable the transmitter on the devicestatic void quicc_smc_serial_stop_xmit(serial_channel *chan){    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    // If anything is in the last buffer, need to get it started    if (smc_chan->txbd->length != 0) {        quicc_smc_serial_flush(smc_chan);        // Note: interrupt will get masked after this buffer finishes    } else {        cyg_drv_interrupt_mask(smc_chan->int_num);    }    smc_chan->tx_enabled = false;}// Serial I/O - low level interrupt handler (ISR)static cyg_uint32 quicc_smc_serial_ISR(cyg_vector_t vector, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    cyg_drv_interrupt_mask(smc_chan->int_num);    return CYG_ISR_CALL_DSR;  // Cause DSR to be run}// Serial I/O - high level interrupt handler (DSR)static void       quicc_smc_serial_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data){    serial_channel *chan = (serial_channel *)data;    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    volatile struct smc_regs *ctl = smc_chan->ctl;    volatile struct cp_bufdesc *txbd;    volatile struct cp_bufdesc *rxbd = smc_chan->rxbd;    struct cp_bufdesc *rxlast;    int i, cache_state;#ifdef CYGDBG_DIAG_BUF    int _time, _stime;    externC cyg_tick_count_t cyg_current_time(void);    cyg_drv_isr_lock();    enable_diag_uart = 0;    HAL_CLOCK_READ(&_time);    _stime = (int)cyg_current_time();    diag_printf("DSR start - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time);    enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF    if (ctl->smc_smce & QUICC_SMCE_TX) {#ifdef XX_CYGDBG_DIAG_BUF        enable_diag_uart = 0;        txbd = smc_chan->tbase;        for (i = 0;  i < CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM;  i++, txbd++) {            diag_printf("Tx BD: %x, length: %d, ctl: %x\n", txbd, txbd->length, txbd->ctrl);        }        enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF        // Transmit interrupt        ctl->smc_smce = QUICC_SMCE_TX;  // Reset interrupt state;        txbd = smc_chan->tbase;  // First buffer        while (true) {            if ((txbd->ctrl & (QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {#ifdef XX_CYGDBG_DIAG_BUF                enable_diag_uart = 0;                HAL_CLOCK_READ(&_time);                _stime = (int)cyg_current_time();                diag_printf("TX Done - Tx: %x, length: %d, time: %x.%x\n", txbd, txbd->length, _stime, _time);                enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF                txbd->length = 0;                txbd->ctrl &= ~QUICC_BD_CTL_Int;  // Reset interrupt bit            }            if (txbd->ctrl & QUICC_BD_CTL_Wrap) {                txbd = smc_chan->tbase;                break;            } else {                txbd++;            }        }        (chan->callbacks->xmt_char)(chan);    }    while (ctl->smc_smce & QUICC_SMCE_RX) {        // Receive interrupt        ctl->smc_smce = QUICC_SMCE_RX;  // Reset interrupt state;        rxlast = (struct cp_bufdesc *) (            (char *)eppc_base() + smc_chan->pram->rbptr );#ifdef CYGDBG_DIAG_BUF        enable_diag_uart = 0;        HAL_CLOCK_READ(&_time);        _stime = (int)cyg_current_time();        diag_printf("Scan RX - rxbd: %x, rbptr: %x, time: %x.%x\n", rxbd, rxlast, _stime, _time);#endif // CYGDBG_DIAG_BUF        while (rxbd != rxlast) {            if ((rxbd->ctrl & QUICC_BD_CTL_Ready) == 0) {#ifdef CYGDBG_DIAG_BUF                diag_printf("rxbuf: %x, flags: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length);                diag_dump_buf(rxbd->buffer, rxbd->length);#endif // CYGDBG_DIAG_BUF                for (i = 0;  i < rxbd->length;  i++) {                    (chan->callbacks->rcv_char)(chan, rxbd->buffer[i]);                }                // Note: the MBX860 does not seem to snoop/invalidate the data cache properly!                HAL_DCACHE_IS_ENABLED(cache_state);                if (cache_state) {                    HAL_DCACHE_INVALIDATE(rxbd->buffer, smc_chan->rxsize);  // Make sure no stale data                }                rxbd->length = 0;                rxbd->ctrl |= QUICC_BD_CTL_Ready;            }            if (rxbd->ctrl & QUICC_BD_CTL_Wrap) {                rxbd = smc_chan->rbase;            } else {                rxbd++;            }        }#ifdef CYGDBG_DIAG_BUF        enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF        smc_chan->rxbd = (struct cp_bufdesc *)rxbd;    }    if (ctl->smc_smce & QUICC_SMCE_BSY) {#ifdef CYGDBG_DIAG_BUF        enable_diag_uart = 0;        diag_printf("RX BUSY interrupt\n");        enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF        ctl->smc_smce = QUICC_SMCE_BSY;  // Reset interrupt state;    }#ifdef CYGDBG_DIAG_BUF    enable_diag_uart = 0;    HAL_CLOCK_READ(&_time);    _stime = (int)cyg_current_time();    diag_printf("DSR done - CE: %x, time: %x.%x\n", ctl->smc_smce, _stime, _time);    enable_diag_uart = 1;#endif // CYGDBG_DIAG_BUF    cyg_drv_interrupt_acknowledge(smc_chan->int_num);    cyg_drv_interrupt_unmask(smc_chan->int_num);#ifdef CYGDBG_DIAG_BUF    cyg_drv_isr_unlock();#endif // CYGDBG_DIAG_BUF}voidshow_rxbd(int dump_all){#ifdef CYGDBG_DIAG_BUF    EPPC *eppc = eppc_base();    struct smc_uart_pram *pram = &eppc->pram[2].scc.pothers.smc_modem.psmc.u;    struct cp_bufdesc *rxbd = (struct cp_bufdesc *)((char *)eppc+pram->rbase);    int _enable = enable_diag_uart;    enable_diag_uart = 0;#if 1    diag_printf("SMC Mask: %x, Events: %x, Rbase: %x, Rbptr: %x\n",                 eppc->smc_regs[0].smc_smcm, eppc->smc_regs[0].smc_smce,                pram->rbase, pram->rbptr);    while (true) {        diag_printf("Rx BD: %x, ctl: %x, length: %d\n", rxbd, rxbd->ctrl, rxbd->length);        if (rxbd->ctrl & QUICC_BD_CTL_Wrap) break;        rxbd++;    }#endif    enable_diag_uart = _enable;    if (dump_all) dump_diag_buf();#endif // CYGDBG_DIAG_BUF}#endif // CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC// ------------------------------------------------------------------------// EOF powerpc/quicc_smc_serial.c

⌨️ 快捷键说明

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