📄 new_smc2.c
字号:
/*-------------------------------------------------------------------------
* FILENAME: smc2.c
*
* DESCRIPTION:
*
* The code in this module provides echo capability on SMC2. It's
* intent is to provide the beginnings of a debug port that is
* mostly compiler independent. If an ASCII terminal is connected
* at 9600,N,8,1 on Port 2 (PB3) on the ADS board with no hardware
* control, characters typed on the keyboard will be received by
* SMC2 and echoed back out the RS232 port to the ASCII terminal.
* This function was designed and tested on an ADS860
* development board. Note that if a different baud rate is
* required, there is a header file on the netcomm website under
* the General Software category that is labelled "Asynchronous
* Baud Rate Tables".
*
* REFERENCES:
*
* 1) MPC860 Users Manual
* 2) PowerPC Microprocessor Family: The Programming Environments for
* 32-Bit Microprocessors
*
* HISTORY:
*
* 27 APR 98 jay initial release
*
*-------------------------------------------------------------------------*/
#include "netcomm.h"
#include "mpc860.h"
#include "masks860.h"
#include "smc2.h"
int stack[100]=0;
int stackTop;
/***********************/
/* Global Declarations */
/***********************/
EPPC *IMMR; /* IMMR base pointer */
BDRINGS *RxTxBD; /* buffer descriptors base pointer */
LB *SMC2Buffers; /* SMC2 base pointers */
/*---------------------*/
/* Function Prototypes */
/*---------------------*/
void startup(void);
void SMC2Init(void);
void SMC2PutChar(UBYTE);
UBYTE SMC2GetChar(void);
UBYTE SMC2Poll(void);
void main(void);
void InitBDs(void);
void EchoChar(void);
void startup (void)
{
asm(" .global _start ");
asm("_start: ");
asm(" addis r1,r0,stackTop@h");
asm(" ori r1,r1,stackTop@l");
main();
}
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: main
*
* DESCRIPTION:
*
* This is the main function for the SMC2 code.
*
* EXTERNAL EFFECT:
*
* PARAMETERS: None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void main(void)
{
/*------------------------*/
/* Establish IMMR pointer */
/*------------------------*/
IMMR = (EPPC *)(GetIMMR() & 0xFFFF0000); /* MPC8xx internal register
map */
/*--------------------------------------------------------------------*/
/* We add 64 bytes to the start of the buffer descriptors because */
/* this code was also tested on the monitor version of SDS debugger. */
/* The monitor program on our target uses most of the first 64 bytes */
/* for buffer descriptors. If you are not using the SDS monitor with */
/* Motorola's ADS development board, you can delete 64 below and */
/* start at the beginning of this particular block of Dual Port RAM. */
/*--------------------------------------------------------------------*/
/*----------------------------------*/
/* Get pointer to BD area on DP RAM */
/*----------------------------------*/
RxTxBD = (BDRINGS *)(IMMR->qcp_or_ud.ud.udata_bd + 64);
/*-------------------------------------------------------------------*/
/* Establish the buffer pool in Dual Port RAM. We do this because the*/
/* pool size is only 2 bytes (1 for Rx and 1 for Tx) and to avoid */
/* disabling data cache for the memory region where BufferPool would */
/* reside. The CPM does not recognize data in buffer pools once it */
/* been cached. It's acesses are direct through DMA to external */
/* memory. */
/*-------------------------------------------------------------------*/
SMC2Buffers = (LB *)(IMMR->qcp_or_ud.ud.udata_bd + 80);
/*----------------------------------------*/
/* Initialize SMC2 and buffer descriptors */
/*----------------------------------------*/
SMC2Init();
while (1)
{
/*--------------------------------------------------*/
/* if there is a receive character echo it back out */
/*--------------------------------------------------*/
if (SMC2Poll()) /* Check BD status for Rx characters */
EchoChar();
}
} /* END main */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: SMC2Init
*
* DESCRIPTION:
*
* Initialize SMC2 as a UART at 9600 Baud
* with 24MHZ CPU clock.
*
* EXTERNAL EFFECT:
*
* PARAMETERS: None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void SMC2Init(void)
{
unsigned long *bcsr1;
/*-----------------------*/
/* Allow SMC2 TX, RX out */
/*-----------------------*/
IMMR->pip_pbpar |= (0x0C00);
IMMR->pip_pbdir &= 0xF3FF; // 不去管它,基本是初始化B口为通用I/O
/*------------------------------------------------*/
/* Set Baud Rate to 9600 for 24MHz System Clock. */
/* Enable BRG Count. */
/*------------------------------------------------*/
IMMR->brgc2 = (0x0013E | 0x10000);//看不懂什么意思
IMMR->si_simode &= ~(0xF0000000); /* SCM2: NMSI mode */
IMMR->si_simode |= 0x10000000; /* SCM2: Tx/Rx Clocks are BRG2 */
/*----------------------------------------*/
/* Set RXBD table start at Dual Port +800 */
/*----------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.rbase =
(UHWORD)&RxTxBD->RxBD;
/*----------------------------------------*/
/* Set TXBD table start at Dual Port +808 */
/*----------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.tbase =
(UHWORD)&RxTxBD->TxBD;
/*---------------------------------------*/
/* Initialize Rx and Tx Params for SMC2: */
/* Spin until cpcr flag is cleared */
/*---------------------------------------*/
for(IMMR->cp_cr = 0x00d1; IMMR->cp_cr & 0x0001;) ;//cp_cr中的CH_HUM = 1101 指令在SMC2/DSP2/PIP 中运行
// CH_HUM = 1001 指令在SMC1/DSP1 中运行
/*--------------------------------------*/
/* Set RFCR,TFCR -- Rx,Tx Function Code */
/* Normal Operation and Motorola byte */
/* ordering */
/*--------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.rfcr = 0x18; //big-endian 数据
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.tfcr = 0x18;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/* Protocol Specific Parameters */
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*---------------------------*/
/* MRBLR = MAX buffer length */
/*---------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.mrblr = 1;
/*------------------------------------*/
/* MAX_IDL = Disable MAX Idle Feature */
/*------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.max_idl = 0;
/*-------------------------------------*/
/* BRKEC = No break condition occurred */
/*-------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.brkec = 0;
/*---------------------------------------*/
/* BRKCR = 1 break char sent on top XMIT */
/*---------------------------------------*/
IMMR->PRAM[PAGE4].pg.other.smc_dsp2.psmc2.u2.brkcr = 1;
/*--------------------*/
/* Initialize the BDs */
/*--------------------*/
InitBDs();
IMMR->smc_regs[SMC2_REG].smc_smce = 0xFF; /* Clear any pending events */
/*--------------------------------------------------*/
/* SMC_SMCM = Mask all interrupts, use polling mode */
/*--------------------------------------------------*/
IMMR->smc_regs[SMC2_REG].smc_smcm = 0;
IMMR->cpmi_cicr = 0; /* Disable all CPM interrups */
IMMR->cpmi_cipr = 0xFFFFFFFF; /* Clear all pending interrupt events */
IMMR->cpmi_cimr = 0; /* Mask all event interrupts */
/*-----------------------------------------------*/
/* Enable RS232 interface on ADS board via BCSR1 */
/* Get the base address of BCSR */
/*-----------------------------------------------*/
bcsr1 = (UWORD *) ((IMMR->memc_br1 & 0xFFFFFFFE) + 4);
*bcsr1 &= 0xFFFB0000; /* Assert the RS232EN* bit */
/*------------------------------------*/
/* 8-bit mode, no parity, 1 stop-bit */
/* UART SMC Mode */
/* Normal operation (no loopback), */
/* SMC Transmitter/Receiver Enabled */
/*------------------------------------*/
IMMR->smc_regs[SMC2_REG].smc_smcmr = 0x4823;//SMC模式寄存器,包括字符长度、协议、诊断模式、发送和接收使能
} /* END SMC2Init */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: InitBDs
*
* DESCRIPTION: This function initializes the Tx and Rx Buffer Descriptors.
*
* EXTERNAL EFFECT: RxTxBD
*
* PARAMETERS: None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void InitBDs(void)
{
/*-----------------------------------*/
/* Setup Receiver Buffer Descriptors */
/*-----------------------------------*/
RxTxBD->RxBD.bd_cstatus = 0xA000; //和mpc850 的RxBD不一样 E=1 ,W=1 /* Enable, Last BD */
RxTxBD->RxBD.bd_length = 1;
RxTxBD->RxBD.bd_addr = &(SMC2Buffers->RxBuffer);
/*--------------------------------------*/
/* Setup Transmitter Buffer Descriptors */
/*--------------------------------------*/
RxTxBD->TxBD.bd_cstatus = 0x2000;//和mpc850 的TxBD不一样 W=1 /* Buffer not yet ready; Last BD */
RxTxBD->TxBD.bd_length = 1;
RxTxBD->TxBD.bd_addr = &(SMC2Buffers->TxBuffer);
} /* END InitBDs */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: EchoChar
*
* DESCRIPTION: This function facilitates the echoing of a received character.
*
* EXTERNAL EFFECT: RxTxBD
*
* PARAMETERS: None
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void EchoChar(void)
{
UBYTE mych;
mych = SMC2GetChar();
SMC2PutChar(mych);
} /* end EchoChar */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: SMC2PutChar
*
* DESCRIPTION: Output a character to SMC2
*
* EXTERNAL EFFECT: RxTxBD
*
* PARAMETERS: ch - input character
*
* RETURNS: None
*
*---------------------------------------------------------------------------*/
void SMC2PutChar(UBYTE ch)
{
/*-----------------------------------*/
/* Loop until transmission completed */
/*-----------------------------------*/
while (RxTxBD->TxBD.bd_cstatus & 0x8000);
/*------------*/
/* Store data */
/*------------*/
*(RxTxBD->TxBD.bd_addr) = ch;
RxTxBD->TxBD.bd_length = 1;
/*---------------*/
/* Set Ready bit */
/*---------------*/
RxTxBD->TxBD.bd_cstatus |= 0x8000;
} /* END SMC2PutChar */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: SMC2GetChar
*
* DESCRIPTION: Get a character from SMC2
*
* EXTERNAL EFFECT: RxTxBD
*
* PARAMETERS: NONE
*
* RETURNS: A character from SMC2
*
*---------------------------------------------------------------------------*/
UBYTE SMC2GetChar(void)
{
UBYTE ch; /* output character from SMC2 */
/*--------------------*/
/* Loop if RxBD empty */
/*--------------------*/
while (RxTxBD->RxBD.bd_cstatus & 0x8000);
/*--------------*/
/* Receive data */
/*--------------*/
ch = *(RxTxBD->RxBD.bd_addr);
/*----------------------*/
/* Set Buffer Empty bit */
/*----------------------*/
RxTxBD->RxBD.bd_cstatus |= 0x8000;
return ch;
} /* END SMC2GetChar */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: SMC2Poll
*
* DESCRIPTION: Poll SMC2 RxBD and check to see if a character was received
*
* EXTERNAL EFFECT: NONE
*
* PARAMETERS: NONE
*
* RETURNS: A one if there is a character available in the receive buffer,
* else zero.
*
*---------------------------------------------------------------------------*/
UBYTE SMC2Poll(void)
{
if(RxTxBD->RxBD.bd_cstatus & 0x8000)
{
return 0; /* character NOT available */
}
else
{
return 1; /* character IS available */
}
} /* END SMC2Poll */
/*-----------------------------------------------------------------------------
*
* FUNCTION NAME: GetIMMR
*
* DESCRIPTION: Returns current value in the IMMR register.
*
* EXTERNAL EFFECT: NONE
*
* PARAMETERS: NONE
*
* RETURNS: The IMMR value in r3. The compiler uses r3 as the register
* containing the return value.
*
*---------------------------------------------------------------------------*/
GetIMMR()
{
asm(" mfspr r3,638 "); /* IMMR is spr #638 */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -