📄 uart.c
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009, lst.
//版权所有 (C), 2004-2009, lst.
//所属模块: uart驱动程序
//作者:lst
//版本:V1.0.1
//文件描述: 驱动44b0的uart
//其他说明:
//修订历史:
// 2. 日期:2009-02-10
// 作者: lst
// 新版本号:1.0.1
// 修改说明: 修改uart0_txint中的笔误,345行的tg_uart1_CB改为tg_uart0_CB
// 1. 日期:2009-01-31
// 作者:lst
// 新版本号:1.0.0
// 修改说明: 原始版本
//------------------------------------------------------
#include <string.h>
#include "inc_os.h"
#include "uart.h"
static struct pan_device *pg_uart0_dev;
static struct pan_device *pg_uart1_dev;
static struct dev_handle *pg_uart0_rhdl;
static struct dev_handle *pg_uart1_rhdl;
static struct uart_UCB tg_uart0_CB,tg_uart1_CB;
uint16_t u16g_evtt_uart0_error;
uint16_t u16g_evtt_uart1_error;
uint8_t uart0_ptcl_send_buf[uart0_buf_len];
uint8_t uart1_ptcl_send_buf[uart1_buf_len];
uint8_t uart0_ptcl_recv_buf[uart0_buf_len];
uint8_t uart1_ptcl_recv_buf[uart1_buf_len];
//----检查串口0接收缓冲区------------------------------------------------------
//功能: 检查接收fifo缓冲区的状态,如果fifo溢出将弹出串口错误事件。
//参数:无。
//返回: 接收fifo中的数据量,如果溢出也返回0
//-----------------------------------------------------------------------------
uint16_t uart_check_rx0_fifo(void)
{
uint16_t rx;
rx = tg_uart0_CB.my_reg->UFSTAT;
if( rx & cn_rx_over)
{
tg_uart0_CB.my_reg->UFCON |= cn_rx_fifo_reset;
tg_uart0_CB.status |= cn_ser_receive_over;
y_event_pop(u16g_evtt_uart0_error,enum_recv_fifo_over,0,0);
return 0;
}else
return(rx & 0x0f);
}
//----检查串口1接收缓冲区------------------------------------------------------
//功能: 检查接收fifo缓冲区的状态,如果fifo溢出将弹出串口错误事件。
//参数:无。
//返回: 接收fifo中的数据量,如果溢出也返回0
//-----------------------------------------------------------------------------
uint16_t uart_check_rx1_fifo(void)
{
ufast_t rx;
rx = tg_uart1_CB.my_reg->UFSTAT;
if( rx & cn_rx_over)
{
tg_uart1_CB.my_reg->UFCON |= cn_rx_fifo_reset;
tg_uart1_CB.status |= cn_ser_receive_over;
y_event_pop(u16g_evtt_uart1_error,enum_recv_fifo_over,0,0);
return 0;
}else
return(rx & 0x0f);
}
//----检查串口发送缓冲区是否满-------------------------------------------------
//功能: 检查发送fifo缓冲区的状态,如果fifo满就返回true
//参数:无。
//返回: true = 缓冲区满,false = 非满
//-----------------------------------------------------------------------------
bool_t uart_tx_fifo_full(struct hard_reg_uart *hard_reg_uart)
{
return (hard_reg_uart->UFSTAT &0x200);
}
//----检查串口发送缓冲区是否空-------------------------------------------------
//功能: 检查发送fifo缓冲区的状态,如果fifo空就返回true
//参数:无。
//返回: true = 缓冲区空,false = 非空
//-----------------------------------------------------------------------------
bool_t uart_tx_fifo_empty(struct hard_reg_uart *hard_reg_uart)
{
return (0==(hard_reg_uart->UFSTAT &0x0f0));
}
//----初始化uart0模块----------------------------------------------------------
//功能:初始化uart0模块
//参数:模块初始化函数没有参数
//返回:true = 成功初始化,false = 初始化失败
//-----------------------------------------------------------------------------
bool_t module_init_uart0(void)
{
struct semaphore_LCB *left_semp,*right_semp;
uint16_t uart_send_evtt;
//分别创建左手和右手访问uart0设备的信号量,第一个参数为1表示串口是独占访问
//的,第二个参数1表示初始状态有一盏信号灯点亮。左手由应用程序使用,右手由硬
//件操作函数使用。
tg_uart0_CB.send_buf_semp = semp_create(1,0,"uart0 buf left");
if(tg_uart0_CB.send_buf_semp == NULL)
goto exit_from_left_buf_semp;
tg_uart0_CB.recv_buf_semp = semp_create(1,0,"uart0 buf right");
if(tg_uart0_CB.recv_buf_semp == NULL)
goto exit_from_right_buf_semp;
left_semp = semp_create(1,1,"uart0 device left");
if(left_semp == NULL)
goto exit_from_left_semp;
right_semp = semp_create(1,1,"uart0 device right");
if(right_semp == NULL)
goto exit_from_right_semp;
//系统初始化时已经使中断处于禁止状态,无需再禁止和清除中断。
//初始化uart硬件控制数据结构
tg_uart0_CB.my_reg = (struct hard_reg_uart *)0x1d00000;
tg_uart0_CB.my_reg->UFCON = 0x57; //bit0=1使能fifo.
tg_uart0_CB.my_reg->UMCON = 0x0;
tg_uart0_CB.my_reg->ULCON = 0x3;
tg_uart0_CB.my_reg->UCON = 0xc5;
tg_uart0_CB.my_reg->UBRDIV = ((cn_mclk<<2)/57600 -32)>>6;
tg_uart0_CB.baud = 57600;
tg_uart0_CB.rx_int_line = cn_irq_line_urxd0;
tg_uart0_CB.tx_int_line = cn_irq_line_utxd0;
//初始化通用串口数据结构
tg_uart0_CB.recv_trigger_level = 0; //缓冲接收触发水平为0
tg_uart0_CB.send_trigger_level = uart0_buf_len>>4; //缓冲发送触发水平为1/16
tg_uart0_CB.timeout = 500; //超时时间=500
ring_init( &tg_uart0_CB.send_ring_buf,
uart0_ptcl_send_buf,
uart0_buf_len);
ring_init( &tg_uart0_CB.recv_ring_buf,
uart0_ptcl_recv_buf,
uart0_buf_len);
tg_uart0_CB.status = cn_ser_rxbuf_empty;
//以下建立uart0设备
pg_uart0_dev = dev_add_root_device("uart0",
right_semp,left_semp,
(dev_write_func) uart_right_write,
(dev_read_func ) uart_right_read,
(dev_ctrl_func ) uart_ctrl,
(dev_write_func ) uart_left_write,
(dev_read_func ) uart_left_read,
(dev_ctrl_func ) uart_ctrl
); //"uart0"是一个根设备
if(pg_uart0_dev == NULL)
goto exit_from_add_device;
//tg_serial_uart0是uart0设备的私有数据
pg_uart0_dev->private_tag = (ptu32_t)(&tg_uart0_CB);
pg_uart0_rhdl = dev_open_right("uart0",0); //打开右手句柄
u16g_evtt_uart0_error = y_evtt_regist(
true,false,110,10,uart_error_service,1024,NULL);
if(u16g_evtt_uart0_error == cn_invalid_evtt_id)
goto exit_from_error_evtt;
uart_send_evtt = y_evtt_regist(true,false,cn_prio_real,
1,uart_send_service,20,NULL);
if(uart_send_evtt == cn_invalid_evtt_id)
goto exit_from_send_evtt;
dev_ctrl(pg_uart0_rhdl,enum_uart_connect_send_evtt,uart_send_evtt,0);
int_echo_line(cn_irq_line_utxd0); //清除可能存在的中断
int_echo_line(cn_irq_line_urxd0); //清除可能存在的中断
int_echo_line(cn_irq_line_uerr01); //清除可能存在的中断
int_isr_connect(cn_irq_line_utxd0,uart0_txint);
int_setto_asyn_signal(cn_irq_line_utxd0);
int_isr_connect(cn_irq_line_urxd0,uart0_rxint);
int_setto_asyn_signal(cn_irq_line_urxd0);
return true;
exit_from_send_evtt:
y_evtt_unregist(u16g_evtt_uart0_error);
exit_from_error_evtt:
dev_delete_device(pg_uart0_dev);
exit_from_add_device:
semp_delete(right_semp);
exit_from_right_semp:
semp_delete(left_semp);
exit_from_left_semp:
semp_delete(tg_uart0_CB.recv_buf_semp);
exit_from_right_buf_semp:
semp_delete(tg_uart0_CB.send_buf_semp);
exit_from_left_buf_semp:
return false;
}
bool_t module_init_uart1(void)
{
struct semaphore_LCB *left_semp,*right_semp;
uint16_t uart_send_evtt;
tg_uart1_CB.send_buf_semp = semp_create(1,0,"uart1 buf left");
if(tg_uart1_CB.send_buf_semp == NULL)
goto exit_from_left_buf_semp;
tg_uart1_CB.recv_buf_semp = semp_create(1,0,"uart1 buf right");
if(tg_uart1_CB.recv_buf_semp == NULL)
goto exit_from_right_buf_semp;
left_semp = semp_create(1,1,"uart1 device left");
if(left_semp == NULL)
goto exit_from_left_semp;
right_semp = semp_create(1,1,"uart1 device right");
if(right_semp == NULL)
goto exit_from_right_semp;
//系统初始化时已经使中断处于禁止状态,无需再禁止和清除中断。
//初始化uart硬件控制数据结构
tg_uart1_CB.my_reg = (struct hard_reg_uart *)0x1d04000;
tg_uart1_CB.my_reg->UFCON = 0x57; //bit0=1使能fifo.
tg_uart1_CB.my_reg->UMCON = 0x0;
tg_uart1_CB.my_reg->ULCON = 0x3;
tg_uart1_CB.my_reg->UCON = 0xc5;
tg_uart1_CB.my_reg->UBRDIV = ((cn_mclk<<2)/57600 -32)>>6;
tg_uart1_CB.baud = 57600;
tg_uart1_CB.rx_int_line = cn_irq_line_urxd1;
tg_uart1_CB.tx_int_line = cn_irq_line_utxd1;
//初始化通用串口数据结构
tg_uart1_CB.recv_trigger_level = 0; //缓冲接收触发水平为0
tg_uart1_CB.send_trigger_level = uart0_buf_len>>4; //缓冲发送触发水平为1/16
tg_uart1_CB.timeout = 500; //超时时间=500
ring_init( &tg_uart1_CB.send_ring_buf,
uart1_ptcl_send_buf,
uart1_buf_len);
ring_init( &tg_uart1_CB.recv_ring_buf,
uart1_ptcl_recv_buf,
uart1_buf_len);
tg_uart1_CB.status = cn_ser_rxbuf_empty;
//以下建立uart1设备
pg_uart1_dev = dev_add_root_device("uart1",
right_semp,left_semp,
(dev_write_func) uart_right_write,
(dev_read_func ) uart_right_read,
(dev_ctrl_func ) uart_ctrl,
(dev_write_func ) uart_left_write,
(dev_read_func ) uart_left_read,
(dev_ctrl_func ) uart_ctrl
); //"uart1"是一个根设备
if(pg_uart1_dev == NULL)
goto exit_from_add_device;
//tg_serial_uart1是uart1设备的私有数据
pg_uart1_dev->private_tag = (ptu32_t)(&tg_uart1_CB);
pg_uart1_rhdl = dev_open_right("uart1",0); //打开右手句柄
u16g_evtt_uart1_error = y_evtt_regist(
true,false,110,10,uart_error_service,1024,NULL);
if(u16g_evtt_uart1_error == cn_invalid_evtt_id)
goto exit_from_error_evtt;
uart_send_evtt = y_evtt_regist(true,false,cn_prio_real,
1,uart_send_service,20,NULL);
if(uart_send_evtt == cn_invalid_evtt_id)
goto exit_from_send_evtt;
dev_ctrl(pg_uart1_rhdl,enum_uart_connect_send_evtt,uart_send_evtt,0);
int_echo_line(cn_irq_line_utxd1); //清除可能存在的中断
int_echo_line(cn_irq_line_urxd1); //清除可能存在的中断
int_echo_line(cn_irq_line_uerr01); //清除可能存在的中断
int_isr_connect(cn_irq_line_utxd1,uart1_txint);
int_setto_asyn_signal(cn_irq_line_utxd1);
int_isr_connect(cn_irq_line_urxd1,uart1_rxint);
int_setto_asyn_signal(cn_irq_line_urxd1);
return true;
exit_from_send_evtt:
y_evtt_unregist(u16g_evtt_uart1_error);
exit_from_error_evtt:
dev_delete_device(pg_uart1_dev);
exit_from_add_device:
semp_delete(right_semp);
exit_from_right_semp:
semp_delete(left_semp);
exit_from_left_semp:
semp_delete(tg_uart1_CB.recv_buf_semp);
exit_from_right_buf_semp:
semp_delete(tg_uart1_CB.send_buf_semp);
exit_from_left_buf_semp:
return false;
}
void uart_error_service(struct event_script *my_event)
{
y_clear_mark();
}
//----uart0接收中断------------------------------------------------------------
//功能: 1.检查接收fifo中的数据量.把数据从接收寄存器全部copy到物理层缓冲区中.
// 2.如果物理层缓冲区满.置串口控制块状态字的溢出位,并发出uart错误事件.
// 3.发送串口接收事件.两个事件都是状态量事件
//参数: 中断函数没有参数.
//返回: 中断函数没有返回值.
//-----------------------------------------------------------------------------
uint32_t uart0_rxint(ufast_t uart_int_line)
{
uint16_t revs,num;
uint16_t rx;
uint8_t ch[16];
rx = tg_uart0_CB.my_reg->UFSTAT;
revs = rx & 0xf;
for(num = 0; num < revs; num++)
//fifo缓冲区有数据,直到处理完成
ch[num] = tg_uart0_CB.my_reg->URXH;
dev_write(pg_uart0_rhdl,(ptu32_t)ch,0,revs);
if( rx & cn_rx_over)
{
tg_uart0_CB.my_reg->UFCON |= cn_rx_fifo_reset;
y_event_pop(u16g_evtt_uart0_error,enum_recv_fifo_over,0,0);
}
return 0;
}
//----uart1接收中断------------------------------------------------------------
//功能: 1.检查接收fifo中的数据量.把数据从接收寄存器全部copy到物理层缓冲区中.
// 2.如果物理层缓冲区满.置串口控制块状态字的溢出位,并发出uart错误事件.
// 3.发送串口接收事件.两个事件都是状态量事件
//参数: 中断函数没有参数.
//返回: 中断函数没有返回值.
//-----------------------------------------------------------------------------
uint32_t uart1_rxint(ufast_t uart_int_line)
{
uint16_t revs,num;
uint16_t rx;
uint8_t ch[16];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -