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

📄 uart.c

📁 s3c6410基于USB OTG下载内核至NORFLASH的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

//////////
// Function Name : UART_TxString
// Function Description : This function trasmits String through UART
// Input : ch [0~4 UART channel]
//		 str [character type string that you want to transmit, the last charater of string should be 'NULL']
// Output : NONE
// Version : v0.1

void UART_TxString(u8 ch, u8 *str)  // The last character of 'str' should be NULL
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;
	u8 cTemp;
	u32 uTemp2;
	

	pUartRegs = (volatile UART_REGS *)(UART_BASE+UART_OFFSET*ch);
	pUartCon = &g_AUartCon[ch];	

	g_AisTxDone[ch] = 0;
	g_pUartTxStr[ch] = str;

	g_pFifoDebug = (u32 *)FIFO_DEBUG_BUF;
	g_uFcnt = 0;

	
	cTemp = Inp8(&pUartCon->cTxMode ) & 3;	
	
	if ( cTemp == 1 ) // interrupt mode
	{		
		INTC_Enable(NUM_UART0);
		INTC_Enable(NUM_UART1);
		INTC_Enable(NUM_UART2);
		INTC_Enable(NUM_UART3);	

		uTemp2 = Inp32(&pUartRegs->rUintM);
		uTemp2 &= ~(BIT_UART_TXD);	
		Outp32(&pUartRegs->rUintM,uTemp2);
//		pUartRegs->rUintM &= ~(BIT_UART_TXD);			
	}
	else if ( (cTemp==2) || (cTemp==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(!g_AisTxDone[ch]);

	// for debugging fifo 
	if ( (Inp32(&pUartRegs->rUfCon) & 1) && (cTemp == 1) ) // 1 : fifo enable 
	{
		g_pFifoDebug = (u32 *)FIFO_DEBUG_BUF;
		while(*g_pFifoDebug) // g_pFifoDebug address, Tx count, UfCon, g_uFcnt
			printf("[0x%x,%d,0x%x,%d] ", g_pFifoDebug, *g_pFifoDebug++, *g_pFifoDebug++,*g_pFifoDebug++);
	}
}



//////////
// Function Name : UART_RxString
// Function Description : This function receives String through UART
// Input : ch [0~4 UART channel]
// Output : g_pUartRxStr[ch] [charater type received string]
// Version : v0.1

u8* UART_RxString(u8 ch)  // The last character of input string should be '\r'. simple test code
{
	volatile UART_REGS *pUartRegs;
	volatile UART_CON *pUartCon;	
	u8 cTemp;
	u32 uTemp2;
	

	pUartRegs = (volatile UART_REGS *)(UART_BASE+UART_OFFSET*ch);
	pUartCon = &g_AUartCon[ch];	

	g_AisRxDone[ch] = 0;
	g_pUartRxStr[ch] = ( u8 *)(UART_BUF+DMA_BUF_LEN);

	g_pFifoDebug = (u32 *)FIFO_DEBUG_BUF;
	g_uFcnt = 0;
	
		
	cTemp = Inp8(pUartCon->cRxMode) & 3;
	if ( cTemp == 1 ) // interrupt mode
	{			
		Outp32(&pUartRegs->rUintSp , (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD));
		Outp32(&pUartRegs->rUintP , (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD));
		
		INTC_Enable(NUM_UART0);
		INTC_Enable(NUM_UART1);
		INTC_Enable(NUM_UART2);
		INTC_Enable(NUM_UART3);

		uTemp2 = Inp32(&pUartRegs->rUintM);
		uTemp2 &= ~(BIT_UART_ERROR|BIT_UART_RXD);	
		Outp32(&pUartRegs->rUintM,uTemp2);
		
	}
	else if ( (cTemp == 2) || (cTemp == 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;

		// 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(!g_AisRxDone[ch]);

	// for debugging fifo 
	if ( (Inp32(&pUartRegs->rUfCon) & 1) && (cTemp == 1) ) // 1 : fifo enable 
	{
		g_pFifoDebug = (u32 *)FIFO_DEBUG_BUF;
		while(*g_pFifoDebug)
			printf("[0x%x,%d,0x%x,%d] ", g_pFifoDebug, *g_pFifoDebug++, *g_pFifoDebug++,*g_pFifoDebug++);
	}
	g_pUartRxStr[ch] = ( u8 *)(UART_BUF+DMA_BUF_LEN);

	return g_pUartRxStr[ch];
}



//////////
// Function Name : UART_Open
// Function Description : This function set up H/W(GPIO) and initialize SFR of UART
// Input : ch [0~4 UART channel]
// Output : g_pUartRxStr[ch] [charater type received string]
// Version : v0.1

u8 UART_Open(u8 ch) // setting H/W & initializing regiter
{

	if(ch == 0)
		g_pUartDebugRegs = UART0_BASE;
	else if(ch == 1)
		g_pUartDebugRegs = UART1_BASE;
	else if(ch == 2)
		g_pUartDebugRegs = UART2_BASE;
	else if(ch == 3)
		g_pUartDebugRegs = UART3_BASE;	

/*
	INTC_SetVectAddr(NUM_DMA1,Isr_Dma);
	if(ch == 0)
	{
		INTC_SetVectAddr(NUM_UART0,Isr_Uart0);
		INTC_Enable(NUM_UART0);
	}
	else if(ch == 1)
	{
		INTC_SetVectAddr(NUM_UART1,Isr_Uart1);
		INTC_Enable(NUM_UART1);
	}
	else if(ch == 2)
	{
		INTC_SetVectAddr(NUM_UART2,Isr_Uart2);
		INTC_Enable(NUM_UART2);
	}
	else if(ch == 3)
	{
		INTC_SetVectAddr(NUM_UART3,Isr_Uart3);
		INTC_Enable(NUM_UART3);
	}
	else
		return 0;
*/
	switch(ch)
	{
		case 0 :
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_0, 2); //Uart0 RXD
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_1, 2); //Uart0 TXD			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_2, 2); //Uart0 CTSn			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_3, 2); //Uart0 RTSn			
			
//			rGPHCON &= ~(0xf000f); // GPH0,1,8,9
//			rGPHCON |= 0xa000a; // Uart 0 Rx, Tx, Rts, Cts			
			if(UART_InitializeREG(UART0_BASE, &g_AUartCon[0])  == SENDBREAK)
				return SENDBREAK; // Initialize register set for Uart 0
			break;
		case 1 :
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_4, 2); //Uart1 RXD
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_5, 2); //Uart1 TXD			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_6, 2); //Uart1 CTSn			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_7, 2); //Uart1 RTSn		

//			rGPHCON &= ~(0xf000f<<4); // GPH2,3,10,11
//			rGPHCON |= (0xa000a<<4); // Uart 1 Rx, Tx, Rts, Cts
			if(UART_InitializeREG(UART1_BASE, &g_AUartCon[1]) == SENDBREAK)
				return SENDBREAK;
			break;
		case 2 :
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_0, 2); //Uart2 RXD
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_1, 2); //Uart2 TXD			


//			rGPHCON &= ~(0xf<<6); // GPH4,5
//			rGPHCON |= (0xa<<6); // Uart 2 Rx, Tx
			if(UART_InitializeREG(UART2_BASE, &g_AUartCon[2]) == SENDBREAK)
				return SENDBREAK;
			break;
		case 3 :
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_2, 2); //Uart2 RXD
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_3, 2); //Uart2 TXD			

//			rGPHCON &= ~(0xf<<12); // GPH6,7
//			rGPHCON |= (0xa<<12); // Uart 3 Rx, Tx
			if(UART_InitializeREG(UART3_BASE, &g_AUartCon[3]) == SENDBREAK)
				return SENDBREAK;
			break;
		default :
			//printf("Can't open UARTx!! Select 0,1, or 2!!");
			return FALSE;
	}
	return TRUE;
}



//////////
// Function Name : UART_Close
// Function Description : This function closed H/W(GPIO) and disable UART exception
// Input : ch [0~4 UART channel]
// Output : 1: success 2:fail
// Version : v0.1

u8 UART_Close(u8 ch)  // return to reset value
{
	volatile UART_REGS *pUartRegs;

	if (ch > 2) return FALSE;
	pUartRegs = (volatile UART_REGS *)(UART_BASE+UART_OFFSET*ch);

	INTC_Disable(NUM_UART0);
	INTC_Disable(NUM_UART1);
	INTC_Disable(NUM_UART2);
	INTC_Disable(NUM_UART3);
	
	pUartRegs->rUintM |= (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
	
	switch(ch)
	{
		case 0 :
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_4, 0); //Uart1 RXD
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_5, 0); //Uart1 TXD			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_6, 0); //Uart1 CTSn			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_7, 0); //Uart1 RTSn		
	
			break;
		case 1 :
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_4, 0); //Uart1 RXD
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_5, 0); //Uart1 TXD			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_6, 0); //Uart1 CTSn			
			GPIO_SetFunctionEach(eGPIO_A, eGPIO_7, 0); //Uart1 RTSn		
			break;
		case 2 :
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_0, 0); //Uart2 RXD
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_1, 0); //Uart2 TXD	
			break;
		case 3 :
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_2, 0); //Uart2 RXD
			GPIO_SetFunctionEach(eGPIO_B, eGPIO_3, 0); //Uart2 TXD		
			break;
		default :
			printf("Can't close UARTx!! Select 0,1, or 2!!");
			return FALSE;
	}
	return TRUE;
}


//////////
// Function Name : UART_InitializeREG
// Function Description : This function set up SFR by pre-defined value 
// Input : *pUartRegs [SFR value base address]
//		 *pUartCon [Pre-defined value's base address, UART_Config]
// Output : SENDBREAK [when sendbreak signal set up]
//		    0 [nomal mode (sendbreak signal disable)]
// Version : v0.1

u32 UART_InitializeREG( UART_REGS *pUartRegs, UART_CON *pUartCon) // Initialize register set with current control set
{

	
	UART_CalcBaudrate(pUartRegs, pUartCon);
	
	Outp32(&pUartRegs->rUlCon , (pUartCon->cSelUartIrda<<6)|(pUartCon->cParityBit<<3)|(pUartCon->cStopBit<<2)
						|(pUartCon->cDataBit));
	Outp32(&pUartRegs->rUCon , (pUartCon->cOpClock<<10)|TX_INT_TYPE|RX_INT_TYPE|RX_ERR_INT_EN|RX_TIMEOUT_EN
						|(pUartCon->cLoopTest<<5)| (pUartCon->cSendBreakSignal<<4) |(pUartCon->cTxMode<<2)|(pUartCon->cRxMode));		
	if(Inp8(&pUartCon->cSendBreakSignal))
		return SENDBREAK;
	Outp32(&pUartRegs->rUfCon , (pUartCon->cTxTrig<<6)|(pUartCon->cRxTrig<<4)|TX_FIFO_RESET|RX_FIFO_RESET
						|(pUartCon->cEnableFifo));
	Outp32(&pUartRegs->rUmCon , (pUartCon->cRtsTrig<<5)|(pUartCon->cAfc<<4)|RTS_ACTIVE);	
	Outp32(&pUartRegs->rUintM , 0xf); // mask
	Outp32(&pUartRegs->rUintSp , 0xf); // source pending clear
	Outp32(&pUartRegs->rUintP , 0xf); // pending clear

	return 0;
	
}


//////////
// Function Name : UART_CalcBaudrate
// Function Description : This function defines UbrDiv and UdivSlot value depends on OpClock src
// Input : *pUartRegs [SFR value base address]
//		 *pUartCon [Pre-defined value's base address, UART_Config]
// Output : NONE
// Version : v0.1

void UART_CalcBaudrate( UART_REGS *pUartRegs, UART_CON *pUartCon)
{
	const u32 aSlotTable[16] = {0x0000, 0x0080, 0x0808, 0x0888, 0x2222, 0x4924, 0x4a52, 0x54aa,
				     		0x5555, 0xd555, 0xd5d5, 0xddd5, 0xdddd, 0xdfdd, 0xdfdf, 0xffdf};
	float tempDiv;
	u32 nOpClock;
	u32 nSlot;
	
	switch(Inp8(&pUartCon->cOpClock))
	{
		case 0 :
		case 2 : // Pclk
		default : 			
			nOpClock = g_PCLK;			
			break;
	}

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


//////////
// Function Name : Isr_Uart0~3
// Function Description : These are Interrupt Service Routine of UART which are connected to Isr_UartSub
// Input : NONE
// Output : NONE
// Version : v0.1

void __irq Isr_Uart0(void)
{		
	
	Isr_UartSub(0);	
	INTC_ClearVectAddr();
}		

void __irq Isr_Uart1(void)
{	
	Isr_UartSub(1);
	INTC_ClearVectAddr();
}

void __irq Isr_Uart2(void)
{	
	Isr_UartSub(2);
	INTC_ClearVectAddr();
}

void __irq Isr_Uart3(void)
{	
	Isr_UartSub(3);
	INTC_ClearVectAddr();	
}	


//////////
// Function Name : Isr_UartSub
// Function Description : This is Uart SubISR which checks errors and operates Tx and Rx
// Input : NONE
// Output : NONE
// Version : v0.1

void Isr_UartSub(u8 ch)
{
	u32 ErrorStatus = 0;	
	volatile UART_REGS *pUartRegs;			
	u8 tempChar;
	u32 uTemp;

	pUartRegs = ( UART_REGS *)(UART_BASE+UART_OFFSET*ch);

	
	// Check Errors 	
	if (Inp32(&pUartRegs->rUintP) & BIT_UART_ERROR)
	{

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

⌨️ 快捷键说明

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