📄 uart.c
字号:
/***************************************************************************\
Copyright (c) 2004-2007 threewater@up-tech.com, All rights reserved.
by threewter 2004.4.26
\***************************************************************************/
/***************************************************************************\
#说明: 串口抽象层函数
---------------------------------- Bug --------------------------------------
---------------------------------- TODO list --------------------------------------
----------------------------------修正--------------------------------------
2004-5-26 创建
\***************************************************************************/
#include "../inc/marco.h"
#include "../ucos-ii/includes.h"
#include "../ucos-ii/uhal/isr.h"
#include "uart.h"
#include "sys/lib.h"
extern struct_Uart_Buffer Uart_Buffer[];
extern serial_driver_t* serial_drv[];
extern int NumberOfUartDrv;
/*********************************\
有数据收到,
填充接收缓冲区数据
\**********************************/
void Put_RevBuffer(int ndev, U8 data)
{
int nrev;
struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
//Receive data
pUart_Buffer->revBuffer[pUart_Buffer->nUart_rev]=data;
RoundINC(pUart_Buffer->nUart_rev, UART_REVBUFFER_SIZE);
nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
if(nrev>=pUart_Buffer->nRev_Uart)
OSSemPost(pUart_Buffer->Uart_Rev_sem);
}
/*********************************\
获得发送缓冲区的数据
成功返回数据
没有数据,则返回-1
\**********************************/
int Get_SndBuffer(int ndev)
{
int data;
int n;
struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
//get data
n=RoundCount(pUart_Buffer->nUart_write, pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
if(n==0)
return -1;
data=pUart_Buffer->sndBuffer[pUart_Buffer->nUart_send];
RoundINC(pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
n=UART_SNDBUFFER_SIZE-n;
if(n>=UART_SNDBUFFER_SIZE/2)
OSSemPost(pUart_Buffer->Uart_Snd_sem);
return data;
}
/*
void irq_OSRevUart(int vector, int ndev)
{
int nrev;
struct_Uart_Buffer *pUart_Buffer=&Uart_Buffer[ndev];
if(ndev>=NumberOfUartDrv)
return;
while(serial_drv[ndev]->poll()){
//Receive data
*(pUart_Buffer->pUart_rev)=(U8)serial_drv[ndev]->read();
pUart_Buffer->pUart_rev++;
if(pUart_Buffer->pUart_rev==pUart_Buffer->Buffer+UART_REVBUFFER_SIZE)
pUart_Buffer->pUart_rev=pUart_Buffer->Buffer;
nrev=pUart_Buffer->pUart_rev-pUart_Buffer->pUart_read;
if(nrev<0)//循环缓冲区调整
nrev+=UART_REVBUFFER_SIZE;
}
if(nrev>=pUart_Buffer->nRev_Uart)
OSMboxPost(pUart_Buffer->Uart_Rev_mbox, (void*)nrev);
}*/
/*************************
读串口n的数据
返回值,实际读取的数据数目
****************************/
int OSReadUart(int ndev, U8 data[], int num, int ntimeout)
{
INT8U err;
int nrev, n, snum;
struct_Uart_Buffer *pUart_Buffer;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return 0;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
snum=num;
for(; num>0;num-=n){
OS_ENTER_CRITICAL();
//设置Uart接收数据数
n=min(num, UART_REVBUFFER_SIZE);
pUart_Buffer->nRev_Uart=n;
nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
OS_EXIT_CRITICAL();
while(nrev<n){
OSSemPend(pUart_Buffer->Uart_Rev_sem, ntimeout,&err);
if(err==OS_TIMEOUT){
goto end;
}
nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
}
OS_ENTER_CRITICAL();
RoundmemCpyFrom(data, pUart_Buffer->revBuffer,
pUart_Buffer->nUart_read, n, UART_REVBUFFER_SIZE);
OS_EXIT_CRITICAL();
data+=n;
}
// for(i=0;i<num;i++){
// data[i]=*(pUart_Buffer->revBuffer[pUart_Buffer->nUart_read]);
// RoundINC(pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
// }
end:
return snum-num;
}
/*************************
写串口n的数据
返回值,实际写入的数据数目
****************************/
int OSWriteUart(int ndev, U8 data[], int num, int ntimeout)
{
INT8U err;
int n;
struct_Uart_Buffer *pUart_Buffer;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return 0;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
OS_ENTER_CRITICAL();
n=RoundFreeCount(pUart_Buffer->nUart_write, pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
OS_EXIT_CRITICAL();
do{
if(n<num){
if(n>0){
OS_ENTER_CRITICAL();
RoundmemCpyTo(pUart_Buffer->sndBuffer, data, pUart_Buffer->nUart_write,
n, UART_SNDBUFFER_SIZE);
serial_drv[ndev]->write();
OS_EXIT_CRITICAL();
num-=n;
}
do{
OSSemPend(pUart_Buffer->Uart_Snd_sem, ntimeout,&err);
if(err==OS_TIMEOUT){
return num;
}
n=RoundFreeCount(pUart_Buffer->nUart_write,
pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
}while(n<=UART_SNDBUFFER_SIZE/2 && n<num);
}else{
OS_ENTER_CRITICAL();
RoundmemCpyTo(pUart_Buffer->sndBuffer, data, pUart_Buffer->nUart_write,
num, UART_SNDBUFFER_SIZE);
serial_drv[ndev]->write();
OS_EXIT_CRITICAL();
return 0;
}
}while(num);
return num;
}
/*************************
写串口n的数据
返回值,实际写入的数据数目
****************************/
int OSWritepollUart(int ndev, U8 data[], int num, int ntimeout)
{
for(; num>0; num--){
serial_drv[ndev]->writepoll(*data);
data++;
}
return 0;
}
//发送缓冲区清空
void Uart_FlushTxBuffer(int ndev)
{
struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
pUart_Buffer->nUart_send=pUart_Buffer->nUart_write=0;
serial_drv[ndev]->flush_output();
}
//接收缓冲区清空
void Uart_FlushRxBuffer(int ndev)
{
struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return;
#endif
pUart_Buffer=&Uart_Buffer[ndev];
pUart_Buffer->nUart_rev=pUart_Buffer->nUart_read=0;
serial_drv[ndev]->flush_input();
}
void OSInitUart(void)
{
int i;
for(i=0;i<NumberOfUartDrv;i++){
Uart_Buffer[i].nRev_Uart=1; //设定的Uart接收字符数
Uart_Buffer[i].nUart_rev=Uart_Buffer[i].nUart_read=0;
Uart_Buffer[i].nUart_send=Uart_Buffer[i].nUart_write=0;
Uart_Buffer[i].Uart_Rev_sem=OSSemCreate(0);
Uart_Buffer[i].Uart_Snd_sem=OSSemCreate(0);
Uart_Buffer[i].Uart_write = OSWritepollUart;
}
}
/*************************
开启串口n中断和缓冲模式
****************************/
int OpenUartRev(int ndev)
{
// struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
if(ndev>=NumberOfUartDrv)
return FAIL;
#endif
// pUart_Buffer=&Uart_Buffer[ndev];
Uart_Buffer[ndev].Uart_write = OSWriteUart;
serial_drv[ndev]->open();
// SetISR_Interrupt(serial_drv[ndev]->nIsr, (Interrupt_func_t)irq_OSRevUart, (void*)ndev);
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -