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

📄 uart.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**
* Project Name : S3C2460 verification project
*
* Copyright 2004 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is only for verifying functions of the S3C2460. 
* Anybody can use this code without our permission.
*/

/**
* File Name    : uart.c
* Description  : S3C2460 UART module code
* Author       : Junon Jeon
* Dept         : Mobile solution, AP
* Created Date : 2004.06.17
* Version      : 0.0
* History
*   R0.0 (2004.06.17): Junon draft
*/

#include <stdio.h>
#include "def.h"
#include "option.h"
#include "2460addr.h"
#include "2460lib.h"
#include "Uart.h"
#include "PLL.h"


#define UART_REG_BASE 	0x44400000
#define UART_REG_OFFSET 	0x4000
#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 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		(1<<9) // 0:pulse 1:level
#define RX_INT_TYPE		(1<<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

#define BIT_UART_MODEM		(1<<3)
#define BIT_UART_TXD		(1<<2)
#define BIT_UART_ERROR		(1<<1)
#define BIT_UART_RXD		(1)

#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'

typedef struct tag_UART_REGS
{
	unsigned int rUlCon;
	unsigned int rUCon;
	unsigned int rUfCon;
	unsigned int rUmCon;
	unsigned int rUtrStat;
	unsigned int rUerStat;
	unsigned int rUfStat;
	unsigned int rUmStat;
	unsigned int rUtxh;
	unsigned int rUrxh;
	unsigned int rUbrDiv;
	unsigned int rUdivSlot;
	unsigned int rUintP;
	unsigned int rUintSp;
	unsigned int rUintM;
} UART_REGS;

typedef struct tag_UART_CON
{
	unsigned int iBaudrate;
	unsigned char fSelUartIrda; // Uart mode
	unsigned char fLoopTest;
	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)
} UART_CON;


void SetUartPort(void);
void ReturnUartPort(void);
void CalcBaudrate( UART_REGS *, UART_CON *);
void InitializeUart( UART_REGS *, UART_CON *);  // initialize with current setting
void UartSubIsr(unsigned char );
void __irq UartIsr(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 char UartClose(unsigned char ch);
//void SelectChannel(unsigned char ch);
//void InputUartProperty(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[4] = {{115200,0,0,0,0,0,3,0,0,1,1,1,1,1}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1}
									, {115200,0,0,0,0,0,3,0,0,1,1,1,1,1}}; 
									// 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};

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

// buffer for test
char TestString[]="\nABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890->UART Tx interrupt test is good!!!!\r";

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

/** 
* Function Name : 
* 
* Function Description : 
*
* Input :
* Output :
* Version :
*/

void * func_uart_test[][2]=
{	
//									    "0123456789012345" max 15磊 肺茄沥窍咯 comment窍技夸.
//UART
	(void *)TestUart, 		"UART common test	",
	(void *)UartTx, 		"UART Tx string	",
	(void *)UartRx, 		"UART Rx string	",
	0,0
};

void Uart_Test(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");
}


void SetUartPort(void)
{
	//Push UART GPIO port configuration
	save_rGPHCON = rGPHCON; 
	save_rGPHPU = rGPHPU;
	save_rSPCON = rSPCON;
	//Configure UART port
	rGPHCON = 0x2AAAAA;	// enable all uart channel [22:0]
	rGPHPU = 0x7ff;	//Uart port pull-up disable [11:0]
	rSPCON &= ~(1<<2);
}       

void ReturnUartPort(void)
{       
	//Pop UART GPIO port configuration
	rGPHCON = save_rGPHCON;
	rGPHPU = save_rGPHPU;
	rSPCON = save_rSPCON;
}

void CalcBaudrate( UART_REGS *pUartRegs, UART_CON *pUartCon)
{
	float tempDiv;
	unsigned int nOpClock;
	unsigned int nSlot;
	
	switch(pUartCon->cOpClock)
	{
		case 1 : // Uextclk
			nOpClock = UextClk;
			break;
		case 3 : // Epll
			nOpClock = EpllClk;
			break;
		case 0 :
		case 2 : // Pclk
		default : 
			nOpClock = PCLK;
			break;
	}

	tempDiv = (nOpClock/(16.*pUartCon->iBaudrate)) - 1;
	nSlot = (int)((tempDiv - (int)tempDiv) * 16);
	pUartRegs->rUbrDiv = (int)(tempDiv);
	pUartRegs->rUdivSlot = nSlotTable[nSlot];
//	printf(" div = %d, slot = 0x%x\n", (int)(tempDiv), nSlotTable[nSlot]);
}

void InitializeUart( UART_REGS *pUartRegs, UART_CON *pUartCon) // Initialize register set with current control set
{
	CalcBaudrate(pUartRegs, pUartCon);
	pUartRegs->rUlCon = (pUartCon->fSelUartIrda<<6)|(pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)
						|(pUartCon->cDataBit);
	pUartRegs->rUCon = (pUartCon->cOpClock<<10)|TX_INT_TYPE|RX_INT_TYPE|RX_ERR_INT_EN|RX_TIMEOUT_EN
						|(pUartCon->fLoopTest<<5)|(pUartCon->cTxMode<<2)|(pUartCon->cRxMode);
	pUartRegs->rUfCon = (pUartCon->cTxTrig<<6)|(pUartCon->cRxTrig<<4)|TX_FIFO_RESET|RX_FIFO_RESET
						|(pUartCon->fEnableFifo);
	pUartRegs->rUmCon = (pUartCon->cRtsTrig<<5)|(pUartCon->fAfc<<4)|RTS_ACTIVE;
	pUartRegs->rUintM = 0xf; // mask
	pUartRegs->rUintSp = 0xf; // source pending clear
	pUartRegs->rUintP = 0xf; // pending clear

	// deglitch bug s/w work around for using EPLL output clock source
	{
		char sel;
		
		printf("\nSelect whether s/w work-around is adopted or not(y/n)\n");
		sel=getchar();
		
		if(sel=='y')
		{
			rGPHCON &= ~(3<<16);  
			Delay(2);
			rGPHCON |= (2<<16); 
			printf("\ns/w work-around is adopted..\n");		
		}
		else
			printf("\ns/w work-around is not adopted..\n");	
	}
}


void __irq UartIsr(void)
{
	rINTMSK |= BIT_UART;
	
	if (rSUBSRCPND&BIT_SUB_UART0)
	{		
		UartSubIsr(0);
	}
	if (rSUBSRCPND&BIT_SUB_UART1)
	{
		UartSubIsr(1);
	}
	if (rSUBSRCPND&BIT_SUB_UART2)
	{
		UartSubIsr(2);
	}

	rINTMSK &= ~(BIT_UART);
}		


void UartSubIsr(unsigned char ch)
{
	unsigned int tempStat = 0;
	unsigned int chBit;
	unsigned char tempChar;
	UART_REGS *pUartRegs;
	
	chBit = (unsigned int)(1<<ch);
	rINTSUBMSK |= chBit; 

	pUartRegs = ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);

	// Check Errors 	
	if (pUartRegs->rUintP & BIT_UART_ERROR)
	{
		pUartRegs->rUintM |= BIT_UART_ERROR;
		pUartRegs->rUintSp = BIT_UART_ERROR;
		pUartRegs->rUintP = BIT_UART_ERROR;
		tempStat = pUartRegs->rUerStat;
		switch(tempStat)//to clear and check the status of register bits
		{
			case 1:
				printf("Overrun error!\n");
				break;
			case 2:
				printf("Parity error!\n");
				break;
			case 4:
				printf("Frame error!\n");
				break;
			case 6:
				printf("Parity, Frame error!\n");
				break;
			case 8:
				printf("Breake detect\n");
				break;
			case 0xa:
				printf("Parity error & Break detect!\n");
				break;
			case 0xc:
				printf("Frame error & Breake detect\n");
				break;
			case 0xe:
				printf("Parity, Frame error & Break detect!\n");
				break;
			default :
				printf("Unknown error : 0x%x\n", tempStat);
				break;
		}
		isRxDone[ch] = 1;
		pUartRegs->rUintM &= ~(BIT_UART_ERROR);
	}

	// Tx ISR	
	if (pUartRegs->rUintP & BIT_UART_TXD)
	{
		pUartRegs->rUintM |= BIT_UART_TXD;
		pUartRegs->rUintSp = BIT_UART_TXD;
		pUartRegs->rUintP = BIT_UART_TXD;

		if (pUartRegs->rUfCon & 1) // 1 : fifo enable 
		{
			// for debugging fifo 
			*pFifoDebug++ = ++fcnt;
			*pFifoDebug++ = (pUartRegs->rUfCon>>6)&3;
			*pFifoDebug++ = (pUartRegs->rUfStat>>8)&0x3f;
			*pFifoDebug = 0;
			
			while (!(pUartRegs->rUfStat & (1<<14)) && (*pUartTxStr[ch] != TX_END_CHAR)) 	//until tx fifo full or end of string
				pUartRegs->rUtxh = *pUartTxStr[ch]++;

			if(*pUartTxStr[ch] == TX_END_CHAR) 
			{
				*(pUartTxStr[ch]+1) = NULL;
				isTxDone[ch] = 1;	
				pUartRegs->rUintM |= (BIT_UART_TXD);
				rSUBSRCPND = chBit;
				ClearPending(BIT_UART);		
				return;
			}
			else 
			{
				pUartRegs->rUintM &= ~(BIT_UART_TXD);
			}
		}
		else // 0 : fifo disable
		{
			if (*pUartTxStr[ch] != TX_END_CHAR)
			{
				pUartRegs->rUtxh = *pUartTxStr[ch]++;
				pUartRegs->rUintM &= ~(BIT_UART_TXD);
			}
			else
			{
				*(pUartTxStr[ch]+1) = NULL;
				isTxDone[ch] = 1;	
				rSUBSRCPND = chBit;
				ClearPending(BIT_UART);		
				return;
			}
		}
	}

	// Rx ISR	
	if (pUartRegs->rUintP & BIT_UART_RXD)
	{
		pUartRegs->rUintM |= BIT_UART_RXD;
		pUartRegs->rUintSp = BIT_UART_RXD;
		pUartRegs->rUintP = BIT_UART_RXD;
		if (pUartRegs->rUfCon & 1) // 1 : fifo enable 
		{
			// for debugging fifo 
			*pFifoDebug++ = ++fcnt;
			*pFifoDebug++ = (pUartRegs->rUfCon>>4)&3;
			*pFifoDebug++ = (pUartRegs->rUfStat)&0x3f;
			*pFifoDebug = 0;

//			while (!(pUartRegs->rUfStat & (1<<6))); // until rx full for AFC rts trigger test
			while (pUartRegs->rUfStat & 0x3f) 	//until rx fifo count 0
			{
				*pUartRxStr[ch] = (unsigned char)(pUartRegs->rUrxh);
				printf("%c", *pUartRxStr[ch]++);
			}	

			if(*(pUartRxStr[ch]-1) == RX_END_CHAR) 
			{
				*pUartRxStr[ch] = NULL;
				isRxDone[ch] = 1;	
				pUartRegs->rUintM |= (BIT_UART_RXD);
				rSUBSRCPND = chBit;
				ClearPending(BIT_UART);		
				return;
			}
			else 
			{
				pUartRegs->rUintM &= ~(BIT_UART_RXD);
			}
		}
		else // 0 : fifo disable
		{
			tempChar = (unsigned char)(pUartRegs->rUrxh);
			if (tempChar != RX_END_CHAR)
			{

⌨️ 快捷键说明

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