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

📄 quicc_smc_serial.c

📁 eCos1.31版
💻 C
📖 第 1 页 / 共 3 页
字号:
}// Function to set up internal tables for device.static voidquicc_smc_serial_init_info(quicc_smc_serial_info *smc_chan,                           volatile struct smc_uart_pram *uart_pram,                           volatile struct smc_regs *ctl,                           int TxBD, int TxNUM, int TxSIZE,                           cyg_uint8 *TxBUF,                           int RxBD, int RxNUM, int RxSIZE,                           cyg_uint8 *RxBUF,                           int portBmask,                           int BRG, int SIpos){    EPPC *eppc = eppc_base();    struct cp_bufdesc *txbd, *rxbd;    cyg_uint32 simode = 0;    int i;    // Disable channel during setup    ctl->smc_smcmr = QUICC_SMCMR_UART;  // Disabled, UART mode    smc_chan->pram = uart_pram;    smc_chan->ctl = ctl;    /*     *  SDMA & LCD bus request level 5     *  (Section 16.10.2.1)     */    eppc->dma_sdcr = 1;    switch (BRG) {    case 1:        smc_chan->brg = (cyg_uint32 *)&eppc->brgc1;        simode = 0;        break;    case 2:        smc_chan->brg = (cyg_uint32 *)&eppc->brgc2;        simode = 1;        break;    case 3:        smc_chan->brg = (cyg_uint32 *)&eppc->brgc3;        simode = 2;        break;    case 4:        smc_chan->brg = (cyg_uint32 *)&eppc->brgc4;        simode = 3;        break;    }    // NMSI mode, BRGn to SMCm  (Section 16.12.5.2)    eppc->si_simode = (eppc->si_simode & ~(0xF<<SIpos)) | (simode<<SIpos);    /*     *  Set up the PortB pins for UART operation.     *  Set PAR and DIR to allow SMCTXDx and SMRXDx     *  (Table 16-39)     */    eppc->pip_pbpar |= portBmask;    eppc->pip_pbdir &= ~portBmask;    /*     *  Reset Rx & Tx params     */    eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;    /*     *  SDMA & LCD bus request level 5     *  (Section 16.10.2.1)     */    eppc->dma_sdcr = 1;    /*     *  Set Rx and Tx function code     *  (Section 16.15.4.2)     */    uart_pram->rfcr = 0x18;    uart_pram->tfcr = 0x18;    /*     *  Set pointers to buffer descriptors.     *  (Sections 16.15.4.1, 16.15.7.12, and 16.15.7.13)     */    uart_pram->rbase = RxBD;    uart_pram->tbase = TxBD;    /* tx and rx buffer descriptors */    txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);    rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);    smc_chan->txbd = txbd;    smc_chan->tbase = txbd;    smc_chan->txsize = TxSIZE;    smc_chan->rxbd = rxbd;    smc_chan->rbase = rxbd;    smc_chan->rxsize = RxSIZE;    /* max receive buffer length */    uart_pram->mrblr = RxSIZE;    /* set max_idle feature - generate interrupt after 4 chars idle period */    uart_pram->max_idl = 4;    /* no last brk char received */    uart_pram->brkln = 0;    /* no break condition occurred */    uart_pram->brkec = 0;    /* 1 break char sent on top XMIT */    uart_pram->brkcr = 1;    /* setup RX buffer descriptors */    for (i = 0;  i < RxNUM;  i++) {        rxbd->length = 0;        rxbd->buffer = RxBUF;        rxbd->ctrl   = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;        if (i == (RxNUM-1)) rxbd->ctrl |= QUICC_BD_CTL_Wrap;  // Last buffer        RxBUF += RxSIZE;        rxbd++;    }    /* setup TX buffer descriptors */    for (i = 0;  i < TxNUM;  i++) {        txbd->length = 0;        txbd->buffer = TxBUF;        txbd->ctrl   = 0;        if (i == (TxNUM-1)) txbd->ctrl |= QUICC_BD_CTL_Wrap;  // Last buffer        TxBUF += TxSIZE;        txbd++;    }    /*     *  Clear any previous events. Enable interrupts.     *  (Section 16.15.7.14 and 16.15.7.15)     */    ctl->smc_smce = 0xFF;    ctl->smc_smcm = QUICC_SMCE_BSY|QUICC_SMCE_TX|QUICC_SMCE_RX;}// Function to initialize the device.  Called at bootstrap time.static bool quicc_smc_serial_init(struct cyg_devtab_entry *tab){    serial_channel *chan = (serial_channel *)tab->priv;    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    volatile EPPC *eppc = (volatile EPPC *)eppc_base();    int TxBD, RxBD;    static int first_init = 1;    int cache_state;    HAL_DCACHE_IS_ENABLED(cache_state);    HAL_DCACHE_SYNC();    HAL_DCACHE_DISABLE();#ifdef CYGDBG_IO_INIT    diag_printf("QUICC_SMC SERIAL init - dev: %x.%d\n", smc_chan->channel, smc_chan->int_num);#endif    if (first_init) {        // Set up tables since many fields are dynamic [computed at runtime]        first_init = 0;#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC1        eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go;  // Totally reset CP        while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ;        TxBD = 0x2800;  // Note: this should be configurable        RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM*8;        quicc_smc_serial_init_info(&quicc_smc_serial_info1,                                   &eppc->pram[2].scc.pothers.smc_modem.psmc.u, // PRAM                                   &eppc->smc_regs[0], // Control registers                                   TxBD,                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxNUM,                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_TxSIZE,                                   &quicc_smc1_txbuf[0][0],                                   RxBD,                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM,                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxSIZE,                                   &quicc_smc1_rxbuf[0][0],                                   0xC0, // PortB mask                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_BRG,                                   12  // SI mask position            );        TxBD = RxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC1_RxNUM*8;#else#ifdef CYGPKG_HAL_POWERPC_MBX        // Ensure the SMC1 side is initialized first and use shared mem        // above where it plays:        diag_init();    // (pull in constructor that inits diag channel)        TxBD = 0x2830;  // Note: this should be inferred from the chip state#else        // there is no diag device wanting to use the QUICC, so prepare it        // for SMC2 use only.        eppc->cp_cr = QUICC_SMC_CMD_Reset | QUICC_SMC_CMD_Go;  // Totally reset CP        while (eppc->cp_cr & QUICC_SMC_CMD_Reset) ;        TxBD = 0x2800;  // Note: this should be configurable#endif        #endif#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SMC2        RxBD = TxBD + CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM*8;        quicc_smc_serial_init_info(&quicc_smc_serial_info2,                                   &eppc->pram[3].scc.pothers.smc_modem.psmc.u, // PRAM                                   &eppc->smc_regs[1], // Control registers                                   TxBD,                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxNUM,                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_TxSIZE,                                   &quicc_smc2_txbuf[0][0],                                   RxBD,                                    CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxNUM,                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_RxSIZE,                                   &quicc_smc2_rxbuf[0][0],                                   0xC00, // PortB mask                                   CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SMC2_BRG,                                   28  // SI mask position            );#endif    }    (chan->callbacks->serial_init)(chan);  // Really only required for interrupt driven devices    if (chan->out_cbuf.len != 0) {        cyg_drv_interrupt_create(smc_chan->int_num,                                 CYGARC_SIU_PRIORITY_HIGH, // Priority - unused (but asserted)                                 (cyg_addrword_t)chan,   //  Data item passed to interrupt handler                                 quicc_smc_serial_ISR,                                 quicc_smc_serial_DSR,                                 &smc_chan->serial_interrupt_handle,                                 &smc_chan->serial_interrupt);        cyg_drv_interrupt_attach(smc_chan->serial_interrupt_handle);        cyg_drv_interrupt_mask(smc_chan->int_num);        smc_chan->tx_enabled = false;    }    quicc_smc_serial_config_port(chan, &chan->config, true);    if (cache_state)        HAL_DCACHE_ENABLE();    return true;}// This routine is called when the device is "looked" up (i.e. attached)static Cyg_ErrNo quicc_smc_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;}// Force the current transmit buffer to be sentstatic voidquicc_smc_serial_flush(quicc_smc_serial_info *smc_chan){    volatile struct cp_bufdesc *txbd = smc_chan->txbd;    if ((txbd->length > 0) && ((txbd->ctrl & QUICC_BD_CTL_Ready) == 0)) {        txbd->ctrl |= QUICC_BD_CTL_Ready|QUICC_BD_CTL_Int;  // Signal buffer ready        if (txbd->ctrl & QUICC_BD_CTL_Wrap) {            txbd = smc_chan->tbase;        } else {            txbd++;        }        smc_chan->txbd = txbd;    }}// Send a character to the device output buffer.// Return 'true' if character is sent to devicestatic boolquicc_smc_serial_putc(serial_channel *chan, unsigned char c){    quicc_smc_serial_info *smc_chan = (quicc_smc_serial_info *)chan->dev_priv;    volatile struct cp_bufdesc *txbd, *txfirst;    EPPC *eppc = eppc_base();

⌨️ 快捷键说明

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