📄 uart.c
字号:
/*************************************************************************************
* Copyright (c) 2005 by National ASIC System Engineering Research Center.
* PROPRIETARY RIGHTS of ASIC are involved in the subject matter of this
* material. All manufacturing, reproduction, use, and sales rights
* pertaining to this subject matter are governed by the license agreement.
* The recipient of this software implicitly accepts the terms of the license.
*
* File Name: uart.c
*
* File Description:
* The file consists of the function used to config uart
*
* Function Description:
* uart_reset_value_test()
* check uart registers reset value
*
* HA_InitUart1(U32 clk, U32 baud, U32 bits, U32 triger)
* initiate UART
*
*
* ER en_re_int(U32)
* enable and disable the recieve int and the transmit int
* thr_isr_uart0(void)
interrupt handler for UART1
rda_isr_uart0(void)
interrupt handler
int_serv_uart0()
UART0 interrupt service
* Created by Michael <yuyu_zh@seu.edu.cn>, 2005-03-21
**************************************************************************************/
//#include "garfield.h"
#include "NUCLEUS.h"
#include "def.h"
#include "UART.h"
#include "hardware_reg.h"
#include "hardware_intc.h"
#include "modbusdef.h"
#define ESRAM_Test_BASE 0x1fff0000
#define HISR_STACK_SIZE 4096
extern unsigned long TMD_System_Clock;
extern char Task_Suspended;
extern NU_MEMORY_POOL System_Memory;
extern VOID ERC_System_Error(INT error_code);
extern NU_TASK _Modbus_Task;
NU_HISR UART_Int_HISR;
//extern _UART_ReciveData UART_ReciveData;
int ModuleUart(void)
{
U32 sysclk = 75000000; // 20MHz, 30MHz, 40MHz, 50MHz, 60MHz
U32 baudrate = 9600; // 57600, 56000, 38400, 19200, 9600
U32 databit = 8; // 6, 7, 8
U32 trigerlevel = 1; // 4, 8, 14
void (*old_lisr)(int);
void *pointer ;
int status;
int triger;
int a;
int recie = 1; //0 disable, 1 enble
int thrie = 0; //0 disable, 1 enble
/* open uart0 interrrupt mask */
unmask_irq(INT_UART1);//根据参数中断号判断出uart0屏蔽打开
init_uart0(sysclk, baudrate, databit, trigerlevel);//初始化uart0
uart0_int_en(recie, thrie);
*(RP)INTC_IEN |= 0X01800000; //第23,24位置1,打开uart1 uart2
unmask_all_irq();
MOD_revbuf.last_timetick = 0; //计时清零
MOD_revbuf.head = 0; //buff写指针清空
a = read_reg(UART0_RBR); //读一下fifo清接收中断
triger = (0x1 <<1); //清空fifo
write_reg(UART0_FCR, triger);
NU_Register_LISR(INT_UART1, UART_Int_LISR, &old_lisr);
NU_Allocate_Memory(&System_Memory, &pointer,HISR_STACK_SIZE, NU_NO_SUSPEND);
status = NU_Create_HISR(&UART_Int_HISR, "HISR_UART", UART_HISR_ENTRY, 2, pointer, HISR_STACK_SIZE);
if (status != NU_SUCCESS)
{
ERC_System_Error(status);
}
}
int message_flag = 0;
int sendover_flag = 0;
void UART_Int_LISR(int vecter)
{
int a;
int triger;
int recie ; //0 disable, 1 enble
int thrie ; //0 disable, 1 enble
int i;
int timetick1;
int timetick2;
volatile unsigned long * pp;
volatile unsigned long * mm;
volatile unsigned long time;
mask_irq(INT_UART1);
switch(( read_reg(UART0_IIR) & 0XE ) >> 1 )//判断bit【3:1】中断源标号
{
case 3 :
rls_isr(); //receiver line status interrupt接收数据状态中断
break;
case 2 : //receiver data available interrupt接收FIFO中的数据达到触发级中断
//rda_isr_uart0();
MOD_revbuf.buf[MOD_revbuf.head++] = read_reg(UART0_RBR);
MOD_revbuf.last_timetick = TMD_System_Clock;
/*
if( 11 == MOD_revbuf.head) //一条消息最多 0~10 11个字节
{
read_reg(UART0_IER) &= ~0x1;
a = read_reg(UART0_RBR); //读一下fifo清接收中断
triger = (0x1 <<1); //清空fifo
write_reg(UART0_FCR, triger);
}*/
break;
case 6 :
//tmo_isr_uart0(); //time out interrupt超时中断
a = read_reg(UART0_RBR); //读一下fifo清接收中断
triger = (0x1 <<1); //清空fifo
write_reg(UART0_FCR, triger);
/*
while( (*(RP8)UART0_LSR & 0x1) )
{
MOD_revbuf.buf[MOD_revbuf.head++] = read_reg(UART0_RBR);
if( 11 == MOD_revbuf.head) //一条消息最多 0~10 11个字节
{
read_reg(UART0_IER) &= ~0x1;
a = read_reg(UART0_RBR); //读一下fifo清接收中断
triger = (0x1 <<1); //清空fifo
write_reg(UART0_FCR, triger);
}
}
MOD_revbuf.last_timetick = TMD_System_Clock;
NU_Activate_HISR(&_Modbus_Task);
*/
break;
case 1 :
//thr_isr_uart0(); //transmit holding register empty interrupt 传输FIFO中断
sendover_flag = 1;
break;
case 0 :
mds_isr(); //modem status intertupt modem状态发生变化中断
break;
default :
break;
}
unmask_irq(INT_UART1);
}
int init_uart0(U32 sysclk, U32 baudrate, U32 databit, U32 trigerlevel)
{
U32 baud, bit, triger, baudh, baudl;
baud = sysclk/16/baudrate;//?
baudh = baud >> 8;//波特率高8位赋值
baudl = baud & 0xff;//波特率低8位赋值
switch(databit)//根据数据位大小判断,
//四种情况对应不同的数据比特数:00(5bits),01(6bits),10(7bits),11(8bits)
{
case 5: bit = 0x80;
break;
case 6: bit = 0x81;
break;
case 7: bit = 0x82;
break;
case 8: bit = 0x83;
break;
default: ;
break;
}
write_reg(UART0_LCR, bit); //divisor latch被访问,通过输入的数据bit第8位为1配置
write_reg(UART0_DLH, baudh);//将计算后的波特率写入高8位
write_reg(UART0_DLL, baudl);//将计算后的波特率写入低8位
read_reg(UART0_LCR) &= (~(0x1 << 7)); //通过UART0_LCR第8位和0相与置0,关闭波特率访问,
//转到普通寄存器的访问,至此完成的数据的初始化
switch(trigerlevel)//触发级初始化,定义transmitter FIFO的trigger level:00(0byte),
//01(2byte),10(4byte),11(8byte)
{
case 1: triger = 0x0;
break;
case 4: triger = 0x1;
break;
case 8: triger = 0x2;
break;
case 14: triger = 0x3;
break;
}
triger = (triger << 6); //receiver trigger
write_reg(UART0_FCR, triger);
//这个函数同样方法可以定义receiver FIFO的trigger level。
write_reg(UART0_IER, 0x00);//打开接收FIFO触发级中断使能
//
return E_OK;
}
int uart0_int_en(int recie, int thrie)//判断uart0是否准备接收和发送数据,从而决定FIFO的使能控制
{
if(recie == 1)//uart0准备好接收数据
read_reg(UART0_IER) |= 0x1;//开接收FIFO触发级中断使能/*received data available interrupt enable*/
else
if(recie == 0)//uart0没准备接收数据
read_reg(UART0_IER) &= ~0x1;//关闭接收FIFO触发级中断使能/*interrupt disable*/
if(thrie == 1)//uart0准备发送数据
read_reg(UART0_IER) |= (0x1 << 1);//开发送FIFO触发级空中断使能 /*transmitter holding register empty interrupt enable*/
else
if(thrie == 0)//uart0没准备好发送数据
read_reg(UART0_IER) &= ~(0x1 << 1); //关闭发送FIFO触发级空中断使能/*transmitter holding register empty interrupt disable*/
return E_OK;
}
ER thr_isr_uart0(void)
{
U32 i;
U32 a = 0x30;
prints("UART transmiter holding register handler!\n");
for(i=0; i<100; i++,a++)
write_reg(UART0_THR,a);//把要发送的数据放入传输FIFO
return E_OK;
}
ER rda_isr_uart0(void)
{
U32 a;
a = read_reg(UART0_RBR);//读取接收FIFO里的数据
return E_OK;
}
/*中断服务程序*/
void int_serv_uart0(void)
{
//a = (*(RP)UART0_IIR & 0XE ) >> 1;
switch(( read_reg(UART0_IIR) & 0XE ) >> 1 )//判断bit【3:1】中断源标号
//switch(a)
{
case 3 :
rls_isr(); //receiver line status interrupt接收数据状态中断
return ;
break;
case 2 :
rda_isr_uart0(); //receiver data available interrupt接收FIFO中的数据达到触发级中断
return ;
break;
case 6 :
tmo_isr_uart0(); //time out interrupt超时中断
return ;
break;
case 1 :
thr_isr_uart0(); //transmit holding register empty interrupt 传输FIFO中断
return ;
break;
case 0 :
mds_isr(); //modem status intertupt modem状态发生变化中断
return ;
break;
default :
return ;
}
}
void UART_HISR_ENTRY()
{
rda_isr_uart0();
Task_Suspended = 1;
}
extern ER rls_isr(void)//出现硬件错误
{
return E_HA;
}
extern ER mds_isr(void)//出现硬件错误
{
return E_HA;
}
ER tmo_isr_uart0(void)
{
volatile U32 a;
a = read_reg(UART0_RBR);//读取接收FIFO中数据,清除这个中断
prints("timer out now!!\n");
return E_OK;
}
ER prints(char *s)//把数据打印到上位机超级终端
{
int i;
while(*s != '\0')
{
{
*(RP)UART0_THR = *s++;//利用指针传输数据,这个是硬件管理的,我们只要把指针指向首数据地址,并且建立循环
}
for(i=0; i<5000 ; i++) ;
}
*(RP)UART0_THR = '\n';
return E_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -