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

📄 uart.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
//Description :  The description of Function Pointer sholud be under 15 characters


#include "system.h"
#include "Uart.h"



#define UART0_REG ( UART_REGS *)UART_REG_BASE  // Uart 0 register base address
#define UART1_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET)
#define UART2_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*2) 
#define UART3_REG ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*3) 
#define UART_BUF (_NONCACHE_STARTADDRESS + 0x10000)
#define FIFO_DEBUG_BUF (_NONCACHE_STARTADDRESS + 0x11000)

#define TX_FIFO_RESET	(1<<2)
#define RX_FIFO_RESET	(1<<1)
#define TX_INT_TYPE(Bit)		((Bit)<<9) // 0:pulse 1:level
#define RX_INT_TYPE(Bit)		((Bit)<<8) // 0:pulse 1:level


#define RX_TIMEOUT_EN	(0<<7) // 0:disable 1:enable, disable for FIFO test
#define RX_ERR_INT_EN	(1<<6) // 0:disable 1:enable
#define RTS_ACTIVE		(1) // In normal mode, nRTS signal  0:low, 1:High

//2460 -> 2443 porting
#define BIT_UART_ERROR		(1<<2)
#define BIT_UART_TXD		(1<<1)
#define BIT_UART_RXD		(1)
#define BIT_UART			(1<<SRCPNDOFFSET)
#define SENDBREAK			0x99
//--------------------------------------------------------------

#define INT_MODE	0
#define DMA_MODE 	1

#define DMA_BUF_LEN 8  // for rx
#define TX_END_CHAR	NULL
#define RX_END_CHAR	'\r'




//Debugging Only
#define		STOPHERE		while(1)
#define		Msg(message)	if(1)printf(message)
#define		SetBitFReg(rReg, uLenOfBit, uVal, uShiftWidth)		rReg = ((rReg  & ~((0xFFFFFFFF >>(32-uLenOfBit) ) << uShiftWidth)) | (uVal <<uShiftWidth))	

#define		PrintBits(strB, a)		printf("\n[%s : 0x%x]\n31    27    23    19    15    11    07    03   ", strB, (a));\
							                  printf("\n|     |     |     |     |     |     |     |      ");\
										printf("\n%s%s%s%s%s%s%s%s",\
										BitTable[((a) & 0xF0000000)>>28], BitTable[((a) & 0xF000000)>>24],BitTable[((a) & 0xF00000)>>20],\
										BitTable[((a) & 0xF0000)>>16],BitTable[((a) & 0xF000)>>12],BitTable[((a) & 0xF00)>>8],\
										BitTable[((a) & 0xF0)>>4],	BitTable[((a) & 0xF)])

char BitTable[16][10] = {   
						"0000  ",
						"0001  ",
						"0010  ",
						"0011  ",
						"0100  ",
						"0101  ",
						"0110  ",
						"0111  ",
						"1000  ",
						"1001  ",
						"1010  ",
						"1011  ",
						"1100  ",
						"1101  ",
						"1110  ",
						"1111  "
					   };
//-->Debugging Only					   
					   
					   
#define		TRUE		1
#define		FALSE		0
#define		BOOL		unsigned int
BOOL		g_bIsLevelInt = TRUE; //TRUE : Level Type , FALSE : Pulse Type





typedef struct tag_UART_CON
{
	unsigned int iBaudrate;
	unsigned char fSelUartIrda; // Uart mode
	unsigned char fLoopTest;  // UCON[5]  (0 : normal, 1 : LoopBack)
	unsigned char fAfc;
	unsigned char fEnableFifo;
	unsigned char cOpClock; 	// 0,2:PCLK, 1:UEXTCLK, 2:EPLL
	unsigned char cDataBit; 	// 0:5bit, 1:6bit, 2:7bit, 3:8bit
	unsigned char cParityBit; 	// 0:no parity, 1:odd, 2:even, 3:forced 1, 4:forced 0
	unsigned char cStopBit; 	// 0:one stopbit, 1:two stopbit
	unsigned char cTxMode; 	// 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
	unsigned char cTxTrig; 	// 0:empty, 1:16, 2:32, 3:48 (byte)
	unsigned char cRxMode; 	// 0:disable, 1:interrupt or polling, 2:DMA0, 3:DMA1
	unsigned char cRxTrig; 	// 0:1, 1:8, 2:16, 3:32 (byte)
	unsigned char cRtsTrig; 	// 0:63, 1:56, 2:48, ... , 7:8 (byte)
	unsigned char cSendBreakSignal;  // ULCON[4]  (0 : normal, 1 : Send Break Signal)
} UART_CON;


void SetUartPort(void);
void ReturnUartPort(void);
void CalcBaudrate( UART_REGS *, UART_CON *);
int InitializeUart( UART_REGS *, UART_CON *);  // initialize with current setting
void UartSubIsr(unsigned char );
void __irq UartIsr0(void);
void __irq UartIsr1(void);
void __irq UartIsr2(void);
void __irq UartIsr3(void);

void __irq DmaIsr(void);

unsigned char SetBaudrate(unsigned char ch, unsigned int Baudrate);
unsigned char SetOpClock(unsigned char ch, unsigned int OpClock);
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char StopBit, unsigned char ParityBit);
unsigned char SetDbgUart(unsigned char ch);  // set registers with debug setting
unsigned char UartOpen(unsigned char ch, unsigned int SetIRQ);
unsigned char UartClose(unsigned char ch);


void TestUart(void);
void UartTx(void);
void UartRx(void);


static unsigned int	save_rGPHCON;//, save_rGPHPU, save_rSPCON;  // for setting Uart Port 
static UART_CON	UartCon[5] = {{115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1,0}}; 
									// control property per each channel. 4th data is defualt value for initialize

const unsigned int nSlotTable[16] = {0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa,
				     		0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf};
				     		
U32 SRCPNDOFFSET;		
U32 SUBINTOFFSET;

volatile unsigned int UextClk = 12000000;
volatile unsigned int EpllClk = 12000000;
static volatile unsigned char isTxDone[4] = {0, 0, 0, 0};
static volatile unsigned char isRxDone[4] = {0, 0, 0, 0};
char *pUartTxStr[4], *pUartRxStr[4];

// buffer for test
char TestString[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART Tx interrupt test is good!!!!\r";
//char TestString[]="UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU!!!!\r"; //Test string for Toggling Value on the oscilloscope

volatile unsigned int *pFifoDebug  = (unsigned int *)FIFO_DEBUG_BUF; //temporary for fifo count test
volatile unsigned int fcnt = 0;


void * func_uart_test[][2]=
{	
	(void *)TestUart, 		"UART Test	",	
	0,0
};

void Test_UART(void)
{
	int i;
	
	printf("\n======  UART Test program start ======\n");
		
	while(1)
	{
		i=0;
		printf("\n\n");
		while(1)
		{   //display menu
			printf("%2d:%s",i,func_uart_test[i][1]);
			i++;
			if((int)(func_uart_test[i][0])==0)
			{
				printf("\n");
				break;
			}
			if((i%4)==0)
			printf("\n");
		}

		printf("\nPress Enter key to exit : ");

		i = GetIntNum();
		if(i==-1) break;		// return.
		if(i>=0 && (i<((sizeof(func_uart_test)-1)/8)) )	// select and execute...
			( (void (*)(void)) (func_uart_test[i][0]) )();
	}	
	printf("\n====== UART Test program end ======\n");
}

///////////////////////// Test functions ////////////////////////

unsigned char UartConfig(void)
{
	unsigned char ch;
	int iNum = 0;
//	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;
	
	

	// Select Channel
	printf("Note : [D] mark means default value. If you press ENTER key, default value is selected.\n");
	printf("Select Channel(0~3) [D=0] : ");

	ch = (unsigned char)GetIntNum();
	if ( ch>3 )	ch = 0; // default uart 0
		
	pUartCon = &UartCon[ch];	

	printf("\n\nConnect PC[COM1 or COM2] and UART%d of SMDK2443 with a serial cable for test!!! \n", ch);
	
	
	//Set Other Options
	printf("\nSelect Other Options\n 0. Nothing[D]  1.Send Break Signal  2. Loop Back Mode  \n Choose : ");
	switch(GetIntNum())
	{		
		default : 	{
						pUartCon->cSendBreakSignal = 0;
						pUartCon->fLoopTest = 0;
						break;
					}
		case 1 :		pUartCon->cSendBreakSignal = 1;	return ch;
		case 2 : 	pUartCon->fLoopTest = 1;		break;		
	}		
	
	
	//Set Parity mode
	printf("\nSelect Parity Mode\n 1. No parity[D] 2. Odd 3. Even 4. Forced as '1' 5. Forced as '0' \n Choose : ");
	switch(GetIntNum())
	{		
		default : 	pUartCon->cParityBit = 0;		break;
		case 2 : 	pUartCon->cParityBit = 4;		break;
		case 3 :		pUartCon->cParityBit = 5;		break;
		case 4 :		pUartCon->cParityBit = 6;		break;
		case 5 :		pUartCon->cParityBit = 7;		break;
	}
	//Set the number of stop bit	
	printf("\n\nSelect Number of Stop Bit\n 1. One stop bit per frame[D] 2. Two stop bit per frame");
	switch(GetIntNum())
	{
		default : 	pUartCon->cStopBit = 0;		break;
		case 2 : 	pUartCon->cStopBit = 1;		break;		
	}
	//Set Word Length	
	printf("\n\nSelect Word Length\n 1. 5bits 2. 6bits 3. 7bits 4. 8bits \n Choose : ");
	switch(GetIntNum())
	{		
		case 1 :		pUartCon->cDataBit = 0;		break;
		case 2 :		pUartCon->cDataBit = 1;		break;
		case 3 :		pUartCon->cDataBit = 2;		break;	
		default :		pUartCon->cDataBit = 3;		break;
	}
	
	
	// Set Operation clock
	printf("\n\nSelect Operating Clock\n 1. PCLK[D]	2. UEXTCLK	3. EPLL \n Choose : ");
	switch (GetIntNum())
	{
	case 2 :
		pUartCon->cOpClock = 1;
		// connect CLKOUT and UEXTCLK
		rGPHCON = rGPHCON & ~(3<<24) | (1<<25);// Uextclk using			
		UextClk = PCLK; 		
		break;

	case 3 :
		pUartCon->cOpClock = 3;
		SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
		 // use EPLL output clock
		rCLKSRC = rCLKSRC & ~(1<<6)|(1<<6); // epll output select
		EpllClk = 50000000; 		
		break;

	default :
		pUartCon->cOpClock = 0; // PCLK		
		break;
	}

	// Select UART or IrDA 1.0
	printf("\n\nSelect External Interface Type\n 1. UART[D]   2. IrDA mode\n Choose : ");
	if (GetIntNum() == 2)		pUartCon->fSelUartIrda = 1; // IrDA mode
	else					pUartCon->fSelUartIrda = 0; // IrDA mode

	// Set Baudrate
	printf("\n\nType the baudrate and then change the same baudrate of host, too.\n");
	printf(" Baudrate (ex 9600, 115200[D], 921600) : ");
	pUartCon->iBaudrate = GetIntNum();
	if ((int)pUartCon->iBaudrate == -1) pUartCon->iBaudrate = 115200;

	// Select UART operating mode
	printf("\n\nSelect Operating Mode\n 1. Interrupt[D]	2. DMA\n Choose : ");
	if (GetIntNum() == 2)
	{
		pUartCon->cTxMode = 2; // DMA0 mode
		pUartCon->cRxMode = 3; // DMA1 mode
	}
	else
	{	
		pUartCon->cTxMode = 1; // Int mode
		pUartCon->cRxMode = 1; // Int mode
	}

	// Select UART FIFO mode
	printf("\n\nSelect FIFO Mode (Tx/Rx[byte])\n 1. no FIFO[D]  2. Empty/1  3. 16/8   4. 32/16  5. 48/32 \n Choose : ");
	iNum = GetIntNum();
	if ( (iNum>1)&&(iNum<6) )
	{
		pUartCon->fEnableFifo = 1;
		pUartCon->cTxTrig = iNum -2;
		pUartCon->cRxTrig = iNum -2;
	}
	else 
	{
		pUartCon->fEnableFifo = 0;
	}

	// Select AFC mode enable/disable
	printf("\n\nSelect AFC Mode\n 1. Disable[D]	2. Enable\n Choose : ");
	if (GetIntNum() == 2)
	{
		pUartCon->fAfc = 1; // AFC mode enable
		printf("Select nRTS trigger level(byte)\n 1. 63[D]   2. 56   3. 48   4. 40   5. 32   6. 24   7. 16   8. 8\n Choose : ");
		iNum = GetIntNum();
		if ( (iNum>1)&&(iNum<9) )	pUartCon->cRtsTrig = iNum -1;
		else						pUartCon->cRtsTrig = 0; // default 63 byte
	}
	else
	{
		pUartCon->fAfc = 0; // AFC mode disable
	}
	return ch;
}


void TxString(unsigned char ch, char *str)  // The last character of 'str' should be NULL
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;
	int iTemp;

	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
	pUartCon = &UartCon[ch];	

	isTxDone[ch] = 0;
	pUartTxStr[ch] = str;

	pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
	fcnt = 0;

	
	if(ch == 1){	SUBINTOFFSET = 3;	SRCPNDOFFSET = 23;}
	else if(ch == 2){	SUBINTOFFSET = 6;		SRCPNDOFFSET = 15;}
	else if(ch == 3){	SUBINTOFFSET = 24;	SRCPNDOFFSET = 18;}
	else {	SUBINTOFFSET = 0;	SRCPNDOFFSET = 28;}// CH 0 default		
	
		
	iTemp = pUartCon->cTxMode & 3;	
	
	if ( iTemp == 1 ) // interrupt mode
	{		
		rINTMSK &= ~(BIT_UART);		
		rINTSUBMSK &= ~(BIT_UART_TXD << SUBINTOFFSET);					
	}
	else if ( (iTemp==2) || (iTemp==3) ) // dma mode
	{
		rDISRC0 = (unsigned int)str;	// Start address
		rDISRCC0 = (0<<1)|(0);		// AHB,Increment
		rDIDST0 = (unsigned int)(&pUartRegs->rUtxh); 	// Memory buffer Address
		rDIDSTC0 = (1<<1)|(1);		// APB,Fixed
		rDCON0 = (1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|strlen(str);
		//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value
		rDMAREQSEL0 = ((19+ch*2)<<1)|1;

		// Clear Int Pending and Unmask    
		rSUBSRCPND = BIT_SUB_DMA0;
		ClearPending(BIT_DMA);
		rINTMSK &= ~(BIT_DMA);
		rINTSUBMSK &= ~(BIT_SUB_DMA0);
		rDMASKTRIG0 = (0<<2)|(1<<1)|(0);    //no-stop, DMA0 channel on, no-SW trigger 
	}	
	
	
	
	while(!isTxDone[ch]);
	
	
	rINTMSK |= (BIT_UART);
	//rINTMSK |= (BIT_DMA);
	rINTSUBMSK |= (BIT_UART_TXD<<SUBINTOFFSET);			
	
}




char* RxString(unsigned char ch)  // The last character of input string should be '\r'. simple test code
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;	
	int iTemp;

	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
	pUartCon = &UartCon[ch];	

	isRxDone[ch] = 0;
	pUartRxStr[ch] = ( char *)(UART_BUF+DMA_BUF_LEN);

	pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
	fcnt = 0;
	
	if(ch == 1){	SUBINTOFFSET = 3;	SRCPNDOFFSET = 23;}
	else if(ch == 2){	SUBINTOFFSET = 6;		SRCPNDOFFSET = 15;}
	else if(ch == 3){	SUBINTOFFSET = 24;		SRCPNDOFFSET = 18;}
	else {	SUBINTOFFSET = 0;	SRCPNDOFFSET = 28;	}	// CH 0 default	
	
	
		
	iTemp = pUartCon->cRxMode & 3;
	if ( iTemp == 1 ) // interrupt mode
	{			
		rINTMSK &= ~(BIT_UART);
		rINTSUBMSK &= ~ ((BIT_UART_ERROR << SUBINTOFFSET)|(BIT_UART_RXD << SUBINTOFFSET));	
		
	}
	else if ( (iTemp == 2) || (iTemp == 3) ) // dma mode
	{
		printf("\nIn DMA rxstring mode");	
		rDISRC1=(unsigned int)(&pUartRegs->rUrxh);	// Start address
		rDISRCC1=(1<<1)|(1);		// APB,Fixed
		rDIDST1=(unsigned int)(UART_BUF);	        // Memory buffer Address
		rDIDSTC1= (0<<1)|(0);		// AHB,Increment
		rDCON1=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<22)|(0<<20)|(DMA_BUF_LEN);				
		//handshake, sync PCLK, TC int, single tx, single service,auto-reload off, Byte size Tx, Tx count value
		rDMAREQSEL1 = ((20+ch*2)<<1)|1;

⌨️ 快捷键说明

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