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

📄 smcuart.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
字号:
/*
 * File:        smcuart.c
 * Purpose:     Polling driver for MPC8XX UART on SMC1 or SMC2
 *
 * Notes:       This file included by smc1uart.c or smc2uart.c
 *
 *
 * Modifications:
 *   
 */  

/********************************************************************/

/*
 * In order to use this dBUG driver, the following assumptions are made:
 *
 * UART on SMC1
 * o BRG1 is allocated to SMC1
 * o Pin PB24 is allocated to SMC1
 * o Pin PB25 is allocated to SMC1
 * o the macro BD_SMC1_TX exists for allocating a BD for SMC Tx
 * o the macro BD_SMC1_RX exists for allocating a BD for SMC Rx
 *
 * UART on SMC2
 * o BRG2 is allocated to SMC2
 * o For MPC821/MPC860, PB20 and PB21 are allocated to SMC2
 * o For MPC823/MPC850, PA8 and PA9 are allocated to SMC2
 * o the macro BD_SMC2_TX exists for allocating a BD for SMC Tx
 * o the macro BD_SMC2_RX exists for allocating a BD for SMC Rx
 *
 * The pin configurations are normally performed in mpcinit.c, and the
 * macros defined in board.h.
 */

#include "src/include/dbug.h"
#include "smcuart.h"

/********************************************************************/

#if     (defined(SMC1UART))

#define _BD_SMC_RX_                     BD_SMC1_RX
#define _BD_SMC_TX_                     BD_SMC1_TX
#define _BRG_                           BRGC1
#define _MPC8XX_CP_CPCR_CHANNEL_SMCx_   MPC8XX_CP_CPCR_CHANNEL_SMC1
#define SMC_INIT                        mpc8xx_smc1_init
#define SMC_PUTCHAR                     mpc8xx_smc1_putchar
#define SMC_GETCHAR                     mpc8xx_smc1_getchar
#define SMC_CHAR_PRESENT                mpc8xx_smc1_char_present

#elif   (defined(SMC2UART))

#define _BD_SMC_RX_                     BD_SMC2_RX
#define _BD_SMC_TX_                     BD_SMC2_TX
#define _BRG_                           BRGC2
#define _MPC8XX_CP_CPCR_CHANNEL_SMCx_   MPC8XX_CP_CPCR_CHANNEL_SMC2
#define SMC_INIT                        mpc8xx_smc2_init
#define SMC_PUTCHAR                     mpc8xx_smc2_putchar
#define SMC_GETCHAR                     mpc8xx_smc2_getchar
#define SMC_CHAR_PRESENT                mpc8xx_smc2_char_present

#else
#error "Unsupported configuration"
#endif

/********************************************************************/

/*
 * Local buffers for CPM to DMA characters
 */

static char
rx_buf[16];

static char
tx_buf[16];

/********************************************************************/
void
SMC_INIT (int div, int div16)
{
    /*
     * This routine initializes SMC as a UART for 8N1.
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();
    MPC8XX_SMC *smc;
    MPC8XX_PRAM_SMCUART *smcpram;
    MPC8XX_BD *rxbd, *txbd;

    smc = (MPC8XX_SMC *)&imm-> _SMC_ ;
    smcpram = (MPC8XX_PRAM_SMCUART *)&imm->dpram. _SMC_ ;

#if (defined(SMC1UART))

    /*
     * Configure SMC1 pins
     */
    imm->pip.PBPAR |= ( 0
        | MPC8XX_PIP_PBPAR_PB24 /* PB24=1, SMRXD1 */
        | MPC8XX_PIP_PBPAR_PB25 /* PB25=1, SMTXD1 */
        ) ;

    imm->pip.PBDIR &= ~( 0
        | MPC8XX_PIP_PBDIR_PB24 /* PB24=0, SMRXD1 */
        | MPC8XX_PIP_PBDIR_PB25 /* PB25=0, SMTXD1 */
        ) ;

    imm->pip.PBODR &= ~( 0
        | MPC8XX_PIP_PBODR_PB24 /* PB24=0, active out */
        | MPC8XX_PIP_PBODR_PB25 /* PB25=0, active out */
        ) ;

#endif

#if (defined(SMC2UART))

#if  (defined(CPU_MPC823) || defined(CPU_MPC850))

    /*
     * Configure SMC2 pins SMTXD2 and SMRXD2 on PA8,9
     */
    imm->portio.PAPAR |= ( 0
        | MPC8XX_PORTIO_PAPAR_PA8   /* PA8=1, SMTXD2 */
        | MPC8XX_PORTIO_PAPAR_PA9   /* PA9=1, SMRXD2 */
        ) ;

    imm->portio.PADIR &= ~( 0
        | MPC8XX_PORTIO_PADIR_PA8   /* PA8=0, SMTXD2 */
        | MPC8XX_PORTIO_PADIR_PA9   /* PA9=0, SMRXD2 */
        ) ;

    /* PAODR[9] = ?? */

#else

    /*
     * Configure SMC2 pins SMTXD2 and SMRXD2 on PB20,21
     */
    imm->pip.PBPAR |= ( 0
        | MPC8XX_PIP_PBPAR_PB20 /* PB20=1, SMRXD2 */
        | MPC8XX_PIP_PBPAR_PB21 /* PB21=1, SMTXD2 */
        ) ;

    imm->pip.PBDIR &= ~( 0
        | MPC8XX_PIP_PBDIR_PB20 /* PB20=0, SMRXD2 */
        | MPC8XX_PIP_PBDIR_PB21 /* PB21=0, SMTXD2 */
        ) ;

    imm->pip.PBODR &= ~( 0
        | MPC8XX_PIP_PBODR_PB20 /* PB20=0, active out */
        | MPC8XX_PIP_PBODR_PB21 /* PB21=0, active out */
        ) ;
#endif

#endif /* SMCxUART */

    /*
     * Configure baud rate generator
     */
    imm->brgs. _BRG_ = ( 0
        | MPC8XX_BRGC_EN
        | MPC8XX_BRGC_CLK_BRGCLK
        | div
        | div16
        ) ;

    /*
     * Setup buffers for use by SMC UART
     */
    rxbd = &imm->dpram.bd[ _BD_SMC_RX_ ];
    txbd = &imm->dpram.bd[ _BD_SMC_TX_ ];
    smcpram->smc.RBASE = (uint16)((uint32)rxbd);
    smcpram->smc.TBASE = (uint16)((uint32)txbd);

    rxbd->status = ( 0
        | MPC8XX_BD_SMC_RX_STATUS_E
        | MPC8XX_BD_SMC_RX_STATUS_W
        ) ;
    rxbd->length = 0;
    rxbd->address = (uint32)&rx_buf[0];

    txbd->status = ( 0
        | MPC8XX_BD_SMC_TX_STATUS_W
        ) ;
    txbd->length = 1;
    txbd->address = (uint32)&tx_buf[0];

    /*
     * Initialize parameter RAM
     */
    smcpram->smc.RFCR = MPC8XX_SMC_FCR_BO_BE;
    smcpram->smc.TFCR = MPC8XX_SMC_FCR_BO_BE;
    smcpram->smc.MRBLR = 1;
    smcpram->uart.MAX_IDL = 0;
    smcpram->uart.BRKLN = 0;
    smcpram->uart.BRKCR = 1;
    smcpram->uart.BRKEC = 0;

    /*
     * Initialize Tx and Rx Parameters and wait for Ack
     */
    imm->cp.CPCR = ( 0
        | MPC8XX_CP_CPCR_OPCODE_INIT_RX_TX
        | _MPC8XX_CP_CPCR_CHANNEL_SMCx_
        | MPC8XX_CP_CPCR_FLG
        ) ;
    while (imm->cp.CPCR & MPC8XX_CP_CPCR_FLG)
        ;

    smc->SMCE = ~0; /* clear int sources */
    smc->SMCM = 0;      /* no interrupts */

    /*
     * Configure SMC as UART, 8N1
     */
    smc->SMCMR = ( 0
        | MPC8XX_SMC_SMCMR_CLEN_9
        | MPC8XX_SMC_SMCMR_SL_1BIT
        | MPC8XX_SMC_SMCMR_PEN_NONE
        | MPC8XX_SMC_SMCMR_SM_UART
        | MPC8XX_SMC_SMCMR_DM_NORMAL
        ) ;

    /*
     * Allow Rx and TX
     */
    smc->SMCMR |= ( 0
        | MPC8XX_SMC_SMCMR_TEN 
        | MPC8XX_SMC_SMCMR_REN
        ) ;
}

/********************************************************************/
void
SMC_PUTCHAR (int ch)
{
    /*
     * This routine puts one char thru SMC
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();
    MPC8XX_PRAM_SMCUART *smcpram;
    MPC8XX_BD *txbd;

    smcpram = (MPC8XX_PRAM_SMCUART *)&imm->dpram. _SMC_ ;

    txbd = (MPC8XX_BD *)((uint32)smcpram->smc.TBASE + (uint32)imm);

    while (txbd->status & MPC8XX_BD_SMC_TX_STATUS_R)
        ;

    *(unsigned char *)txbd->address = ch;
    txbd->length = 1;
    txbd->status |= MPC8XX_BD_SMC_TX_STATUS_R;
}

/********************************************************************/
int
SMC_GETCHAR (void)
{
    /*
     * This routine gets one char from SMC
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();
    MPC8XX_PRAM_SMCUART *smcpram;
    MPC8XX_BD *rxbd;
    int ch;

    smcpram = (MPC8XX_PRAM_SMCUART *)&imm->dpram. _SMC_ ;

    rxbd = (MPC8XX_BD *)((uint32)smcpram->smc.RBASE + (uint32)imm);

    while (rxbd->status & MPC8XX_BD_SMC_RX_STATUS_E)
        ;
    ch = *(unsigned char *)rxbd->address;
    rxbd->status |= MPC8XX_BD_SMC_RX_STATUS_E;

    return ch;
}

/********************************************************************/
int
SMC_CHAR_PRESENT (void)
{
    /*
     * This routine detects if char on SMC
     */
    MPC8XX_IMM *imm = mpc8xx_get_immp();
    MPC8XX_PRAM_SMCUART *smcpram;
    MPC8XX_BD *rxbd;

    smcpram = (MPC8XX_PRAM_SMCUART *)&imm->dpram. _SMC_ ;

    rxbd = (MPC8XX_BD *)((uint32)smcpram->smc.RBASE + (uint32)imm);

    return !(rxbd->status & MPC8XX_BD_SMC_RX_STATUS_E);
}

⌨️ 快捷键说明

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