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

📄 uart.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------
//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 + -