quicc_smc_serial.c

来自「eCos操作系统源码」· C语言 代码 · 共 1,104 行 · 第 1/4 页

C
1,104
字号
DEVTAB_ENTRY(quicc_smc_serial_io_scc2,              CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC2_NAME,             0,                     // Does not depend on a lower level interface             &cyg_io_serial_devio,              quicc_sxx_serial_init,              quicc_sxx_serial_lookup,     // Serial driver may need initializing             &quicc_sxx_serial_channel_scc2    );#endif //  CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC2#ifdef CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3static quicc_sxx_serial_info quicc_sxx_serial_info_scc3 = {    QUICC_CPM_SCC3,                     // Channel indicator    CYGNUM_HAL_INTERRUPT_CPM_SCC3,      // interrupt    _SCC_CHAN};#if CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE > 0static unsigned char quicc_smc_serial_out_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE];static unsigned char quicc_smc_serial_in_buf_scc3[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BUFSIZE];static SERIAL_CHANNEL_USING_INTERRUPTS(quicc_sxx_serial_channel_scc3,                                       quicc_sxx_serial_funs,                                        quicc_sxx_serial_info_scc3,                                       CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BAUD),                                       CYG_SERIAL_STOP_DEFAULT,                                       CYG_SERIAL_PARITY_DEFAULT,                                       CYG_SERIAL_WORD_LENGTH_DEFAULT,                                       CYG_SERIAL_FLAGS_DEFAULT,                                       &quicc_smc_serial_out_buf_scc3[0], sizeof(quicc_smc_serial_out_buf_scc3),                                       &quicc_smc_serial_in_buf_scc3[0], sizeof(quicc_smc_serial_in_buf_scc3)    );#elsestatic SERIAL_CHANNEL(quicc_sxx_serial_channel_scc3,                      quicc_sxx_serial_funs,                       quicc_sxx_serial_info_scc3,                      CYG_SERIAL_BAUD_RATE(CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_BAUD),                      CYG_SERIAL_STOP_DEFAULT,                      CYG_SERIAL_PARITY_DEFAULT,                      CYG_SERIAL_WORD_LENGTH_DEFAULT,                      CYG_SERIAL_FLAGS_DEFAULT    );#endifstatic unsigned char quicc_scc3_txbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_TxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));static unsigned char quicc_scc3_rxbuf[CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxNUM*CYGNUM_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_RxSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));DEVTAB_ENTRY(quicc_smc_serial_io_scc3,              CYGDAT_IO_SERIAL_POWERPC_QUICC_SMC_SCC3_NAME,             0,                     // Does not depend on a lower level interface             &cyg_io_serial_devio,              quicc_sxx_serial_init,              quicc_sxx_serial_lookup,     // Serial driver may need initializing             &quicc_sxx_serial_channel_scc3    );#endif //  CYGPKG_IO_SERIAL_POWERPC_QUICC_SMC_SCC3// Internal function to actually configure the hardware to desired baud rate, etc.static boolquicc_smc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init){    quicc_sxx_serial_info *smc_chan = (quicc_sxx_serial_info *)chan->dev_priv;    unsigned int baud_divisor = select_baud[new_config->baud];    cyg_uint32 _lcr;    EPPC *eppc = eppc_base();    volatile struct smc_regs *ctl = (volatile struct smc_regs *)smc_chan->ctl;    if (baud_divisor == 0) return false;    // Disable channel during setup    ctl->smc_smcmr = QUICC_SMCMR_UART;  // Disabled, UART mode    HAL_IO_BARRIER();  // Inforce I/O ordering    // Disable port interrupts while changing hardware    _lcr = smc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |         smc_select_stop_bits[new_config->stop] |        smc_select_parity[new_config->parity];    // Stop transmitter while changing baud rate    eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_StopTx;    HAL_IO_BARRIER();  // Inforce I/O ordering    // Set baud rate generator    *smc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);    // Enable channel with new configuration    ctl->smc_smcmr = QUICC_SMCMR_UART|QUICC_SMCMR_TEN|QUICC_SMCMR_REN|_lcr;    HAL_IO_BARRIER();  // Inforce I/O ordering    eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_RestartTx;    if (new_config != &chan->config) {        chan->config = *new_config;    }    return true;}// Function to set up internal tables for device.static voidquicc_smc_serial_init_info(quicc_sxx_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 port){    EPPC *eppc = eppc_base();    struct cp_bufdesc *txbd, *rxbd;    int i;        smc_chan->pram = (void *)uart_pram;    smc_chan->ctl = (void *)ctl;    // Set up baud rate generator    smc_chan->brg = _mpc8xx_allocate_brg(port);    // Disable channel during setup    ctl->smc_smcmr = QUICC_SMCMR_UART;  // Disabled, UART mode    /*     *  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;    /*     *  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++;    }    /*     *  Reset Rx & Tx params     */    HAL_IO_BARRIER();  // Inforce I/O ordering    eppc->cp_cr = smc_chan->channel | QUICC_SMC_CMD_Go | QUICC_SMC_CMD_InitTxRx;    HAL_IO_BARRIER();  // Inforce I/O ordering    /*     *  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;}// Internal function to actually configure the hardware to desired baud rate, etc.static boolquicc_scc_serial_config_port(serial_channel *chan, cyg_serial_info_t *new_config, bool init){    quicc_sxx_serial_info *scc_chan = (quicc_sxx_serial_info *)chan->dev_priv;    unsigned int baud_divisor = select_baud[new_config->baud];    EPPC *eppc = eppc_base();    volatile struct scc_regs *regs = (volatile struct scc_regs *)scc_chan->ctl;    if (baud_divisor == 0) return false;    // Set baud rate generator    *scc_chan->brg = 0x10000 | (UART_BITRATE(baud_divisor)<<1);    // Disable channel during setup    HAL_IO_BARRIER();  // Inforce I/O ordering    regs->scc_gsmr_l = 0;    regs->scc_psmr = QUICC_SCC_PSMR_ASYNC |         scc_select_word_length[new_config->word_length - CYGNUM_SERIAL_WORD_LENGTH_5] |         scc_select_stop_bits[new_config->stop] |        scc_select_parity[new_config->parity];    // Enable channel with new configuration    regs->scc_gsmr_h = 0x20;          // 8bit FIFO    regs->scc_gsmr_l = 0x00028004;    // 16x TxCLK, 16x RxCLK, UART    /*     *  Init Rx & Tx params for SCCX     */    HAL_IO_BARRIER();  // Inforce I/O ordering    eppc->cp_cr = QUICC_CPM_CR_INIT_TXRX | scc_chan->channel | QUICC_CPM_CR_BUSY;    HAL_IO_BARRIER();  // Inforce I/O ordering    regs->scc_gsmr_l |= (QUICC_SCC_GSMR_L_Tx | QUICC_SCC_GSMR_L_Rx);  // Enable Rx, Tx    if (new_config != &chan->config) {        chan->config = *new_config;    }    return true;}// Function to set up internal tables for device.static voidquicc_scc_serial_init_info(quicc_sxx_serial_info *scc_chan,                           volatile struct uart_pram *uart_pram,                           volatile struct scc_regs *ctl,                           int TxBD, int TxNUM, int TxSIZE,                           cyg_uint8 *TxBUF,                           int RxBD, int RxNUM, int RxSIZE,                           cyg_uint8 *RxBUF,                           int portAmask, int portBmask, int portCmask,                           int port){    EPPC *eppc = eppc_base();    struct cp_bufdesc *txbd, *rxbd;    int i;    // Disable channel during setup    ctl->scc_gsmr_l = 0;    scc_chan->pram = (void *)uart_pram;    scc_chan->ctl = (void *)ctl;    // Set up baud rate generator    scc_chan->brg = _mpc8xx_allocate_brg(port);    /*     *  Set up the PortA/B/C pins for UART operation.     */    eppc->pio_papar |= portAmask;    eppc->pio_padir &= ~portAmask;    eppc->pio_paodr &= ~portAmask;    eppc->pio_pcdir &= portCmask;    eppc->pio_pcpar &= portCmask;    eppc->pio_pcso  |= portCmask;    eppc->pip_pbpar |= portBmask;    eppc->pip_pbdir |= portBmask;    /*     *  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;

⌨️ 快捷键说明

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