📄 smcuart.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 + -