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

📄 smc.c

📁 PowerPC与PC微机串行通信
💻 C
字号:
/*****************************************************************************
* FILENAME: smc.c
*
* DESCRIPTION:
*
* The code in this module provides echo capability on SMC1. It's
* intent is to provide the beginnings of a debug port that is
* mostly compiler independent. If an ASCII terminal is connected
* at 38400, N, 8, 1 on port 2(PB3) on the ADS board with no hardware
* control, characters typed on the keyboard will be received by 
* SMC1 and echoed back out the RS232 port to the ASCII terminal.
* This function was designed and tested on an ADS850 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)MPC850 Users Manual
*
* HISTORY:
* 
* 15 Dec 2007   steven    initial release
*
*------------------------------------------------------------------------------*/


#include "vxWorks.h"
#include "ppc860Siu.h"
#include "ppc860Cpm.h"
#include "ppc860Sio.h"
#include "smc.h"


/*--------------------
 * Global definition *
 *-------------------*/
int RxIndex = 0;		/* the index of next receive BD */
UINT32 immBase;		/* the base of internal memory map */
LB *Smc1Buffer;		/* Rx and Tx Buffer*/
BDRINGS *RxTxBD;		/* Rx and Tx BD */


/*----------------------
* Routine Declaration *
*----------------------*/
void SMC1Init();
void InitBDs();
UBYTE Smc1Poll();
void EchoChar();
UBYTE Smc1GetChar();
void Smc1PutChar(UBYTE ch);


/*---------------
* get the immr *
*--------------*/
UINT32 GetIMMR()
{
	__asm__("mfspr 3, 638");
	__asm__("rlwinm 3, 3, 0, 0, 15");
}     

/* the beginning of the program */
int main()
{
	immBase = GetIMMR();

	/* set Rx and Tx BD to dpr */
	RxTxBD = (BDRINGS *)(immBase + 0x2000 + 64);
    
	/* set Rx and Tx Buffers to dpr */
	Smc1Buffer = (LB *)(immBase + 0x2000 + 64 + sizeof(BDRINGS) + 64);
    	
	SMC1Init();
    
	while (1) 
	{
		if (Smc1Poll())
			EchoChar();                
	}
	return 0;
}

/* initiate SMC1 to UART */
void SMC1Init()
{
	/* set SDMA's RAID */
	*MPC860_SDCR(immBase) = SDCR_RAID_BR5; /* set RISC arbitrator ID field to U-bus priority 5 */
    
	/* set PBPAR's SMRxD1 and SMTxD1 */
	*MPC860_PBPAR(immBase) |= 0xc0;			/* set pb24, 25 peripheral function */
	*MPC860_PBDIR(immBase) &= 0xf33f;  		/* peripheral function 0, 25 SMTXD1, 24 SMRXD1 */	

	/* set BRGC3's CD 48M / (16 * 38400) - 1 = 77 */
	/* *MPC860_BRGC3(immBase) &= 0xFFFFE001;    /* enable BRGC3 and set CD 1249(asynchronize) */
	/* *MPC860_BRGC3(immBase) |= (48000000/(38400 * 16)) << 1;
    
	/* set SIMODE's SMC1CS */
	*MPC860_SIMODE(immBase) = 0x00002000;      /* set to non multiple mode */
	*MPC860_SIMODE(immBase) &= 0xFFFF8FFF;
	/* *MPC860_SIMODE(immBase) |= MPC860_SIMODE_SMC1_BRG3;	  /* connect to brg3 */

	*SMC_RBASE(immBase + 0x3e80) = (UHWORD) RxTxBD->RxBD;    /* set SMC1 rBD */
	*SMC_TBASE(immBase + 0x3e80) = (UHWORD) &RxTxBD->TxBD;	  /* set SMC1 tBD */
    
	/* set SMC1 Parameter RAM's TFCR */  
	*SMC_RFCR(immBase + 0x3e80) = 0x10; /* ppc big endian mode */
	*SMC_TFCR(immBase + 0x3e80) = 0x10; /* ppc big endian mode */
	    
	/* set CPCR */
	*MPC860_CPCR(immBase) = 0x0091 ;  
	    
	/* set UART parameter BRKLN */
	*SMC_MRBLR(immBase + 0x3e80) = 1;
	*SMC_MAX_IDL(immBase + 0x3e80) = 0; /*set last received break length 0*/
	*SMC_BRKEC(immBase + 0x3e80) = 0;	/* */
	*SMC_BRKCR(immBase + 0x3e80) = 1;	/* */
    
	InitBDs();

	/* initial event register SMCE1 */
	*MPC860_SMCE1(immBase) = 0xff;
    
	/* initial mask register SMCM1 */
	*MPC860_SMCM1(immBase) =  0x17;

	/* configure CP interrup register */
	*MPC860_CICR(immBase) = 0;

	/* clear all pending interrupt events*/
	*MPC860_CIPR(immBase) = 0xffffffff;
    
	/* initial interrupt register CIMR */
	*MPC860_CIMR(immBase) |= 0x10;

	/*------------------------------------*/
	/* 8-bit mode,  no parity, 1 stop-bit */
	/* UART SMC Mode							  */
	/* Normal operation (no loopback),	  */
	/* SMC Transmitter/Receiver Enabled	  */
	/*------------------------------------*/
	*MPC860_SMCMR1(immBase) = 0x4820;
	*MPC860_SMCMR1(immBase) = 0x4823;
}    

/* initiate Rx and Tx BD */
void InitBDs() 
{
	int i;
    
	for(i = 0; i < SIZE; i++)
	{
		/* set RxBD to empty */
		RxTxBD->RxBD[i].status = 0x8000;
		RxTxBD->RxBD[i].length = 1;
		RxTxBD->RxBD[i].addr =(UBYTE *) &(Smc1Buffer->RxBuffer[i]);
	}
    
	/* set wrap bit */
	RxTxBD->RxBD[SIZE - 1].status = 0xa000;

	/* set wrap bit */
	RxTxBD->TxBD.status = 0x2000;
	RxTxBD->TxBD.length = 1;
	RxTxBD->TxBD.addr =(UBYTE *) &(Smc1Buffer->TxBuffer);
}

/* poll the receive buffer */
UBYTE Smc1Poll() 
{
	if (RxTxBD->RxBD[RxIndex].status & 0x8000)
		return 0;
	else 
		return 1;
}


/* receive and transmit char */
void EchoChar() 
{
	UBYTE data;
	data = Smc1GetChar();
	Smc1PutChar(data);
}


/* receive char continuously */
UBYTE Smc1GetChar()
{
	UBYTE ch;
           
	while(RxTxBD->RxBD[RxIndex].status & 0x8000)
	{
	}
	ch = *(RxTxBD->RxBD[RxIndex].addr);
                      
	RxTxBD->RxBD[RxIndex].status |= 0x8000;
      
	RxIndex = (RxIndex + 1) % SIZE;
      
	return ch; 
}

/* transmit char */
void Smc1PutChar(UBYTE ch)
{
	while(RxTxBD->TxBD.status & 0x8000)
	{
	}

	*(RxTxBD->TxBD.addr) = ch;
	RxTxBD->TxBD.length = 1;

	RxTxBD->TxBD.status |= 0x8000;
}

⌨️ 快捷键说明

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