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

📄 uartdrv.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
字号:
/******************************************************************************
filename:		uart.c
author:			yc
create data:	2004-11-5
description:	the file initiate and config uart
******************************************************************************/
#include "stdio.h"
#include "string.h"

#include "HA_typedef.h"
#include "hardware.h"
#include "uartdrv.h"
#include "uartsrv.h"
#include <sys\systsk.h>
#include "internal.h"


#include <kernel\itron.h>


static int rdcount0 = 0;	//have read uart0 count
static int wrcount0 = 0;	//have write uart0 count
static int rdcount1 = 0;	//have read uart1 count 
static int wrcount1 = 0;	//have write uart1 count


int init_uart(ID devid)
{
		
	int uart_base;	
	int a;
	
	uart_base = (devid == UART0_ID) ? UART0_BASE : UART1_BASE;	//UART0: UART_BASE = 0x10004000
																//UART1: UART_BASE = 0x10005000

	if(devid == UART0_ID)
		*(RP)(PMU_PSCR) |= 0x0200;	//OPEN UART0
	else
		*(RP)(PMU_PSCR) |= 0x0100;	//OPEN UART1
		
	
	*(RP)UART_FCR(uart_base) |= 0x02;	//clear BRB fifo
	*(RP)UART_FCR(uart_base) |= 0x04;	//clear THR fifo
	a = *(RP)UART_RBR(uart_base);		//clear timeout interrupt
		
	if(uart_base == 0x10004000)                          
		mask_irq(INT_UART0);
	else 
		mask_irq(INT_UART1);
	
	
	*(RP)UART_IER(uart_base) = 0x00;	
//	*(RP)UART_LCR(uart_base) |= 0x80;
//	*(RP)UART_DLL(uart_base) = 0x00;
//	*(RP)UART_DLH(uart_base) = 0x00;
//	*(RP)UART_LCR(uart_base) = 0x11;
	
		
	memset(RecBuf0, '\0', BUF_SIZE);
	memset(TraBuf0, '\0', BUF_SIZE);
	memset(RecBuf1, '\0', BUF_SIZE);
	memset(TraBuf1, '\0', BUF_SIZE);
	
	wrcount0 = 0;
	rdcount0 = 0;	 
	wrcount1 = 0;
	rdcount1 = 0;
	 
	pReadRecBuf0 = RecBuf0;
	pReadTraBuf0 = TraBuf0;
	pWriteRecBuf0 = RecBuf0;
	pWriteTraBuf0 = TraBuf0;

	pReadRecBuf1 = RecBuf1;
	pReadTraBuf1 = TraBuf1;
	pWriteRecBuf1 = RecBuf1;
	pWriteTraBuf1 = TraBuf1;

	irq_uart0_flag = 0;
	irq_uart1_flag = 0;
	
		
	return TRUE;
}

int conf_uart(ID devid, unsigned long sysclk, unsigned long baudrate, unsigned long databit, unsigned long trigerlevel)
{
	int uart_base;	
	
	unsigned long	baud, bit, triger, baudh, baudl;
	
	uart_base = (devid == UART0_ID) ? UART0_BASE : UART1_BASE;	//UART0: UART_BASE = 0x10004000
																//UART1: UART_BASE = 0x10005000
		
	
    baud  = sysclk/16/baudrate;
    baudh = baud >> 8;
    baudl = baud & 0xff;
    
    switch(databit)
    {
    	case 5: bit = 0x00;
    		break;
    	     
    	case 6: bit = 0x01;
    		break;
    	       
    	case 7: bit = 0x02;
    		break;
    	     
    	case 8: bit = 0x03;
    		break;
    	
    	default: ;
    		break;             	  	
    }	
   // bit |= (0x01 << 7);
    *(RP)UART_LCR(uart_base) = bit;
    *(RP)UART_LCR(uart_base) |= (0x01 << 7);	//divisor latch accessed
                            
    *(RP)UART_DLL(uart_base) = baudl;
    *(RP)UART_DLH(uart_base) = baudh;
    *(RP)UART_LCR(uart_base) &= (~(0x01 << 7));	//divisor latch access disable
    
	switch(trigerlevel)
    {
    	case 1:  triger = 0x0;
    		break;
    	     
    	case 4:  triger = 0x1;
    		break;
    	     
    	case 8:  triger = 0x2;
    		break;
    	     
    	case 14: triger = 0x3;
    		break;
    	
    }	
	*(RP)UART_FCR(uart_base) = (triger << 6);
	
//	*(RP)UART_IER(uart_base) = 0x00;                          

/*	 
	if(uart_base == 0x10004000)                          
	{
		irq_enable(INT_UART0);
		unmask_irq(INT_UART0);
	}
	else 
	{
		irq_enable(INT_UART1);
		unmask_irq(INT_UART1);
	}
*/
	return TRUE;
	
}

/******************************************************************************
filename:		serv_uart
author:			yc
create data:	2004-11-5
description:	the file is used to serve uart interrupt
******************************************************************************/
int serv_uart(ID devid)
{
	int flag; 
	int uart_base;	
	
	
	
	uart_base = (devid == UART0_ID) ? UART0_BASE : UART1_BASE;	//UART0: UART_BASE = 0x10004000
																//UART1: UART_BASE = 0x10005000
	
	flag = (*(RP)UART_IIR(uart_base) & 0x0E) >> 1;
	
	switch(flag)
	{
		case STA_ERR:					//state error interrupt
        	return FALSE;
            
		case REC_FUL:					//receive fifo full interrupt
			rec_ful_handler(devid);
			break;
		   
		case REC_TMO:					//receive fifo time out interrrupt
			rec_tmo_handler(devid);
			break;
		   
		case TRA_EMP:					//transmit fifo empty interrupt
			tra_emp_handler(devid);
			break;
		   
		case MOD_ERR:					//modem state changed interrupt
			return FALSE;
		
		default:
			break;
	}	
	
	return TRUE;
	
}

int rec_ful_handler(ID devid)			//trigerlever interrupt
{

	int i;
	int uart_base;
	
	
	if(devid == UART0_ID)				//for uart0
	{
		uart_base = UART0_BASE;
		for(i = 0; i < 8; i++)
		{
			*pWriteRecBuf0 = *(RP8)UART_RBR(uart_base);	
			wrcount0++;
			if(wrcount0 != BUF_SIZE) pWriteRecBuf0++;
			else break;
		}
		pWriteRecBuf0--;
		if(wrcount0 == BUF_SIZE)
		{
			wrcount0 = 0;
			pWriteRecBuf0 = RecBuf0;
			set_flg(UART0_RBUF_EVENT, UART0_REC);
			irq_uart0_flag = 1;			//mask uart0_irq
			return TRUE;
		}
		
		else if(pWriteRecBuf0 >= pReadRecBuf0)
		{
			wrcount0 = 0;
			pWriteRecBuf0 = RecBuf0;
			set_flg(UART0_RBUF_EVENT, UART0_REC);
			irq_uart0_flag = 1;			//mask uart0_irq
			return TRUE;
		}
		pWriteRecBuf0++;	
		
	}
	
	
	else								//for uart1
	{
		uart_base = UART1_BASE;
		for(i = 0; i < 8; i++)
		{
			*pWriteRecBuf1 = *(RP8)UART_RBR(uart_base);	
			wrcount1++;
			if(wrcount1 != BUF_SIZE) pWriteRecBuf1++;
			else break;
		}
		pWriteRecBuf1--;
		if(wrcount1 == BUF_SIZE)
		{
			wrcount1 = 0;
			pWriteRecBuf1 = RecBuf1;
			set_flg(UART1_RBUF_EVENT, UART1_REC);
			irq_uart1_flag = 1;			//mask uart1_irq
			return TRUE;
		}
		
		else if(pWriteRecBuf1 >= pReadRecBuf1)
		{
			wrcount1 = 0;
			pWriteRecBuf1 = RecBuf1;
			set_flg(UART1_RBUF_EVENT, UART1_REC);
			irq_uart1_flag = 1;			//mask uart1_irq
			return TRUE;
		}
		pWriteRecBuf1++;	
		
	}
	
	
	return TRUE;     
}


int rec_tmo_handler(ID devid)
{
	int uart_base;
	
	if(devid == UART0_ID)				//for uart0
	{
		uart_base = UART0_BASE;
		
		*pWriteRecBuf0 = *(RP8)UART_RBR(uart_base);	
				
		if(pWriteRecBuf0 >= pReadRecBuf0)
		{
			pWriteRecBuf0 = RecBuf0; 
			wrcount0 = 0;
			set_flg(UART0_RBUF_EVENT, UART0_REC);	
			irq_uart0_flag = 1;			//mask uart0_irq
			return TRUE;
		}
		else
		{	
			wrcount0++;
			pWriteRecBuf0++;
		}
	}
	
	
	else								//for uart1
	{
		uart_base = UART1_BASE;
		
		*pWriteRecBuf1 = *(RP8)UART_RBR(uart_base);	
				
		if(pWriteRecBuf1 >= pReadRecBuf1)
		{
			pWriteRecBuf1 = RecBuf1; 
			wrcount1 = 0;
			set_flg(UART1_RBUF_EVENT, UART1_REC);	
			irq_uart1_flag = 1;			//mask uart1_irq
			return TRUE;
		}
		else
		{	
			wrcount1++;
			pWriteRecBuf1++;
		}
	}
	
	
	
	return TRUE;
}
	
	
	


int	tra_emp_handler(ID devid)
{
	int uart_base;	
	volatile int i;
	
	
	if(devid == UART0_ID)				//for uart0
	{
		uart_base = UART0_BASE;
		
		*(RP8)UART_THR(uart_base) = *pReadTraBuf0;
		rdcount0++;
		
		for(i = 0; i < 5000; i++);		//wait for transmitting data
		
		if(rdcount0 == BUF_SIZE)
		{
			rdcount0 = 0;
			pReadTraBuf0 = TraBuf0;
			DIS_UART_TRA(uart_base);
			irq_uart0_flag = 1;			//mask uart0_irq
			set_flg(UART0_WBUF_EVENT, UART0_TRA);
//			return TRUE;	
		}
		else if(pReadTraBuf0 >= pWriteTraBuf0)
		{	
			rdcount0 = 0;
			pReadTraBuf0 = TraBuf0;
			DIS_UART_TRA(uart_base);
			irq_uart0_flag = 1;			//mask uart0_irq
//			return TRUE;
		}
		else
			pReadTraBuf0++;
		
	}
	
	
	else								//for uart1
	{
		uart_base = UART1_BASE;
		
	//	if(((pReadTraBuf1 + 1)>= pWriteTraBuf1)||((rdcount1+2)==BUF_SIZE))
	//		DIS_UART_TRA(uart_base);
		
		*(RP8)UART_THR(uart_base) = *pReadTraBuf1;
		rdcount1++;
		
		for(i = 0; i < 5000; i++);		//wait for transmitting data
		
		if(rdcount1 == BUF_SIZE)
		{
			rdcount1 = 0;
			pReadTraBuf1 = TraBuf1;
			DIS_UART_TRA(uart_base);
			irq_uart1_flag = 1;			//mask uart1_irq
			set_flg(UART1_WBUF_EVENT, UART1_TRA);
//			return TRUE;	
		}
		else if(pReadTraBuf1 >= pWriteTraBuf1)
		{	
			rdcount1 = 0;
			pReadTraBuf1 = TraBuf1;
			DIS_UART_TRA(uart_base);
			irq_uart1_flag = 1;			//mask uart1_irq
//			return TRUE;
		}
		else
			pReadTraBuf1++;
		
	}
	
	
	
	
	return TRUE;	
	
}


void ENT_INT_UART0( void )
{
	ent_int();

 	mask_irq(INT_UART0);
  	
	serv_uart(UART0_ID);
	
	if(irq_uart0_flag == 0)	unmask_irq(INT_UART0);
	
	ret_int();
}


void ENT_INT_UART1( void )
{
	ent_int();

 	mask_irq(INT_UART1);
  	
	serv_uart(UART1_ID);
	
	if(irq_uart1_flag == 0)	unmask_irq(INT_UART1);
	
	ret_int();
}

⌨️ 快捷键说明

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