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

📄 uart.c

📁 三星s3c2460开发板完整功能测试代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				printf("%c", tempChar);
				*pUartRxStr[ch]++ = tempChar;
			}
			else 
			{
				*pUartRxStr[ch] = NULL;
			    	printf("\n");
				isRxDone[ch] = 1;
				rSUBSRCPND = chBit;
				ClearPending(BIT_UART);		
				return;
			}
			pUartRegs->rUintM &= ~(BIT_UART_RXD);
		}
	}

	// Modem UART ISR	
	if (pUartRegs->rUintP & BIT_UART_MODEM)
	{
		pUartRegs->rUintM |= BIT_UART_MODEM;
		pUartRegs->rUintSp = BIT_UART_MODEM;		
		pUartRegs->rUintP = BIT_UART_MODEM;

		// Implementation for modem uart

		pUartRegs->rUintM &= ~(BIT_UART_MODEM);
	}

	// unknown UART interrupt 
	if (pUartRegs->rUintP & ~(BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD))
		printf("UARTx sub INT - unknown sub interrupt!!\n");

	rSUBSRCPND = chBit;
	ClearPending(BIT_UART);

	rINTSUBMSK &= ~chBit; 
}


void __irq DmaIsr(void) // only one for test
{
	unsigned char ch;
	unsigned char* pBuf;
	volatile unsigned int i;
	
	rINTMSK |= BIT_DMA_SBUS;

	if (rSUBSRCPND&BIT_SUB_DMA0)
	{
		rDMASKTRIG0=0;	// Stop Dma0
		rINTSUBMSK |= BIT_SUB_DMA0;
		rSUBSRCPND = BIT_SUB_DMA0;
		ClearPending(BIT_DMA_SBUS);

		ch = ((rDMAREQSEL0>>1) -19)/2;
		isTxDone[ch] = 1;

		rINTSUBMSK &= ~BIT_SUB_DMA0;
	}

	if (rSUBSRCPND&BIT_SUB_DMA1)
	{
		rDMASKTRIG1=0;	// Stop Dma1
		rINTSUBMSK |= BIT_SUB_DMA1;
		rSUBSRCPND = BIT_SUB_DMA1;
		ClearPending(BIT_DMA_SBUS);

		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
		}
		else
		{
			rDMASKTRIG1 = (0<<2)|(1<<1)|(0);    //no-stop, DMA1 channel on, no-SW trigger 
		}

		rINTSUBMSK &= ~BIT_SUB_DMA1;
	}

	rINTMSK &= ~BIT_DMA_SBUS;
}



////////////////////// 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 > 2) return FALSE;

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


unsigned char UartOpen(unsigned char ch) // setting H/W & initializing regiter
{
	pISR_UART = (unsigned)UartIsr;
	pISR_DMA_SBUS = (unsigned)DmaIsr;

	switch(ch)
	{
		case 0 :
			rGPHCON &= ~(0xff); // GPH0~3
			rGPHCON |= 0xaa; // Uart 0 Rx, Tx, Rts, Cts
			rGPHPU |= 0xf; // pull-up disable
			InitializeUart(UART0_REG, &UartCon[0]); // Initialize register set for Uart 0
			break;
		case 1 :
			rGPHCON &= ~(0xff<<8); // GPH4~7
			rGPHCON |= (0xaa<<8); // Uart 1 Rx, Tx, Rts, Cts
			rGPHPU |= (0xf<<4);
			InitializeUart(UART1_REG, &UartCon[1]);
			break;
		case 2 :
			rGPHCON &= ~(0xf<<18); // GPH9~10
			rGPHCON |= (0xa<<18); // Uart 2 Rx, Tx
			rGPHPU |= (3<<9);
			InitializeUart(UART2_REG, &UartCon[2]);
			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
{
	volatile UART_REGS *pUartRegs;

	if (ch > 2) return FALSE;
	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);

	rINTMSK |= (BIT_UART);
	rINTSUBMSK |= (1<<ch); 
	pUartRegs->rUintM |= (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
	rSUBSRCPND = (1<<ch);    
	ClearPending(BIT_UART);

	switch(ch)
	{
		case 0 :
			rGPHCON &= ~(0xff); // GPH0~3
			rGPHPU &= ~(0xf); // pull-up disable
			break;
		case 1 :
			rGPHCON &= ~(0xff<<8); // GPH4~7
			rGPHPU &= ~(0xf<<4);
			break;
		case 2 :
			rGPHCON &= ~(0xf<<18); // GPH9~10
			rGPHPU &= ~(3<<9);
			break;
		default :
			printf("Can't close UARTx!! Select 0,1, or 2!!");
			return FALSE;
	}
	return TRUE;
}


///////////////////////// 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~2) [D=0] : ");
	ch = (unsigned char)GetIntNum();
	if ( ch>2 )
		ch = 0; // default uart 0
	pUartCon = &UartCon[ch];	
	pUartRegs = (volatile UART_REGS *)(UART_REG_BASE+UART_REG_OFFSET*ch);

	printf("Select Setting method  \n 1. User Setting[D]	2. Use Default Setting(B115200,D8,P0,S1,NC,Int,no FIFO)\n Choose : ");
	if (GetIntNum() == 2)
	{
		memcpy(&UartCon[ch], &UartCon[3], sizeof(UART_CON));	
		return ch;
	}

	// Set Operation clock
	printf("\nConnect PC[COM1 or COM2] and UART%d of SMDK2460 with a serial cable for test!!! \n", ch);
	printf("Select Operating Clock\n 1. PCLK[D]	2. UEXTCLK	3. EPLL \n Choose : ");
	switch (GetIntNum())
	{
	case 2 :
		pUartCon->cOpClock = 1;
#if 1 // connect CLKOUT and UEXTCLK
		rGPHCON &= ~(3<<16); // Uextclk using		
		rCLKOUTCON = (4<<12); // clkout = PCLK
		rSPCON &= ~(1<<17); // clkout en
		UextClk = PCLK; 
#else // if you want to use any clock source except the PCLK
		printf("\nType External Clock(Hz) [D=PCLK] : ");
		UextClk = GetIntNum();	
		if ((int)UextClk == -1) UextClk = PCLK; 
		rCLKOUTCON = (5<<12)|(1<<4)|1; // DCLK = PCLK/2 
		UextClk = PCLK/2;
#endif
		break;

	case 3 :
		pUartCon->cOpClock = 3;
		SetEPLL(42, 1, 2); // Epll output - 96MHz, pll input - 12MHz
#if 1 // use EPLL output clock
		rCLKSRCCON = rCLKSRCCON&~(1<<10)|(1<<6); // epll output select
		EpllClk = 50000000; 
#else // use reference clock
		rCLKSRCCON |= (1<<10); // crystal input
		EpllClk = 12000000; 
#endif
		printf("rEPLLCON = 0x%x \n", rEPLLCON);
		printf("rCLKSRCCON = 0x%x \n", rCLKSRCCON);
		printf("rCLKDIVCON = 0x%x \n", rCLKDIVCON);
		break;

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

	// Select UART or IrDA 1.0
	printf("Select 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("Type 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("Select 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("Select 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("Select 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;

	iTemp = pUartCon->cTxMode & 3;
	if ( iTemp == 1 ) // interrupt mode
	{
		rINTMSK &= ~(BIT_UART);
		rINTSUBMSK &= ~(1<<ch);
		pUartRegs->rUintM &= ~(BIT_UART_TXD);
	}
	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_SBUS);
		rINTMSK &= ~(BIT_DMA_SBUS);
		rINTSUBMSK &= ~(BIT_SUB_DMA0);
		rDMASKTRIG0 = (0<<2)|(1<<1)|(0);    //no-stop, DMA0 channel on, no-SW trigger 
	}
	
	while(!isTxDone[ch]);

	// for debugging fifo 
	if ( (pUartRegs->rUfCon & 1) && (iTemp == 1) ) // 1 : fifo enable 
	{
		pFifoDebug = (unsigned int *)FIFO_DEBUG_BUF;
		while(*pFifoDebug) // pFifoDebug address, Tx count, UfCon, fcnt
			printf("[0x%x,%d,0x%x,%d] ", pFifoDebug, *pFifoDebug++, *pFifoDebug++,*pFifoDebug++);
	}
}


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;

	iTemp = pUartCon->cRxMode & 3;
	if ( iTemp == 1 ) // interrupt mode
	{
		pUartRegs->rUintSp = (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
		pUartRegs->rUintP = (BIT_UART_MODEM|BIT_UART_TXD|BIT_UART_ERROR|BIT_UART_RXD);
		rSUBSRCPND = (1<<ch);     
		ClearPending(BIT_UART);
		rINTMSK &= ~(BIT_UART);
		rINTSUBMSK &= ~(1<<ch);
		pUartRegs->rUintM &= ~(BIT_UART_ERROR|BIT_UART_RXD);
	}
	else if ( (iTemp == 2) || (iTemp == 3) ) // dma mode
	{
		rDISRC1=(unsigned int)(&pUartRegs->rUrxh);	// Start address
		rDISRCC1=(1<<1)|(1);		// APB,Fixed
		rDIDST1=(unsigned int)(UART_BUF);	        // Memory buffer Address

⌨️ 快捷键说明

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