optical/NxBase/serial.c
2025-09-04 09:45:08 +08:00

462 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#define _IN_SERIAL_C
#include "serial.h"
#include "cpuid.h"
/*------------------------------------------------------------------------------------------*/
#ifndef MAX_STBUF1_SIZE
#define MAX_STBUF1_SIZE (128)
#endif
#ifndef MAX_SRBUF1_SIZE
#define MAX_SRBUF1_SIZE (128)
#endif
#ifndef MAX_STBUF2_SIZE
#define MAX_STBUF2_SIZE (128)
#endif
#ifndef MAX_SRBUF2_SIZE
#define MAX_SRBUF2_SIZE (128)
#endif
#ifndef MAX_STBUF3_SIZE
#define MAX_STBUF3_SIZE (128)
#endif
#ifndef MAX_SRBUF3_SIZE
#define MAX_SRBUF3_SIZE (128)
#endif
#ifndef MAX_STBUF4_SIZE
#define MAX_STBUF4_SIZE (128)
#endif
#ifndef MAX_SRBUF4_SIZE
#define MAX_SRBUF4_SIZE (128)
#endif
#ifndef MAX_STBUF5_SIZE
#define MAX_STBUF5_SIZE (128)
#endif
#ifndef MAX_SRBUF5_SIZE
#define MAX_SRBUF5_SIZE (128)
#endif
#ifndef MAX_STBUF6_SIZE
#define MAX_STBUF6_SIZE (128)
#endif
#ifndef MAX_SRBUF6_SIZE
#define MAX_SRBUF6_SIZE (128)
#endif
typedef struct
{
// 串口
u16 sEnFlag; // 有效标志 = 0x55aa结构有效
USART_TypeDef * USARTx;
BAUD_TypeDef baud;
// 缓冲区
int squeueLen; // 发送缓冲区长度
u8 * sendQueue; // 发送缓冲区
u8 * pSdQueueHead; // 发送队列头指针
u8 * pSdQueueTail; // 发送队列尾指针
u16 lenSdQueue; // 发送队列有效长度
u16 ctrlSdFlag; // 发送标志, TRUE, 串口正在发送; FALSE, 串口没有发送
int rqueueLen; // 接收缓冲区长度
u8 * rsevQueue; // 接收缓冲区
u8 * pRsQueueHead; // 接收队列头指针
u8 * pRsQueueTail; // 接收队列尾指针
u16 lenRsQueue; // 接收队列有效长度
u16 ctrlRsFlag; // 接收允许标志, TRUE, 允许串口接收; FALSE, 不允许串口接收
ResvExProc resvexproc; // 接收外部处理函数指针
}UsartCtrl;
#define FLAG_ENABLE 0x55AA
/*------------------------------------------------------------------------------------------*/
#define IsUsartRxneFlag(usart) LL_USART_IsActiveFlag_RXNE(usart)
#define IsUsartTxeFlag(usart) LL_USART_IsActiveFlag_TXE(usart)
#define IsUsartTcFlag(usart) LL_USART_IsActiveFlag_TC(usart)
#define EnableItReceive(usart) LL_USART_EnableIT_RXNE(usart)
#define DisableItReceive(usart) LL_USART_DisableIT_RXNE(usart)
#define EnableItTrans(usart) LL_USART_EnableIT_TXE(usart)
#define DisableItTrans(usart) LL_USART_DisableIT_TXE(usart)
#define ReceiveData LL_USART_ReceiveData8
#define TransmitData LL_USART_TransmitData8
/*------------------------------------------------------------------------------------------*/
// 中断处理宏,所有处理过程相同
#define INITUSART(usart) do \
{\
/* 使能接收中断 */ \
LL_USART_ReceiveData8(USART##usart); \
LL_USART_EnableIT_RXNE(USART##usart); \
\
/* 打开串口 */ \
LL_USART_Enable(USART##usart); \
} while (0)
/*------------------------------------------------------------------------------------------*/
#define USART_PROC(usart) \
\
u8 g_usart##usart##TBuff[MAX_STBUF##usart##_SIZE];\
u8 g_usart##usart##RBuff[MAX_SRBUF##usart##_SIZE];\
UsartCtrl g_uCtrl##usart; \
\
int InitUsart##usart(BAUD_TypeDef baud, char dat, char parity, char stop) \
{ \
/* 收发队列配置 */ \
memset(&g_uCtrl##usart, 0, sizeof(UsartCtrl)); \
g_uCtrl##usart.sendQueue = g_usart##usart##TBuff; \
g_uCtrl##usart.squeueLen = MAX_STBUF##usart##_SIZE; \
g_uCtrl##usart.rsevQueue = g_usart##usart##RBuff; \
g_uCtrl##usart.rqueueLen = MAX_SRBUF##usart##_SIZE; \
g_uCtrl##usart.USARTx = USART##usart; \
g_uCtrl##usart.baud = baud; \
\
g_uCtrl##usart.pSdQueueHead = &(g_uCtrl##usart.sendQueue[0]); \
g_uCtrl##usart.pSdQueueTail = g_uCtrl##usart.pSdQueueHead; \
g_uCtrl##usart.lenSdQueue = 0; \
g_uCtrl##usart.ctrlSdFlag = FALSE; \
\
g_uCtrl##usart.pRsQueueHead = &(g_uCtrl##usart.rsevQueue[0]); \
g_uCtrl##usart.pRsQueueTail = g_uCtrl##usart.pRsQueueHead; \
g_uCtrl##usart.lenRsQueue = 0; \
g_uCtrl##usart.ctrlRsFlag = TRUE; \
\
g_uCtrl##usart.sEnFlag = FLAG_ENABLE; \
g_uCtrl##usart.resvexproc = NULL; \
\
INITUSART(usart); \
return 0; \
} \
\
/*------------------------------------------------------------------------------------------*/ \
/* 功能:发送数据,将数据添加到发送队列中 */ \
/* 参数: pDatBuf发送数据缓冲区 */ \
/* len, 发送数据长度 */ \
/* 返回: >= 0, 实际发送数据 */ \
/* 返回: -1, 输入参数错误 */ \
/* -2, 串口没有初始化*/ \
/* -3, 接收缓冲区控制错误*/ \
int Usart##usart##SendData(u8 * pDatBuf, int len) \
{ \
int i; \
u8 * pSDat; \
\
if (pDatBuf == NULL || len < 0) \
{ \
return -1; \
} \
if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \
{ \
return -2; \
} \
\
/* 数据长度 */ \
EnterCritical(); \
if (g_uCtrl##usart.lenSdQueue+len > g_uCtrl##usart.squeueLen) \
{ \
len = 0; /*g_uCtrl##usart.squeueLen - g_uCtrl##usart.lenSdQueue;*/ \
} \
pSDat = g_uCtrl##usart.pSdQueueTail; \
ExitCritical(); \
\
if (len < 0) \
{ \
return -3; \
} \
/* 拷贝数据 */ \
for (i = 0; i < len; i++) \
{ \
*pSDat++ = *pDatBuf++; \
if (pSDat > &(g_uCtrl##usart.sendQueue[g_uCtrl##usart.squeueLen-1])) \
{ \
pSDat = &(g_uCtrl##usart.sendQueue[0]); \
} \
} \
/* 发送数据 */ \
if (len != 0) \
{ \
EnterCritical(); \
g_uCtrl##usart.pSdQueueTail = pSDat; \
g_uCtrl##usart.lenSdQueue += len; \
if (g_uCtrl##usart.ctrlSdFlag != TRUE && g_uCtrl##usart.lenSdQueue != 0) \
{ \
g_uCtrl##usart.ctrlSdFlag = TRUE; /* 设置标志 */ \
EnableItTrans(g_uCtrl##usart.USARTx); /* 打开中断,相当于启动传输 */ \
} \
ExitCritical(); \
} \
return len; \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 功能:接收数据,将数据从接收队列中取出 */ \
/* 参数: pDat存放缓冲区*/ \
/* expectLen希望得到数据的大小 */ \
/* 返回: >= 0实际得到数据的大小 */ \
/* -1, 输入参数错误*/ \
/* -2, 串口没有初始化*/ \
/* -3, 接收缓冲区控制错误*/ \
\
int Usart##usart##GetData(u8 * pDat, int expectLen) \
{ \
int i, len; \
u8 * pSDat; \
\
if (pDat == NULL || expectLen < 0) \
{ \
return -1; \
} \
\
if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \
{ \
return -2; \
} \
\
EnterCritical(); \
pSDat = g_uCtrl##usart.pRsQueueHead; \
len = g_uCtrl##usart.lenRsQueue; \
ExitCritical(); \
\
if (len < 0) \
{ \
return -3; \
} \
\
if (expectLen > len) /* 需要的数据大于串口中的数据 */ \
{ \
return 0; \
} \
\
/* 读取数据 */ \
for (i = 0; i < expectLen; i++) \
{ \
*pDat++ = *pSDat; \
pSDat++; \
if (pSDat > &(g_uCtrl##usart.rsevQueue[g_uCtrl##usart.rqueueLen-1])) \
{ \
pSDat = &(g_uCtrl##usart.rsevQueue[0]); \
} \
} \
\
EnterCritical(); \
g_uCtrl##usart.pRsQueueHead = pSDat; \
g_uCtrl##usart.lenRsQueue -= expectLen; \
ExitCritical(); \
\
return expectLen; \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 清空接收缓冲区 */ \
int Usart##usart##CleanRsBuf(void) \
{ \
int len; \
EnterCritical(); \
g_uCtrl##usart.pRsQueueHead = g_uCtrl##usart.pRsQueueTail; \
len = g_uCtrl##usart.lenRsQueue; \
g_uCtrl##usart.lenRsQueue = 0; \
ExitCritical(); \
return len; \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 得到接收数据的长度 */ \
int Usart##usart##GetRsLen(void) \
{ \
int len; \
EnterCritical(); \
len = g_uCtrl##usart.lenRsQueue; \
ExitCritical(); \
return len; \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 清空发送缓冲区 */ \
int Usart##usart##CleanSdBuf(void) \
{ \
int len; \
EnterCritical(); \
g_uCtrl##usart.pSdQueueHead = g_uCtrl##usart.pSdQueueTail; \
len = g_uCtrl##usart.lenSdQueue; \
g_uCtrl##usart.lenSdQueue = 0; \
ExitCritical(); \
return len; \
} \
\
/*------------------------------------------------------------------------------------------*/ \
/* 得到发送缓冲区空闲长度 */ \
int Usart##usart##GetSdFreeLen(void) \
{ \
int len; \
EnterCritical(); \
len = g_uCtrl##usart.squeueLen - g_uCtrl##usart.lenSdQueue; \
ExitCritical(); \
return len; \
} \
\
/*------------------------------------------------------------------------------------------*/ \
/* 判断发送缓冲区是否为空 */ \
int IsUsart##usart##SendBufEmpty(void) \
{ \
int len; \
EnterCritical(); \
len = g_uCtrl##usart.lenSdQueue; \
ExitCritical(); \
if (len != 0) \
{ \
return FALSE; \
} \
else \
{ \
return TRUE; \
} \
} \
/* 发送是否完成 */ \
int IsUsart##usart##SendOver(void) \
{ \
int flag; \
EnterCritical(); \
flag = g_uCtrl##usart.ctrlSdFlag; \
ExitCritical(); \
if (flag == TRUE) \
{ \
return FALSE; \
} \
else \
{ \
return TRUE; \
} \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 中断处理 */ \
void USART##usart##IntProc(void) \
{ \
u8 dat; \
if (IsUsartRxneFlag(g_uCtrl##usart.USARTx) != RESET) /* USART 接收中断 */ \
{ \
dat = ReceiveData(g_uCtrl##usart.USARTx); \
if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \
{ \
return; \
} \
if (g_uCtrl##usart.lenRsQueue < g_uCtrl##usart.rqueueLen) \
{ \
*(g_uCtrl##usart.pRsQueueTail) = dat; /* 放入队列中 */ \
g_uCtrl##usart.pRsQueueTail++; \
if (g_uCtrl##usart.pRsQueueTail > &(g_uCtrl##usart.rsevQueue[g_uCtrl##usart.rqueueLen-1])) \
{ \
g_uCtrl##usart.pRsQueueTail = &(g_uCtrl##usart.rsevQueue[0]); \
} \
g_uCtrl##usart.lenRsQueue++; /* 长度增加 */ \
} \
if (g_uCtrl##usart.resvexproc != NULL) \
{ \
g_uCtrl##usart.resvexproc(dat); \
} \
} \
if (IsUsartTxeFlag(g_uCtrl##usart.USARTx) != RESET) /* USART 发送中断 */ \
{ \
if (g_uCtrl##usart.sEnFlag != FLAG_ENABLE) \
{ \
DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \
return; \
} \
if (g_uCtrl##usart.lenSdQueue != 0) \
{ \
TransmitData(g_uCtrl##usart.USARTx, *(g_uCtrl##usart.pSdQueueHead)); /* 传输数据 */ \
g_uCtrl##usart.pSdQueueHead++; /* 指针后移 */ \
if (g_uCtrl##usart.pSdQueueHead > &(g_uCtrl##usart.sendQueue[g_uCtrl##usart.squeueLen-1])) \
{ \
g_uCtrl##usart.pSdQueueHead = &(g_uCtrl##usart.sendQueue[0]); \
} \
g_uCtrl##usart.lenSdQueue--; /* 长度减小 */ \
g_uCtrl##usart.ctrlSdFlag = TRUE; /* 设置标志 */ \
} \
else \
{ \
g_uCtrl##usart.ctrlSdFlag = FALSE; /* 设置标志 */ \
DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \
} \
} \
} \
/*------------------------------------------------------------------------------------------*/ \
/* 注册接收数据外部处理函数 */ \
void RegUsart##usart##ResvExFunc(ResvExProc proc) \
{ \
g_uCtrl##usart.resvexproc = proc; \
} \
\
/*------------------------------------------------------------------------------------------*/ \
/* USARTx同步发送数据 */ \
int Usart##usart##SendDataSync(u8 * pDatBuf, int len) \
{ \
DisableItTrans(g_uCtrl##usart.USARTx); /* 关闭中断 */ \
while(len != 0) \
{ \
while(IsUsartTcFlag(g_uCtrl##usart.USARTx) == RESET); \
TransmitData(g_uCtrl##usart.USARTx, *pDatBuf); \
pDatBuf++; \
len--; \
} \
return len; \
} \
\
/* USARTx同步接收数据 */ \
int Usart##usart##GetDataSync(u8 * pDat, int expectLen) \
{ \
int count = 0; \
DisableItReceive(g_uCtrl##usart.USARTx); /* 关闭中断 */ \
while(expectLen != 0) \
{ \
while(IsUsartTcFlag(g_uCtrl##usart.USARTx) == RESET); \
*pDat = ReceiveData(g_uCtrl##usart.USARTx); \
pDat++; \
expectLen--; \
count++; \
} \
return count; \
}\
/*------------------------------------------------------------------------------------------*/
#ifdef COMM_USART1
USART_PROC(1);
#endif
#ifdef COMM_USART2
USART_PROC(2);
#endif
#ifdef COMM_USART3
USART_PROC(3);
#endif
#ifdef COMM_USART4
USART_PROC(4);
#endif
#ifdef COMM_USART5
USART_PROC(5);
#endif
#ifdef COMM_USART6
USART_PROC(6);
#endif