/* ****************************************************************************** * * @file uart.c * @brief uart module * * * @version 1.0 * @date 2022/12/14 15:00:40 * @author Alex Xu * * Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd. * All Rights Reserved * * History: * Revision Date Author Desc * 1.0.0 2022/12/14 Alex build this file ******************************************************************************/ /*_____ I N C L U D E S ____________________________________________________*/ #include "uart.h" #include "system.h" #include "vox_module.h" #include "sleep.h" #if UART0_ENABLE /******************************************************************************\ Macro definitions \******************************************************************************/ #define NONE_PARITY 0 //无校验 #define ODD_PARITY 1 //奇校验 #define EVEN_PARITY 2 //偶校验 #define MARK_PARITY 3 //标记校验 #define SPACE_PARITY 4 //空白校验 #define PARITYBIT EVEN_PARITY //定义校验位 /******************************************************************************\ Variables definitions \******************************************************************************/ bit busy0; idata uint8_t RX0_Buffer[COM0_Data_Lenth] = 0; //接收缓冲 bit Uart0_RX_Finish_Flag = 0; #endif #ifdef _DEBUG_ALL char putchar(char c) { while(!TI0); TI0 = 0; return (S0BUF = c); } #endif #if UART0_ENABLE /* ******************************************************************************* * void Uart0SendPacket(uint8_t Length,uint8_t *TransBuf) * * Description : UART0 Send Packet * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ #ifdef VOX_TX void Uart0SendPacket(uint8_t Length,uint8_t *TransBuf) { uint8_t i = 0; for(i=0;i 0; --j ) { crc = (crc >> 1) ^ (0xEDB88320 & (-(crc & 1))); } i++; } return crc ^ 0xffffffff; } #endif /* ******************************************************************************* * void HandleTxCommand(VOX_BES_COMMAND_E RxCommand, e_Vox_Chan nVox_Chn_Select) * * Description : 发送数据包的封装,并打开相应的双向通信通道 * Command payload * Header checksum side cmd len Data * 1bytes 1byte 1byte 1byte 1byte Len bytes * * Arguments : VOX_BES_COMMAND_E TxCommand: , e_Vox_Chan nVox_Chn_Select * Returns : * * Notes : * ******************************************************************************* */ void HandleTxCommand(VOX_FAC_COMMAND_E TxCommand) { uint8_t tx_pData[11] = 0; uint8_t i = 0; /*数据包头*/ tx_pData[0] = BOX_FAC_HEADER; /*指令编号*/ tx_pData[2] = TxCommand; switch(TxCommand) { case CMD_FAC_START: break; case CMD_FAC_HALL: break; case CMD_FAC_GUAGE: break; case CMD_FAC_LED: break; case CMD_FAC_SHUTDOWN: break; case CMD_FAC_GET_DAUGE: break; case CMD_FAC_GET_NTC: break; case CMD_FAC_GET_FWVER: break; case CMD_FAC_SET_VOX_5V: break; default: break; } SFRADDR = MFP_CTL0; SFRDATA |= 0x04; //P01 as UART's TX #if UART0_ENABLE Uart0SendPacket(tx_pData[4] + 6, tx_pData); //+6的原因:多加一个字节发送,后面要设置TX为GPIO,会导致最后一个字节没来得及发出去。 #endif SFRADDR = MFP_CTL0; //Set P01 Pinmux As GPIO Function,原因:TX和RX连在一起,要保证RX能正常接收到数据,TX需设置为GPIO模式,并浮空或输入模式。 SFRDATA &= ~0x0C; } #endif #ifdef VOX_RX /* ******************************************************************************* * void HandleRxCommand(ACK_TYPE_E RxCommand) * * Description : 耳机端发送的数据包的解析及处理 * Ack payload: * Header checksum side cmd len Data * 1bytes 1byte 1byte 1byte 1byte Len bytes * * Arguments : ACK_TYPE_E RxCommand: * Returns : * * Notes : * ******************************************************************************* */ void HandleRxMsg(VOX_FAC_COMMAND_E RxCommand) { uint8_t i = 0; switch(RxCommand) { case CMD_FAC_START: break; case CMD_FAC_HALL: break; case CMD_FAC_GUAGE: break; case CMD_FAC_LED: break; case CMD_FAC_SHUTDOWN: break; case CMD_FAC_GET_DAUGE: break; case CMD_FAC_GET_NTC: break; case CMD_FAC_GET_FWVER: break; case CMD_FAC_SET_VOX_5V: break; default: break; } } /* ******************************************************************************* * void HandleVoxCommMsg(void) * * Description : Vox 通讯功能处理函数,100ms定时调用。由于和耳机通信前需要打开耳机端的TRX功能,并且每次通信只能一只耳机。通过切换VOL/VOR通信开关进行通信 * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void HandleVoxCommMsg(void) { uint8_t CrcCheckSum = 0; uint8_t i = 0; /*RX数据处理*/ if( Uart0_RX_Finish_Flag ) { Uart0_RX_Finish_Flag = 0; if( CrcCheckSum == RX0_Buffer[1] ) { HandleRxMsg((VOX_FAC_COMMAND_E)RX0_Buffer[2]); } else { return; } } } #endif #define Vox_Comm_Data_Len 5 #define Vox_R_W_FLAG 4 /*uart0中断处理函数*/ void uart0_Interrupt(void) interrupt Interrupt_Vector_RI_TI { static uint8_t Rx0Status; static uint8_t RX0_Cnt; static uint8_t RX0DataLen; /*处理UART0发送中断*/ if(TI0) { TI0 = 0; busy0 = 0; } /*处理UART0接收中断*/ if(RI0) { RI0 = 0; #if SLEEP_ENABLE Enter_Sleep_Cnt_Restart_Flag = 1; #endif #ifdef VOX_RX switch(Rx0Status) { case 0: if( S0BUF == 0x04 ) { Rx0Status = 1; RX0_Buffer[0] = S0BUF; } else { Rx0Status = 0; RX0_Cnt = 0; } break; case 1: if( S0BUF == 0xFB ) { Rx0Status = 2; RX0_Cnt = 1; RX0_Buffer[RX0_Cnt] = S0BUF; RX0_Cnt++; } else { Rx0Status = 0; RX0_Cnt = 0; } break; case 2: RX0_Buffer[RX0_Cnt] = S0BUF; RX0_Cnt++; if( (RX0_Buffer[3] == 1) || (RX0_Buffer[4] == 0) ) //读操作或写数据长度为0,则不带4字节CRC校验和 { RX0_Cnt = 0; Rx0Status = 0; Uart0_RX_Finish_Flag = 1; break; } if( RX0_Cnt == Vox_Comm_Data_Len ) { RX0DataLen = RX0_Buffer[4] + 9; //获取数据长度:Header(2Bytes) + CMD(1Bytes) + W Flag(1Bytes) + Datalen(1Bytes) + Data + CRC(4Bytes) } if( (RX0DataLen == RX0_Cnt) || (RX0_Cnt > COM0_Data_Lenth) ) //当接收到的data个数等于RX0DataLen,这结束本次传输。 { RX0_Cnt = 0; Rx0Status = 0; Uart0_RX_Finish_Flag = 1; } } #endif } } #endif