
#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


