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

📄 uart.c

📁 三星2443芯片
💻 C
📖 第 1 页 / 共 2 页
字号:

		// Clear Int Pending and Unmask    		
		rINTMSK &= ~(BIT_DMA);
		rINTSUBMSK &= ~(BIT_SUB_DMA1);		
		rDMASKTRIG1 = (0<<2)|(1<<1)|(0);    //no-stop, DMA1 channel on, no-SW trigger 		
	}	
	while(!isRxDone[ch]);

	pUartRxStr[ch] = ( char *)(UART_BUF+DMA_BUF_LEN);
	return pUartRxStr[ch];
}

	

void TestUart(void)
{
	unsigned char ch;
	ch = UartConfig();	
	if( UartOpen(ch,1) == SENDBREAK ) 
	{
		printf("\n\nSend Break Signal has been transfered");
		return; 	
	} 	
	// UART Tx test with interrupt	
	printf("\n[Uart channel %d Tx Test]\n",ch);	
	TxString(ch, TestString);	
	printf("\nTx Done~ \n");	
		

	// UART Rx test with interrupt 
	printf("\n[Uart channel %d Rx Test]\n",ch);
	printf("Case 1 : Interrupt mode. After typing characters and pressing ENTER key.\n");
	printf("Case 2 : Interrupt FIFO mode & DMA mode. After typing characters and pressing ENTER key until FIFO level trigger.\n");	
	printf(" Then, you will see those characters.\n");
	printf("\nRx : %s \n",RxString(ch));
	printf("\nRx Done~ \n");

	// Test End
	printf("\nComplete UART test!!! \n");
	UartClose(ch);
	SetDbgUart(1); // change channel setting for debug port set
}


void UartTx(void)
{
	unsigned char ch;
	char str[128];

	ch = UartConfig();
	UartOpen(ch,1); 

	printf("\n[Uart%1d Tx String]\n",ch);
	printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n");
	while (getchar() != 0x1b)
	{
		gets(str);
//		printf("Tx : ");
		TxString(ch, str);
		printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n");
	}	

	UartClose(ch);
	SetDbgUart(0); // change channel setting for debug port set
}


void UartRx(void)
{
	unsigned char ch;

	ch = UartConfig();
	UartOpen(ch,1); 

	printf("\n[Uart%1d Rx String]\n",ch);
	printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n");
	while (getchar() != 0x1b)
	{
		printf("Rx : %s ", RxString(ch));		
		printf("\nIf you want to exit, press 'ESC' key at first. The character instead of 'ESC' is ignored.\n");
	}	

	UartClose(ch);
	SetDbgUart(0); // change channel setting for debug port set
}




void SetUartPort(void)
{	//Push UART GPIO port configuration
	save_rGPHCON = rGPHCON; 

	//Configure UART port
	rGPHCON	&= ~((0xf<<20)|(0xf<<16)|(0xf<<12)|(0xf<<8)|(0xf<<4)|(0xf<<0));
	rGPHCON	|=  ((0xa<<20)|(0xa<<16)|(0xa<<12)|(0xa<<8)|(0xa<<4)|(0xa<<0));
 
}       

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

void CalcBaudrate( UART_REGS *pUartRegs, UART_CON *pUartCon)
{
	float tempDiv;
	unsigned int nOpClock;
	unsigned int nSlot;
	
	switch(pUartCon->cOpClock)
	{
		case 1 : 			nOpClock = UextClk;			break;// Uextclk
		case 3 : 			nOpClock = EpllClk;			break;// Epll
		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];	
}

int InitializeUart( UART_REGS *pUartRegs, UART_CON *pUartCon) // Initialize register set with current control set
{
	#if 1
	rGPHCON = ((rGPHCON  & ~(0x03 << 26)) | (0x02 << 26));	
	rMISCCR = ((rMISCCR  & ~(0x07 << 4)) | (0x04 << 4));	
	#endif 
	
	CalcBaudrate(pUartRegs, pUartCon);
	
	pUartRegs->rUlCon = (pUartCon->fSelUartIrda<<6)|(pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)
						|(pUartCon->cDataBit);
	pUartRegs->rUCon = (pUartCon->cOpClock<<10)|TX_INT_TYPE(g_bIsLevelInt)|RX_INT_TYPE(g_bIsLevelInt)|RX_ERR_INT_EN|RX_TIMEOUT_EN
						|(pUartCon->fLoopTest<<5)| (pUartCon->cSendBreakSignal<<4) |(pUartCon->cTxMode<<2)|(pUartCon->cRxMode);		
	if(pUartCon->cSendBreakSignal)
		return SENDBREAK;
	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;	
	return 0;
	
}

//ARM disables IFQ in CPSR  When it enters ISR, There is no need to masking SUBMASK or MASK registers
void __irq UartIsr0(void)
{		
	UartSubIsr(0);	
}		

void __irq UartIsr1(void)
{	
	UartSubIsr(1);
}

void __irq UartIsr2(void)
{	
	UartSubIsr(2);
}

void __irq UartIsr3(void)
{	
	UartSubIsr(3);
}	



void UartSubIsr(unsigned char ch)
{
	unsigned int ErrorStatus = 0;	
	char ReadChar;
	unsigned int uSubSrcPnd;
	volatile UART_REGS *pUartRegs;			
	
	uSubSrcPnd = rSUBSRCPND;	
	pUartRegs = ( UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);
	
	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;	}// default : CH 0		
	
	if(!g_bIsLevelInt)		rSUBSRCPND = (BIT_UART_ERROR<<SUBINTOFFSET)|(BIT_UART_TXD<<SUBINTOFFSET)|(BIT_UART_RXD<<SUBINTOFFSET);		
	// Check Errors 	
	if (uSubSrcPnd & (BIT_UART_ERROR<< SUBINTOFFSET))
	{	
		ErrorStatus = pUartRegs->rUerStat;
		switch(ErrorStatus)//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", ErrorStatus); break;
		}
		isRxDone[ch] = 1;	
		rINTSUBMSK |= (BIT_UART_RXD<<SUBINTOFFSET);				
	}
	// Tx ISR		
	if (uSubSrcPnd & (BIT_UART_TXD<<SUBINTOFFSET))
	{	
		if (pUartRegs->rUfCon & 1) // 1 : fifo enable 
		{		
			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])) // if there is no character in the pUartTxStr[ch], Tx is done
			{		rINTSUBMSK |= (BIT_UART_TXD<<SUBINTOFFSET);			isTxDone[ch] = 1;		}
		}
		else // 0 : fifo disable
		{	
			if (*pUartTxStr[ch])		pUartRegs->rUtxh = *pUartTxStr[ch]++;	// if there is no character in the pUartTxStr[ch], Tx is done	
			else
			{	rINTSUBMSK |= (BIT_UART_TXD<<SUBINTOFFSET);			isTxDone[ch] = 1;			}
		}				
	}
	// Rx ISR		
	if (uSubSrcPnd & (BIT_UART_RXD<<SUBINTOFFSET))
	{	
		if (pUartRegs->rUfCon & 1) // 1 : fifo enable 
		{	
			while (pUartRegs->rUfStat & 0x3f) 	//until rx fifo count 0			
				*pUartRxStr[ch]++ = (unsigned char)(pUartRegs->rUrxh);	
				
			if(*(pUartRxStr[ch]-1) == RX_END_CHAR) 
			{			
				*pUartRxStr[ch] = NULL;				isRxDone[ch] = 1;
				rINTSUBMSK |= (BIT_UART_RXD<<SUBINTOFFSET);							
			}			       
		}
		else // 0 : fifo disable
		{				
			ReadChar = (unsigned char)(pUartRegs->rUrxh);
			if (ReadChar != RX_END_CHAR)		*pUartRxStr[ch]++ = ReadChar;
			else 
			{
				*pUartRxStr[ch] = NULL;			    	printf("\n");				
				isRxDone[ch] = 1;		
				rINTSUBMSK |= (BIT_UART_RXD<<SUBINTOFFSET);							
			}					
		}		
	}		
	if(g_bIsLevelInt)		rSUBSRCPND = (BIT_UART_ERROR<<SUBINTOFFSET)|(BIT_UART_TXD<<SUBINTOFFSET)|(BIT_UART_RXD<<SUBINTOFFSET);				
	ClearPending(BIT_UART);	
}



void __irq DmaIsr(void) // only one for test
{
	unsigned char ch;
	unsigned char* pBuf;
	volatile unsigned int i;
	
	if (rSUBSRCPND&BIT_SUB_DMA0)
	{	//printf("\n [TX]IN DMA ");
		rDMASKTRIG0=0;	// Stop Dma0		
		ch = ((rDMAREQSEL0>>1) -19)/2;
		isTxDone[ch] = 1;
		
		rINTSUBMSK |= (BIT_SUB_DMA0);		
		rSUBSRCPND = BIT_SUB_DMA0;
		ClearPending(BIT_DMA);
	}

	if (rSUBSRCPND&BIT_SUB_DMA1)
	{	//printf("\n [RX]IN DMA ");
		rDMASKTRIG1=0;	// Stop Dma1
		pBuf = (unsigned char*)UART_BUF;
		ch = ((rDMAREQSEL1>>1) -19)/2;

		for (i=0; i<DMA_BUF_LEN; i++)
			*pUartRxStr[ch]++ = *pBuf++;

		if ( *(pUartRxStr[ch]-1) == RX_END_CHAR )		
		{			
			isRxDone[ch] = 1;
			*pUartRxStr[ch] = NULL; // added null after rx string
			rINTSUBMSK |= BIT_SUB_DMA1;
			rINTMSK |= BIT_DMA;			
		}
		else
		{			
			rDMASKTRIG1 = (0<<2)|(1<<1)|(0);    //no-stop, DMA1 channel on, no-SW trigger 			
		}	
		rSUBSRCPND = BIT_SUB_DMA1;
		ClearPending(BIT_DMA);	
	}	
}




////////////////////// User library functions /////////////////////

unsigned char SetBaudrate(unsigned char ch, unsigned int Baudrate)
{
	UART_REGS *pUartRegs;
	UART_CON *pUartCon;

	if (ch > 2) return FALSE;
	
	pUartCon = &UartCon[ch];	
	pUartRegs = (UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);

	pUartCon->iBaudrate = Baudrate;
	CalcBaudrate(pUartRegs, pUartCon);

	return TRUE;
}

unsigned char SetOpClock(unsigned char ch, unsigned int OpClock)
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;

	if (ch > 2) return FALSE;

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

	pUartCon->cOpClock = OpClock;
	pUartRegs->rUCon &= ~(3<<10);
	pUartRegs->rUCon |= (pUartCon->cOpClock<<10);

	return TRUE;
}

//DataBit    	0:5bit, 1:6bit, 2:7bit, 3:8bit
//ParityBit  	0,1,2,3:no parity, 4:odd, 5:even, 6:forced 1, 7:forced 0
//StopBit 	0:one stopbit, 1:two stopbit
unsigned char SetLineCon(unsigned char ch, unsigned char DataBit, unsigned char ParityBit, unsigned char StopBit)
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;

	if (ch > 2) return FALSE;

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

	pUartCon->cDataBit = DataBit;
	pUartCon->cParityBit = ParityBit;
	pUartCon->cStopBit = StopBit;
	pUartRegs->rUlCon = pUartRegs->rUlCon&(~0x3f) | (pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)|(pUartCon->cDataBit);

	return TRUE;
}

unsigned char SetDbgUart(unsigned char ch)
{
	if (ch > 3) return FALSE;

	memcpy(&UartCon[ch], &UartCon[4], sizeof(UART_CON));
	UartOpen(ch,1);
	
	return TRUE;
}


unsigned char UartOpen(unsigned char ch, unsigned int SetIRQ) // setting H/W & initializing regiter
{
	if(SetIRQ)
	{
		pISR_UART0 = (unsigned)UartIsr0;
		pISR_UART1 = (unsigned)UartIsr1;
		pISR_UART2 = (unsigned)UartIsr2;
		pISR_UART3 = (unsigned)UartIsr3;
		pISR_DMA = (unsigned)DmaIsr;
	}

	switch(ch)
	{
		case 0 :
			rGPHCON &= ~(0xf000f); // GPH0,1,8,9
			rGPHCON |= 0xa000a; // Uart 0 Rx, Tx, Rts, Cts			
			if(InitializeUart(UART0_REG, &UartCon[0])  == SENDBREAK)
				return SENDBREAK; // Initialize register set for Uart 0
			break;
		case 1 :
			rGPHCON &= ~(0xf000f<<4); // GPH2,3,10,11
			rGPHCON |= (0xa000a<<4); // Uart 1 Rx, Tx, Rts, Cts
			if(InitializeUart(UART1_REG, &UartCon[1]) == SENDBREAK)
				return SENDBREAK;
			break;
		case 2 :
			rGPHCON &= ~(0xf<<6); // GPH4,5
			rGPHCON |= (0xa<<6); // Uart 2 Rx, Tx
			if(InitializeUart(UART2_REG, &UartCon[2]) == SENDBREAK)
				return SENDBREAK;
			break;
		case 3 :
			rGPHCON &= ~(0xf<<12); // GPH6,7
			rGPHCON |= (0xa<<12); // Uart 3 Rx, Tx
			if(InitializeUart(UART3_REG, &UartCon[3]) == SENDBREAK)
				return SENDBREAK;
			break;
		default :
			printf("Can't open UARTx!! Select 0,1, or 2!!");
			return FALSE;
	}
	return TRUE;
}


unsigned char UartClose(unsigned char ch)  // return to reset value
{
	if (ch > 3) return FALSE;
	rINTMSK |= (BIT_UART);
	rINTSUBMSK |=  (BIT_UART_ERROR<<SUBINTOFFSET)|(BIT_UART_TXD<<SUBINTOFFSET)|(BIT_UART_RXD<<SUBINTOFFSET);
	rSUBSRCPND |=  (BIT_UART_ERROR<<SUBINTOFFSET)|(BIT_UART_TXD<<SUBINTOFFSET)|(BIT_UART_RXD<<SUBINTOFFSET);
	ClearPending(BIT_UART);

	switch(ch)
	{
		case 0 :
			rGPHCON &= ~(0xf000f); // GPH0,1,8,9			
			break;
		case 1 :
			rGPHCON &= ~(0xf000f<<4); // GPH2,3,10,11
			break;
		case 2 :
			rGPHCON &= ~(0xf<<6); // GPH4,5
			break;
		case 3 :
			rGPHCON &= ~(0xf<<12); // GPH6,7
			break;
		default :
			printf("Can't close UARTx!! Select 0,1, or 2!!");
			return FALSE;
	}
	return TRUE;
}

//---------------------------------------UART0 test function-------------------------------------

⌨️ 快捷键说明

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