Files
RS485_T1_Transition/Source/SYSTEM/uart.c
yeyangwen 13980737e3 feat:修改设备类型
feat:修改为红外转发设备,将中弘网关协议转换为主机红外协议
2026-02-09 17:32:59 +08:00

628 lines
18 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.
#include "includes.h"
#include <string.h>
#include <stdarg.h>
/**
* BLV_C8_PB 串口使用情况
* UART1 用与RCU进行双向通讯 115200 -> 对应设置 416
* UART0 用于PB数据发送没有接收 9600 -> 对应设置 5000
* */
UART_t g_uart[3];
U8_T DealBuffer[USART_BUFFER_SIZE] = {0}; //数据处理缓冲
U16_T DealLen = 0x00;
MULIT_t m_send;
void UARTx_Init(UART_IDX uart_id, Uart_prt prt_cf) {
switch(uart_id){
case UART_0:
UART0_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART0,0); //use PA0.1->RXD0, PA0.0->TXD0
// UARTInit(UART0,5000,UART_PAR_NONE); //baudrate=sysclock 48M/1000=4800
UARTInitRxTxIntEn(UART0,416,UART_PAR_NONE); //baudrate=sysclock 48M/1000=4800,tx rx int enabled
// UART0_Int_Enable();
memset(&g_uart[UART_0],0,sizeof(UART_t));
g_uart[UART_0].RecvTimeout = Recv_115200_TimeOut;
g_uart[UART_0].processing_cf = prt_cf;
break;
case UART_1:
UART1_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART1,2); //use PA0.13->RXD1, PB0.0->TXD1
// UARTInit(UART1,416,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200
UARTInitRxTxIntEn(UART1,5000,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200 tx rx int enabled
UART1_Int_Enable();
memset(&g_uart[UART_1],0,sizeof(UART_t));
g_uart[UART_1].RecvTimeout = Recv_9600_TimeOut;
g_uart[UART_1].processing_cf = prt_cf;
GPIO_Init(GPIOA0,13,Output);
GPIO_DriveStrength_EN(GPIOA0,13);
GPIO_Write_Low(GPIOA0,13);
break;
case UART_2:
memset(&g_uart[UART_2],0,sizeof(UART_t));
memset(&m_send,0,sizeof(MULIT_t));
m_send.HighBit_Flag = 0x01;
g_uart[UART_2].RecvTimeout = Recv_9600_TimeOut;
g_uart[UART_2].processing_cf = prt_cf;
//2025-03-29串口2的RX管脚外部中断用于通讯总线繁忙判断。
GPIO_PullHigh_Init(GPIOB0,5); //RX,PB0.5
GPIO_IntGroup_Set(PB0,5,Selete_EXI_PIN5); //EXI0 set PB0.2
GPIOB0_EXI_Init(EXI5); //PB0.2 as input
EXTI_trigger_CMD(ENABLE,EXI_PIN5,_EXIFT); //ENABLE falling edge下降沿触发
EXTI_trigger_CMD(ENABLE,EXI_PIN5,_EXIRT); //上升沿触发
EXTI_interrupt_CMD(ENABLE,EXI_PIN5); //enable EXI
GPIO_EXTI_interrupt(GPIOB0,0b0000000000100000); //enable GPIOB02 as EXI
EXI3_Int_Enable();
UART2_DeInit(); //clear all UART Register
UART_IO_Init(IO_UART2,2); //use PB0.4->RXD1, PB0.5->TXD1
//UARTInit(UART2,416,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200
UARTInitRxTxIntEn(UART2,5000,UART_PAR_NONE); //baudrate=sysclock 48M/416=115200 tx rx int enabled
UART2_Int_Enable();
GPIO_Init(GPIOB0,3,Output);
GPIO_DriveStrength_EN(GPIOB0,3);
GPIO_Write_Low(GPIOB0,3);
break;
}
}
/*******************************************************************************
* Function Name : UART0_RecvINT_Processing
* Description : 串口0 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART0_RecvINT_Processing(char data){
if((g_uart[UART_0].RecvLen + 1) >= USART_BUFFER_SIZE) g_uart[UART_0].RecvLen = 0;
g_uart[UART_0].RecvBuffer[g_uart[UART_0].RecvLen++] = (U8_T)data;
g_uart[UART_0].RecvIdleTiming = SysTick_1ms;
g_uart[UART_0].Receiving = 0x01;
}
void UART0_TASK(void){
if(g_uart[UART_0].Receiving == 0x01){
if(SysTick_1ms - g_uart[UART_0].RecvIdleTiming > g_uart[UART_0].RecvTimeout){
g_uart[UART_0].RecvIdleTiming = SysTick_1ms;
Dbg_Println(DBG_BIT_SYS_STATUS, "UART0 recv Len %d", g_uart[UART_0].RecvLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART0 buff",g_uart[UART_0].RecvBuffer,g_uart[UART_0].RecvLen);
if(g_uart[UART_0].processing_cf != NULL){
g_uart[UART_0].processing_cf(g_uart[UART_0].RecvBuffer,g_uart[UART_0].RecvLen);
}
g_uart[UART_0].RecvLen = 0;
g_uart[UART_0].Receiving = 0;
}
}
}
/*******************************************************************************
* Function Name : UART1_RecvINT_Processing
* Description : 串口1 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART1_RecvINT_Processing(char data){
if((g_uart[UART_1].RecvLen + 1) >= USART_BUFFER_SIZE) g_uart[UART_1].RecvLen = 0;
g_uart[UART_1].RecvBuffer[g_uart[UART_1].RecvLen++] = (U8_T)data;
g_uart[UART_1].RecvIdleTiming = SysTick_1ms;
g_uart[UART_1].Receiving = 0x01;
}
void UART1_TASK(void){
U8_T rev = 0xFF;
if(g_uart[UART_1].Receiving == 0x01){
if(SysTick_1ms - g_uart[UART_1].RecvIdleTiming > g_uart[UART_1].RecvTimeout){
SYSCON_Int_Disable(); //2025-03-19,复制接收缓冲到数据处理缓冲内
g_uart[UART_1].RecvIdleTiming = SysTick_1ms;
memcpy(DealBuffer,g_uart[UART_1].RecvBuffer,g_uart[UART_1].RecvLen);
DealLen = g_uart[UART_1].RecvLen;
g_uart[UART_1].RecvLen = 0;
g_uart[UART_1].Receiving = 0;
SYSCON_Int_Enable();
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS, "UART1 recv Len %d", DealLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART1 buff",DealBuffer,DealLen);
#endif
if(g_uart[UART_1].processing_cf != NULL){
rev = g_uart[UART_1].processing_cf(DealBuffer,DealLen);
}
memset(DealBuffer,0,USART_BUFFER_SIZE);
}
}
}
/*******************************************************************************
* Function Name : UART2_RecvINT_Processing
* Description : 串口2 接收中断处理函数 - 接收中断调用
*******************************************************************************/
void UART2_RecvINT_Processing(char data){
if((g_uart[UART_2].RecvLen + 1) >= USART_BUFFER_SIZE) g_uart[UART_2].RecvLen = 0;
g_uart[UART_2].RecvBuffer[g_uart[UART_2].RecvLen++] = (U8_T)data;
g_uart[UART_2].RecvIdleTiming = SysTick_1ms;
g_uart[UART_2].Receiving = 0x01;
}
void UART2_TASK(void){
U8_T rev = 0xFF;
if(g_uart[UART_2].Receiving == 0x01){
if(SysTick_1ms - g_uart[UART_2].RecvIdleTiming > g_uart[UART_2].RecvTimeout){
SYSCON_Int_Disable(); //2025-03-19,复制接收缓冲到数据处理缓冲内
g_uart[UART_2].RecvIdleTiming = SysTick_1ms;
memcpy(DealBuffer,g_uart[UART_2].RecvBuffer,g_uart[UART_2].RecvLen);
DealLen = g_uart[UART_2].RecvLen;
g_uart[UART_2].RecvLen = 0;
g_uart[UART_2].Receiving = 0;
SYSCON_Int_Enable();
#if DBG_LOG_EN
Dbg_Println(DBG_BIT_SYS_STATUS, "UART2 recv Len %d", DealLen);
Dbg_Print_Buff(DBG_BIT_SYS_STATUS,"UART2 buff",DealBuffer,DealLen);
#endif
if(g_uart[UART_2].processing_cf != NULL){
rev = g_uart[UART_2].processing_cf(DealBuffer,DealLen);
}
// /*Boot处理函数 */
// if(rev != 0x00)
// {
// Boot_Comm_UpgradeProcess(DealBuffer,DealLen);
// }
memset(DealBuffer,0,USART_BUFFER_SIZE);
}
}
}
/*因为开启了UART_TX_DONE_S 中断,发送完成需要清楚该中断标志位,因此每次调用串口输出后,需调用该函数,否则会在中断出不来
* 已取消
* */
void UART_Waiting_For_Send(CSP_UART_T *uart){
unsigned int Dataval = 0,delay_cnt = 0;
do{
Dataval = CSP_UART_GET_ISR(uart);
Dataval = Dataval & UART_TX_DONE_S;
delay_cnt ++;
if(delay_cnt >= 50000){
break;
}
}while(Dataval == 0x00); //发送完成
uart->ISR=UART_TX_DONE_S;
}
volatile int RS485_Comm_Flag = 0,RS485_Comm_Start = 0,RS485_Comm_End = 0,RS485_Comming = 0;
volatile int RS485_Comm_Flag1 = 0,RS485_Comm_Start1 = 0,RS485_Comm_End1 = 0,RS485_Comming1 = 0;
void MCU485_SendData(U8_T *buff,U16_T len){
unsigned int Dataval = 0,delay_cnt = 0;
//等待通讯发送完成
while(RS485_Comming == 0x01){
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
GPIO_Reverse(GPIOB0,3);
}
delay_nus(500);
CK_CPU_DisAllNormalIrq();
GPIO_Write_High(GPIOB0,3);
RS485_Comm_Flag = 0x01;
RS485_Comm_Start = 0x00;
RS485_Comm_End = 0x00;
CK_CPU_EnAllNormalIrq();
UARTTransmit(UART2,buff,len);
do{
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
}while((RS485_Comm_Start < len) || (RS485_Comm_End < len)); //发送完成
CK_CPU_DisAllNormalIrq();
GPIO_Write_Low(GPIOB0,3);
RS485_Comm_Flag = 0x00;
CK_CPU_EnAllNormalIrq();
}
//发送给设备端的485发送函数
void Controller485_SendData(U8_T *buff,U16_T len)
{
unsigned int Dataval = 0,delay_cnt = 0;
//等待通讯发送完成
while(RS485_Comming1 == 0x01){
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
GPIO_Reverse(GPIOA0,13);
}
delay_nus(500);
CK_CPU_DisAllNormalIrq();
GPIO_Write_High(GPIOA0,13);
RS485_Comm_Flag1 = 0x01;
RS485_Comm_Start1 = 0x00;
RS485_Comm_End1 = 0x00;
CK_CPU_EnAllNormalIrq();
UARTTransmit(UART1,buff,len);
do{
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
}while((RS485_Comm_Start1 < len) || (RS485_Comm_End1 < len)); //发送完成
CK_CPU_DisAllNormalIrq();
GPIO_Write_Low(GPIOA0,13);
RS485_Comm_Flag1 = 0x00;
CK_CPU_EnAllNormalIrq();
}
/**********************************************************
* @brief 带总线状态判断的485发送
* buff:发送数据
* len数据长度
* @retval
* */
U8_T BUS485_Send(U8_T *buff,U16_T len)
{
unsigned int Dataval = 0,delay_cnt = 0;
//等待通讯发送完成
while(RS485_Comming == 0x01){
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
GPIO_Reverse(GPIOB0,3);
}
if(m_send.BusState_Flag == UART_BUSIDLE){ //总线空闲
CK_CPU_DisAllNormalIrq();
GPIO_Write_High(GPIOB0,3);
RS485_Comm_Flag = 0x01;
RS485_Comm_Start = 0x00;
RS485_Comm_End = 0x00;
m_send.BusState_Flag = UART_BUSBUSY;//发送前总线置位繁忙
m_send.BUSBUSY_LOCK = 0x01; //锁定总线状态
CK_CPU_EnAllNormalIrq();
UARTTransmit(UART2,buff,len);
do{
delay_nus(100);
delay_cnt ++;
if(delay_cnt >= 100){
break;
}
}while((RS485_Comm_Start < len) || (RS485_Comm_End < len)); //发送完成
CK_CPU_DisAllNormalIrq();
GPIO_Write_Low(GPIOB0,3);
RS485_Comm_Flag = 0x00;
m_send.BusState_Tick = SysTick_1ms;
m_send.BUSBUSY_LOCK = 0x00; //解锁总线状态
CK_CPU_EnAllNormalIrq();
return UART_BUSIDLE; //发送成功
}
else //总线繁忙
{
return UART_BUSBUSY; //发送失败
}
return 0x02; //传入状态无效
}
/**********************************************************
* @brief 重发、数据有效期、超时发送判断2025-03-25
* buff:发送数据
* len数据长度
* DatSd发送标记,0x00:无发送0x01有数据发送
*
* @retval 0x00:发送成功 0x01:等待发送 0x02:数据无效
* */
U8_T MultSend_Task(U8_T *buff,U16_T len,U8_T DatSd)
{
if( (len == 0)||(len > USART_SEND_SIZE) ) return LEN_ERR;
if(DatSd == 0x01)
{
if( m_send.ResendCnt < m_send.TotalCnt) //判断数据是否还在有效期,是否还有发送次数
{
if(SysTick_1ms - m_send.BusbusyTimeout < m_send.DataValid_Time)
{
if( (m_send.ResendCnt == 0x00) || (SysTick_1ms - m_send.ASend_Tick >= m_send.DataWait_Time) ){//数据发送间隔
if(BUS485_Send(buff,len) == UART_BUSIDLE){ //发送数据
m_send.ASend_Tick = SysTick_1ms;
m_send.ResendCnt++;
Dbg_Println(DBG_BIT_SYS_STATUS,"SendCnt:%d success",m_send.ResendCnt);
return BUSSEND_SUCC;//数据发送成功
}
}
}else{
Dbg_Println(DBG_BIT_SYS_STATUS,"data end");
return DATA_END;//数据有效期结束
}
}else{
Dbg_Println(DBG_BIT_SYS_STATUS,"retry end,%d",m_send.ResendCnt );
return RETRY_END;//没有重发次数
}
}
return BUSSEND_WAIT;//等待
}
/**********************************************************
* @brief 设置发送标志、组包、选择数据有效期档位2025-03-25
* data: 发送数据
* sled 数据长度
* SCnt: 设置数据发送次数
* indate 设置数据有效期
* tim_val: 发送时间间隔
* @retval None
* */
void Set_GroupSend(U8_T *data,U16_T sled,U8_T SCnt,U32_T indate,U32_T tim_val)
{
if((sled == 0x00)|| (sled > USART_SEND_SIZE)) return;
memset(m_send.SendBuffer,0, USART_SEND_SIZE);
memcpy(m_send.SendBuffer,data,sled);
m_send.SendLen = sled;
m_send.DataValid_Time = indate;//数据有效期
m_send.TotalCnt = SCnt; //数据发送次数
m_send.DataWait_Time = tim_val;//发送数据间隔
m_send.ASend_Flag = 0x01;
m_send.SendState = BUSSEND_WAIT;
m_send.ResendCnt = 0x00;
m_send.BusbusyTimeout = SysTick_1ms;
}
//清除发送标志
void Clear_SendFlag(void)
{
m_send.ASend_Flag = 0x00;
m_send.SendState = BUSSEND_SUCC;
}
void BUS485_Jump_Boot(U8_T jump)
{
m_send.Jump_Flag = jump;
}
//485发送任务
void BUS485Send_Task(void) //2025-03-29
{
//空闲等待
if(m_send.ASend_Flag == 0x01)
{
m_send.SendState = MultSend_Task(m_send.SendBuffer,m_send.SendLen,m_send.ASend_Flag);
if( (m_send.SendState == DATA_END)||(m_send.SendState == RETRY_END) )//判断发送数据是否有效
{
Dbg_Println(DBG_BIT_SYS_STATUS,"send end");
m_send.ASend_Flag = 0x00; //清除发生标志位
/*设置波特率*/
// if( m_send.SetBaudFlag == 0x01 ){
//
// UARTx_ChangeBaud(UART_2,m_send.SetBaud);
// m_send.SetBaudFlag = 0x00;
// m_send.SetBaud = 0x00;
// }
// if(m_send.Jump_Flag == 0x01){
// Dbg_Println(DBG_BIT_Debug_STATUS,"Jump Boot");
//
// SYSCON->UREG3 = g_boot.bootTimeout; //向Boot 设定Boot超时时间
// SYSCON_Software_Reset();
// }
}
}
}
//获取当前BUS485 发生状态,获取完状态后清除当前状态
U8_T Get_BUS485_Send_State(void)
{
U8_T rev_state = 0x0F;
if(m_send.ASend_Flag == 0x01){
rev_state |= 0x80;
}
rev_state |= (m_send.SendState & 0x0F);
return rev_state;
}
/**********************************************************
* @brief 2025-03-25检测总线空闲在定时器中断里调用
* @retval None
* */
void BusIdle_Task(void)
{
if((m_send.BusState_Flag != UART_BUSIDLE)&&(m_send.BUSBUSY_LOCK != 0x01))
{
CK_CPU_DisAllNormalIrq();
if( (m_send.HighBit_Flag == 0x01)&&(SysTick_1ms - m_send.BusState_Tick >= (6 + m_send.Bus_DelayTime)) )
{
m_send.BusState_Flag = UART_BUSIDLE;
}
CK_CPU_EnAllNormalIrq();
}
}
/*******************************************************************
* @brief 检测总线繁忙在串口接收RX引脚的外部中断服务函数里调用
* @retval None
* */
void BusBusy_Task(void)
{
CK_CPU_DisAllNormalIrq();
m_send.BusState_Flag = UART_BUSBUSY;
m_send.BusState_Tick = SysTick_1ms;
m_send.Bus_DelayTime = (SysTick_1ms - m_send.ASend_Tick)%10;//随机延时
if(READ_RXLEVEL_STATE == 0x01){
m_send.HighBit_Flag = 0x01; //高电平标志置位
}else if(READ_RXLEVEL_STATE == 0x00){
m_send.HighBit_Flag = 0x00; //低电平
}
CK_CPU_EnAllNormalIrq();
}
/*调试信息输出接口*/
U32_T Dbg_Switch = (DBG_OPT_Debug_STATUS << DBG_BIT_Debug_STATUS)
+ (DBG_OPT_DEVICE_STATUS << DBG_BIT_DEVICE_STATUS)
+ (DBG_OPT_SYS_STATUS << DBG_BIT_SYS_STATUS);
#if DBG_LOG_EN
char Dbg_Buffer[128] = {0};
U32_T SysTick_Now = 0, SysTick_Last = 0, SysTick_Diff = 0;
#endif
void Dbg_Print(int DbgOptBit, const char *cmd, ...){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer),"%8d [%6d]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
va_list args; //定义一个va_list类型的变量用来储存单个参数
va_start(args, cmd); //使args指向可变参数的第一个参数
str_offset = vsnprintf(Dbg_Buffer, sizeof(Dbg_Buffer) ,cmd, args); //必须用vprintf等带V的
va_end(args); //结束可变参数的获取
DBG_Printf(Dbg_Buffer,str_offset);
}
#endif
}
void Dbg_Println(int DbgOptBit, const char *cmd, ...){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%8ld [%6ld]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
va_list args; //定义一个va_list类型的变量用来储存单个参数
va_start(args, cmd); //使args指向可变参数的第一个参数
str_offset = vsnprintf(Dbg_Buffer, sizeof(Dbg_Buffer) ,cmd, args); //必须用vprintf等带V的
va_end(args); //结束可变参数的获取
DBG_Printf(Dbg_Buffer,str_offset);
DBG_Printf("\r\n",2);
}
#endif
}
void Dbg_Print_Buff(int DbgOptBit, const char *cmd, U8_T *buff,U16_T len){
#if DBG_LOG_EN
U16_T str_offset = 0;
if (Dbg_Switch & (1 << DbgOptBit)) {
SysTick_Now = SysTick_1ms;
SysTick_Diff = SysTick_Now - SysTick_Last; //上一次打印时间差
SysTick_Last = SysTick_Now;
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%8ld [%6ld]: ", SysTick_Now, SysTick_Diff);
DBG_Printf(Dbg_Buffer,str_offset);
for (uint32_t i = 0; i < len; i++) {
str_offset = snprintf(Dbg_Buffer, sizeof(Dbg_Buffer) , "%02X ", buff[i]);
DBG_Printf(Dbg_Buffer,str_offset);
}
DBG_Printf("\r\n",2);
}
#endif
}