📄 uartdrv.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 + -