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

📄 uartdrv.c

📁 基于EPSON 的一种操作系统内核改造的实时嵌入式操作系统ASIXOS,国内一家研发中心开发。精炼可靠
💻 C
字号:
/******************************************************************************
filename:		uart.c
author:			yc
create data:	2005-01-12
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>

#if UART_DEVNUM == 5
UARTDEV uartdev[5]={{{UART0_BASE, 24, 0x00000001, 0x00000002, 4, 5},},
				    {{UART1_BASE, INT_UART1, 0x00000004, 0x00000008, 6, 7},},
				    {{UART2_BASE, INT_UART2, 0x00000010, 0x00000020, 8, 9},},
				    {{UART3_BASE, INT_UART3, 0x00000040, 0x00000080, 10, 11},},
				    {{UART4_BASE, INT_UART4, 0x00000100, 0x00000200, 12, 13},}
				   };
#else
UARTDEV uartdev[3]={{{UART0_BASE, INT_UART0, 0x00000001, 0x00000002, 4, 5},},
				    {{UART1_BASE, INT_UART1, 0x00000004, 0x00000008, 6, 7},},
				    {{UART2_BASE, INT_UART2, 0x00000010, 0x00000020, 8, 9},}
				   };

#endif
                          
int init_uart(ID devid)					
{	
	int a;

	*(RP)UART_FCR(uartdev[devid].usetbl.UART_BASE) |= 0x02;	//clear BRB fifo
	*(RP)UART_FCR(uartdev[devid].usetbl.UART_BASE) |= 0x04;	//clear THR fifo
	a = *(RP)UART_RBR(uartdev[devid].usetbl.UART_BASE);		//clear timeout interrupt
		
	mask_irq(uartdev[devid].usetbl.INT_UART);
	
	*(RP)UART_IER(uartdev[devid].usetbl.UART_BASE) = 0x00;	
		
	memset(uartdev[devid].RecBuf, '\0', BUF_SIZE);
	memset(uartdev[devid].TraBuf, '\0', BUF_SIZE);
	
	uartdev[devid].wrcount = 0;
	uartdev[devid].rdcount = 0;	 
	 
	uartdev[devid].pReadRecBuf = uartdev[devid].RecBuf;
	uartdev[devid].pReadTraBuf = uartdev[devid].TraBuf;
	uartdev[devid].pWriteRecBuf = uartdev[devid].RecBuf;
	uartdev[devid].pWriteTraBuf = uartdev[devid].TraBuf;

	uartdev[devid].irq_uart_flag = 0;
         
		     
	return TRUE;
}

int conf_uart(ID devid, unsigned long sysclk, unsigned long baudrate, unsigned long databit, unsigned long trigerlevel)
{
		
	unsigned long	baud, bit, triger, baudh, baudl;
		
	
    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(uartdev[devid].usetbl.UART_BASE) = bit;
    *(RP)UART_LCR(uartdev[devid].usetbl.UART_BASE) |= (0x01 << 7);		//divisor latch accessed
                           
    *(RP)UART_DLL(uartdev[devid].usetbl.UART_BASE) = baudl;
    *(RP)UART_DLH(uartdev[devid].usetbl.UART_BASE) = baudh;
    *(RP)UART_LCR(uartdev[devid].usetbl.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(uartdev[devid].usetbl.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; 
		
	flag = (*(RP)UART_IIR(uartdev[devid].usetbl.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;
		  	
	for(i = 0; i < 8; i++)
	{
		*(uartdev[devid].pWriteRecBuf) = *(RP8)UART_RBR(uartdev[devid].usetbl.UART_BASE);	
		uartdev[devid].wrcount++;
		if(uartdev[devid].wrcount != BUF_SIZE) uartdev[devid].pWriteRecBuf++;
		else break;
	}
	uartdev[devid].pWriteRecBuf--;
	if(uartdev[devid].wrcount == BUF_SIZE)
	{
		uartdev[devid].wrcount = 0;
		uartdev[devid].pWriteRecBuf = uartdev[devid].RecBuf;
		set_flg(uartdev[devid].usetbl.RBUF_EVENT, uartdev[devid].usetbl.UART_REC);
		uartdev[devid].irq_uart_flag = 1;			//mask uart_irq
		return TRUE;
	}
	
	else if(uartdev[devid].pWriteRecBuf >= uartdev[devid].pReadRecBuf)
	{
		uartdev[devid].wrcount = 0;
		uartdev[devid].pWriteRecBuf = uartdev[devid].RecBuf;
		set_flg(uartdev[devid].usetbl.RBUF_EVENT, uartdev[devid].usetbl.UART_REC);
		uartdev[devid].irq_uart_flag = 1;			//mask uart_irq
		return TRUE;
	}
	uartdev[devid].pWriteRecBuf++;	
	
		
	return TRUE;     
}


int rec_tmo_handler(ID devid)
{
	*(uartdev[devid].pWriteRecBuf) = *(RP8)UART_RBR(uartdev[devid].usetbl.UART_BASE);	
			
	if(uartdev[devid].pWriteRecBuf >= uartdev[devid].pReadRecBuf)
	{
		uartdev[devid].pWriteRecBuf = uartdev[devid].RecBuf; 
		uartdev[devid].wrcount = 0;
		set_flg(uartdev[devid].usetbl.RBUF_EVENT, uartdev[devid].usetbl.UART_REC);	
		uartdev[devid].irq_uart_flag = 1;			//mask uart_irq
		return TRUE;
	}
	else
	{	
		uartdev[devid].wrcount++;
		uartdev[devid].pWriteRecBuf++;
	}
	
	return TRUE;
}
	
	
	


int	tra_emp_handler(ID devid)
{
	volatile int i;
	
	*(RP8)UART_THR(uartdev[devid].usetbl.UART_BASE) = *(uartdev[devid].pReadTraBuf);
	uartdev[devid].rdcount++;
	
	for(i = 0; i < 5000; i++);						//wait for transmitting data
	
	if(uartdev[devid].rdcount == BUF_SIZE)
	{
		uartdev[devid].rdcount = 0;
		uartdev[devid].pReadTraBuf = uartdev[devid].TraBuf;
		DIS_UART_TRA(uartdev[devid].usetbl.UART_BASE);
		uartdev[devid].irq_uart_flag = 1;			//mask uart_irq
		set_flg(uartdev[devid].usetbl.WBUF_EVENT, uartdev[devid].usetbl.UART_TRA);
//		return TRUE;	
	}
	else if(uartdev[devid].pReadTraBuf >= uartdev[devid].pWriteTraBuf)
	{	
		uartdev[devid].rdcount = 0;
		uartdev[devid].pReadTraBuf = uartdev[devid].TraBuf;
		DIS_UART_TRA(uartdev[devid].usetbl.UART_BASE);
		uartdev[devid].irq_uart_flag = 1;			//mask uart_irq
//		return TRUE;
	}
	else
		uartdev[devid].pReadTraBuf++;
	

	
	return TRUE;	
	
}


void ENT_INT_UART0( void )
{
	ent_int();
	
 	mask_irq(uartdev[0].usetbl.INT_UART);			//中断号需改
  	
	serv_uart(0);
	
	if(uartdev[0].irq_uart_flag == 0)	unmask_irq(uartdev[0].usetbl.INT_UART);
	
	ret_int();
}


void ENT_INT_UART1( void )
{
	ent_int();

 	mask_irq(uartdev[1].usetbl.INT_UART);
  	
	serv_uart(1);
	
	if(uartdev[1].irq_uart_flag == 0)	unmask_irq(uartdev[1].usetbl.INT_UART);
	
	ret_int();
}





⌨️ 快捷键说明

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