/********************************************************************************

 **** Copyright (C), 2019, Fortior Technology Co., Ltd.                      ****

 ********************************************************************************
    File Name     : UART.c
    Author        : Bruce HW&RD
    Date          : 2019-09-11
    Description   : .C file function description
    Version       : 1.0
    Function List :

    Record        :
    1.Date        : 2019-09-11
     Author      : Bruce HW&RD
     Modification: Created file

********************************************************************************/
#include "FU68xx_5.h"
#include <Myproject.h>

//MCUART   xdata  Uart;
ddatet1  xdata  DATA1;
DATE_HUI xdata  DATA2_Hui;

uint8   FaultCommuMonCt = 0;

extern int8 xdata UART1_RX_flag;
extern int8 xdata UART1_TX_flag;
extern int8 xdata  UART1_Rec_S;
extern int8 UART1_rx_rat_time, UART1_rx_count;
extern uint8 xdata UART1_In_L, UART1_In_H;    //
extern int8  xdata UART1_Rx_dat[12];//Á¬ÊÕ8×Ö½Ú

void UART2_Init(void)
{
    uint16  bps = 0;
    #if (Uart_COMMUNICATION==0)
    {
        bps = 1200;
    }
    #elif (Uart_COMMUNICATION==1)
    {
        bps = 9600;
    }
    #endif
    SetBit(PH_SEL, UART2EN);
    /*  UART模式 UT2_MOD1,UT2_MOD0为:
        00  模式0，移位寄存器波特率为 系统时钟 /12
        01  模式1，8-bit UART 波特率为 fcpu_clk / ( (16 / (1+ UT2_BAUD[BAUD2_SEL]) ) / (UT2_BAUD+1) )
        10  模式2，9-bit UART 波特率为 fcpu_clk / ( 32 – 16* UT2_BAUD[BAUD2_SEL])
        11  模式3，9-bit UART 波特率为 fcpu_clk / ( (16 / (1+ UT2_BAUD[BAUD2_SEL])) / (UT2_BAUD+1) )   */
    UT2MOD1 = 0;                // 9位模式    01
    UT2MOD0 = 1;
    /* Does not allow multi-thread cpu operation */
    /* UT2_SM2 为 0 - 单机通讯为 1 - 多机通讯 */
    UT2SM2 = 0;
    /* UT2_REN 为 0 - 禁止接收为 1 - 使能接收 */
    UT2REN = 1;
    UT2RI = 0;
    /* Uart2设置中断优先级 */
    SetBit(IP3, PSPI_UT21);
    ClrBit(IP3, PSPI_UT20);
    // UART2CH1, UART2CH0
    // 00：P3.6 为 RXD、P3.7 为 TXD（P3.6 为单线模式的输入输出）
    // 01：P4.7 为 RXD、P1.2 为 TXD（P1.2 为单线模式的输入输出）
    // 1X：P0.1 为 RXD、P0.0 为 TXD（P0.1 为单线模式的输入输出）
    ClrBit(PH_SEL1, UART2CH1);
    ClrBit(PH_SEL1, UART2CH0);
    // 设置波特率 根据 fcpu_clk / ( (16 / (1+ UT2_BAUD[BAUD2_SEL]) ) / (UT2_BAUD+1) )计算
    UT2_BAUD = 0;
    //    if (bps > 600)
    {
        UT2_BAUD |= 1500000 / bps - 1;
    }
    //    else
    //    {
    //        SetBit(UT2_BAUD,BAUD2_SEL);
    //
    //        UT2_BAUD |= 750000 / bps - 1;
    //    }
    /* Enable UART2 interrupt */
    SetBit(UT2_BAUD, UART2IEN);
}

void UART1_Init(void)
{
    #if (Debugg==1)
    {
        /*工具程序*/
        /*工具*/
        SetBit(PH_SEL, UART1EN);     //p0[6]as UART_RXD; p0[5]as UART_TXD
        UT_MOD1 = 0;
        UT_MOD0 = 1;                //8bit?????UART??
        SM2 = 0;                    //??Mode2?Mode3????
        REN = 1;                    //????
        ES0 = 0;                    //????
        SetBit(IP3, PI2C_UT11);
        ClrBit(IP3, PI2C_UT10);    // 中断优先级别3
        //                  SetBit(UT_BAUD , UART_2xBAUD);  //????0-->Disable  1-->Enable
        UT_BAUD = 0x9B;             //default baudrate:9600-0x9b,1200-0x4E1  00  150000      1D =50000
        ES0 = 1;                    //??/??????
        
    }
    #else
    {
        //    /*自己串口*/
        SetBit(PH_SEL, UART1EN);     //p0[6]as UART_RXD; p0[5]as UART_TXD
        UT_MOD1 = 0;
        UT_MOD0 = 1;                //8bit?????UART??
        SM2 = 0;                    //??Mode2?Mode3????
        REN = 1;                    //????
        ES0 = 0;                    //????
        ClrBit(IP3, PI2C_UT11);
        ClrBit(IP3, PI2C_UT10);    // 中断优先级别3
        SetBit(UT_BAUD, UART_2xBAUD);   //????0-->Disable  1-->Enable
        UT_BAUD = 0x00;             //default baudrate:9600-0x9b,1200-0x4E1  00  150000      1D =50000
        ES0 = 0;                    //??/??????
    }
    #endif
}

char putchar(char c)
{
    UT_DR = c;
    
    while (TI == 0) {}; TI = 0;
    
    return c;
}

/*  P是PSW程序状态字的一个位，表示奇偶校验位：它用来表示ALU运算结果中二进制数位“1”的个数的奇偶性。
    若为奇数，则P=1，否则为0。 运算结果有奇数个1，P＝1；运算结果有偶数个1，P＝0。*/
//奇校验（odd parity）：让传输的数据（包含校验位）中1的个数为奇数。
//偶校验（even parity）：让传输的数据（包含校验位）中1的个数为偶数。


//  Buf  校验的数据  o_or_e   奇偶方式选择

uint8 even_or_odd(uint8 Buf, uint8 o_or_e)
{
    uint8  even_odd = 0, tmpP = 0;
    ACC  = Buf;
    tmpP = P;
    
    if (o_or_e == 0)      //偶校验
    {
        even_odd = (tmpP == 1) ? 1 : 0;
    }
    else                 //奇校验
    {
        even_odd = (tmpP == 1) ? 0 : 1;
    }
    
    return even_odd;
}

#if (Uart_Select==Uart_MoNi)

/*数据接收函数*/
void UartRecive(void)
{
    Uart.UartReadTemp = RX_BUF ;      // 读接收数据
    Uart.R_DATA[Uart.UartReadCnt++] = Uart.UartReadTemp;
}

/*数据发送函数*/
void UartSend(void)
{
    if (Uart.TxCnt < (TX_LEN1 - 1))
    {
        Uart.TxCnt++;
        TX_BUF = Uart.T_DATA[Uart.TxCnt];
    }
    else
    {
        Uart.TxCnt = 0;
        Uart.sendflag = 0;
    }
}


/*串口数据处理，处理接收到的串口数据，运行于大循环中*/
void UartDealResponse(void)
{
    uint8 i;
    Uart_Check();//判断接收的数据是否正确
    
    if (Uart.sussf_falg == 1) //数据接收正确且成功
    {
        Uart.ResponseFlag = 1; //发送延时计时标志位
        Uart.UartReadCnt = 0;
        Uart.time_shuju = 0;
        mcFaultDect.commu_time = 0;
        /*提取并转换串口接收数据*/
        /*压机速度获取*/
        DATA1.DATA12 = Uart.R_DATA[1];
        
        if (DATA1.bf.DATA1_0 == 1)
        {
            Uart.YaJI_Speed          = (uint16) Uart.R_DATA[2] * 60;
            
            if (Uart.R_DATA[2] == 0)
            {
                Uart.YaJI_Speed         = 0;
            }
        }
        else
        {
            Uart.YaJI_Speed  = 0;
        }
        
        ConTrolCmd.yajispeed = Uart.YaJI_Speed;
        
        /*4通阀控制*/
        if (DATA1.bf.DATA1_1 == 1)
        {
            ConTrolCmd.sitongfa = 1;
        }
        else//4通阀关闭
        {
            ConTrolCmd.sitongfa = 0;
        }
        
        /*风机速度获取*/
        if (DATA1.bf.DATA1_2 == 1) //室外风机
        {
            Uart.FengSpeed      = (uint16)Uart.R_DATA[3] * 10;
        }
        else
        {
            Uart.FengSpeed      = 0;
        }
        
        ConTrolCmd.fengjispeed = Uart.FengSpeed;
        
        /*电子膨胀阀开度获取*/
        if (DATA1.bf.DATA1_6 == 1) //电子膨胀阀
        {
            Uart.PengZhangFa    = Uart.R_DATA[4] + 256;
        }
        else
        {
            Uart.PengZhangFa    = Uart.R_DATA[4];
        }
        
        ConTrolCmd.dianzifakaidu = Uart.PengZhangFa;
        
        /*回传数据*/
        for (i = 0; i <= TX_LEN1; i++) //赋值之前先清零
        {
            Uart.T_DATA[i] = 0;
        }
        
        DATA2_Hui.DATA_HUI = 0; //先清零
        
        if (isCtrlPowOn)
        {
            DATA2_Hui.bf.DATA2_0 = 1;
        }
        
        if (ConTrolCmd.sitongfa == 1)
        {
            DATA2_Hui.bf.DATA2_1 = 1;
        }
        
        if ( Uart.FengSpeed)
        {
            DATA2_Hui.bf.DATA2_2 = 1;
        }
        
        cumfault_6();
        Uart.T_DATA[0]  =  TX_ZHENTOU1;
        Uart.T_DATA[1]  =  DATA2_Hui.DATA_HUI;
        Uart.T_DATA[3]  =  0;                                                                   //风机转速
        Uart.T_DATA[4]  =  Uart.PengZhangFa_ACT ;                                              //电子膨胀阀开度
        Uart.T_DATA[5]  =  (uint8)(Huan_temp / 5 + 100);
        Uart.T_DATA[6]  =  (uint8)(Guan_temp / 5 + 100);
        Uart.T_DATA[7]  =  (uint8)(Paiqi_temp / 10 + 50);
        Uart.T_DATA[8]  =  0x00 ;                                                                //预留
        Uart.T_DATA[9]  =  FaultCommuMonCt ;                                                      //预留
        Uart.T_DATA[10] =  checkAdd1(Uart.T_DATA, 0, TX_LEN1 - 1);
        Uart.TxCnt = 0;
        Uart.sussf_falg = 0;
    }
    
    if ((Uart.time_cnt > 500 || Uart.time_shuju > 2000) && Uart.sendflag == 0) //16s内读取不到数据清零或2s内校验不成功
    {
        Uart.UartReadCnt = 0;
        Uart.time_shuju = 0;
        
        for (i = 0; i < RX_LEN1; i++)
        {
            Uart.R_DATA[i] = 0;
        }
        
        UART1_RX_flag = 0;
        UART1_TX_flag = 0;
        UART1_Rec_S = 0;
        UART1_rx_count = 0;
        UART1_rx_rat_time = 0;
        UART1_In_L = 0;
        UART1_In_H = 0;
        RX_BUF = 0;
        
        for (i = 0; i < 11; i++)
        {
            UART1_Rx_dat[i] = 0;
        }
    }
    
    if (Uart.send_delay_time >= 160) //延时160ms发送
    {
        TX_BUF = Uart.T_DATA[0];
        Uart.sendflag = 1;
        Uart.TxCnt = 0;
        Uart.send_delay_time = 0;
        Uart.ResponseFlag = 0;
    }
}

/*SUM1求和检验*/
uint8 checkAdd1(uint8 * chCheckAdrr, uint8 chStartAddr, uint8 iCheckCnt)
{
    uint8 i;
    uint8 iCheckResult = 0;
    chCheckAdrr += chStartAddr;
    
    for (i = 0; i < iCheckCnt; i++)
    {
        iCheckResult += *chCheckAdrr;
        chCheckAdrr++;
    }
    
    iCheckResult &= 0xff;
    return (iCheckResult);
}


/*SUM2求和检验*/
uint8 checkAdd2(uint8 * chCheckAdrr, uint8 chStartAddr, uint8 iCheckCnt)
{
    uint8 i;
    uint8 iCheckResult = 0;
    chCheckAdrr += chStartAddr;
    
    for (i = 0; i < iCheckCnt; i++)
    {
        iCheckResult += *chCheckAdrr;
        chCheckAdrr++;
    }
    
    iCheckResult &= 0xff;
    return (iCheckResult);
}

void Uart_Check(void)
{
    uint8 i = 0;
    
    if (Uart.R_DATA[0] != RX_ZHENTOU1) //针头错误清零
    {
        UART1_RX_flag = 0;
        UART1_TX_flag = 0;
        Uart.UartReadCnt = 0;
        
        for (i = 0; i < RX_LEN1; i++)
        {
            Uart.R_DATA[i] = 0;
        }
    }
    
    if (Uart.UartReadCnt >= RX_LEN1)
    {
        Uart.UartReadCnt = 0;
        
        if ((Uart.R_DATA[0] == RX_ZHENTOU1) && (checkAdd2(Uart.R_DATA, 0, (RX_LEN1 - 1)) == Uart.R_DATA[RX_LEN1 - 1])) //将读取的正确数据转换为所用数据,并将所需数据给Uart.T_DATA赋值
        {
            Uart.sussf_falg = 1;
        }
        
        if ((Uart.R_DATA[0] != RX_ZHENTOU1) || (checkAdd2(Uart.R_DATA, 0, RX_LEN1 - 1) != Uart.R_DATA[RX_LEN1 - 1])) //检验不对清零
        {
            Uart.sussf_falg = 0;
            UART1_RX_flag = 0;
            UART1_TX_flag = 0;
            Uart.UartReadCnt = 0;
            
            for (i = 0; i < RX_LEN1; i++)
            {
                Uart.R_DATA[i] = 0;
            }
        }
    }
}

void cumfault_6(void)
{
    if (((mcFaultSource == FaultHardOVCurrent) || (mcFaultSource == FaultSoftOVCurrent)) && (mcProtectTime.CurrentPretectTimes >= CurrentProtectRestartTimes))
    {
        FaultCommuMonCt = 4;
    }
    else if ((mcFaultSource == FaultLossPhase) && (mcProtectTime.LossPHTimes >= PhaseProtectRestartTimes))
    {
        FaultCommuMonCt = 3;
    }
    else if ((mcFaultSource == FaultStall) && (mcProtectTime.StallTimes >= StallProtectRestartTimes))
    {
        FaultCommuMonCt = 3;
    }
    else if ((mcFaultSource == FaultIbusOffset) && (mcProtectTime.IbusOffsetProtectTimes >= IbusOffsetRestartTimes))
    {
        FaultCommuMonCt = 4;
    }
    else if (mcFaultSource == FaultIpmTemp)
    {
        FaultCommuMonCt = 27;
    }
    else if (mcFaultSource == FaultUnderVoltage)
    {
        FaultCommuMonCt = 2;
    }
    else if (mcFaultSource == FaultOverVoltage)
    {
        FaultCommuMonCt = 1;
    }
    else if (mcFaultSource == FaultGuanTempSensor)
    {
        FaultCommuMonCt = 19;
    }
    else if (mcFaultSource == FaultHuanTempSensor)
    {
        FaultCommuMonCt = 20;
    }
    else
    {
        FaultCommuMonCt = 0;
    }
}

#endif

