#define DTU3LITE #define ZEROEXPORT #define ARW #include #include #include #include #include #include #include "rtc.h" #include "SysTick.h" #include "usart_nrf.h" #include "Memory.h" #include #include "malloc.h" #include "TimeProcessing.h" #ifdef DTU3PRO #ifdef DTU_IAP #include "iwdg.h" #endif #else #include "stm32_wdg.h" #endif uint32_t Index_Pro; uint32_t TotalIndex_Pro; uint16_t TotalIndex_Dat; uint16_t Index_Dat; uint8_t PakageOne[(MAX_PRO_PACKAGE_ROW)]; uint8_t Uart_SendBuffer[UART_LEN]; //Send buffer uint8_t Uart_ProcessBuffer[UART_LEN]; //Process buffer uint8_t Uart_CurSendMainCmd = 0; //The current network command sends the main command uint16_t Uart_CurSendSubCmd = 0; //The current network command sends the command uint8_t Uart_CurRecMainCmd = 0; //Receipt main command of current network command uint16_t Uart_CurRecSubCmd = 0; //Receipt subcommand of current network command uint8_t Uart_CurrentReplyState = 0; //current receipt state uint8_t Uart_CurSendAddr[4]; uint8_t Uart_CurrentReplyAddr[4]; //Download receipt address uint8_t Uart_ReceiveBufferLen = 0; //Currently received bytes uint8_t Uart_SendBufferLen = 0; //Currently send bytes BaudType Uart_CurrentDtuBaud = Device_INIT_BAUD; //Current DTU air baud rate uint32_t DailyEnergyTemp[PORT_LEN] = {0}; InverterMajor MIMajor[PORT_LEN]; //;Inverter main information InverterReal MIReal[PORT_LEN]; //Inverter real-time data InverterDetail MIDetail; //Micro Inverter Details DtuMajor Dtu3Major; //DTU main information DtuDetail Dtu3Detail; //DTU details bool IsPolling = false; //Is it polling status bool RightHexFile = false; //Whether it is hex file stealing bool RightHexLastLine = false; bool nRFHasCheck = false; bool HasTempRegister = false; char string[512]; //External ram/flash reads micro-inverse program code char *TestGridOnFile; NetCmdType CurNetCmd = NET_INIT; uint16_t PortNO = 0; //Number of nth components uint8_t MainCmd; //Network command main command uint16_t SubCmd = 0xa5a5; //Network command subcommand uint32_t LocalTime_300Ms; extern u8 connect_server; //Connect to the server flag const char pro_start0[] = {'\r', '\n', '\n', ':'}; //\r\n\n: const char pro_start1[] = {'\n', '\n', '-', '-'}; //\r\n--: const char pro_start2[] = {'\r', '\n', '\r', '\n', '-'}; const char pro_start3[] = {'\r', '\n', '\r', '\n', ':'}; const char pro_pack_start[] = {'\r', '\n', ':'}; const char pro_end[] = {'0', '0', '0', '0', '0', '0', '0', '1', 'f', 'f'}; uint16_t UsartNrf_Get_crc_xor16(uint16_t *b_hex, uint16_t len) { uint16_t i; uint16_t crc; crc = 0; for(i = 0; i < len; i++) { crc = crc ^ (*(b_hex + i)); } return (crc); } /*********************************************** ** Function name: ** Descriptions: //Get the inverter type ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ InverterType UsartNrf_GetInvterType(uint8_t *pId) { if(((pId[1] & 0xf0) == 0x10) || ((pId[1] & 0xf0) == 0x20)) { return Inverter_250; } else if(((pId[1] & 0xf0) == 0x30) || ((pId[1] & 0xf0) == 0x40)) //500w { return Inverter_500; } else if(((pId[1] & 0xf0) == 0x50) || ((pId[1] & 0xf0) == 0x60)) { return Inverter_1000; } return InitInverterType; } /*********************************************** ** Function name: Real-time data collection exception handling ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ bool UsartNrf_Process_ExceptionFilter(uint8_t *pBuffer, uint8_t Head, uint8_t Tail, uint16_t MaxValue) { if(((uint16_t)pBuffer[Head] << 8 | pBuffer[Tail]) > MaxValue) //pv voltage { return false; } else { return true; } } /*********************************************** ** Function name: Initialize the Inverter version ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Version_InitInverter(void) { MIDetail.Property.USFWBuild_VER = 0; MIDetail.Property.AppFWBuild_VER = 0; MIDetail.Property.AppFWBuild_YYYY = 0; MIDetail.Property.AppFWBuild_MMDD = 0; MIDetail.Property.AppFWBuild_HHMM = 0; MIDetail.Property.AppFW_PNH = 0; MIDetail.Property.AppFW_PNL = 0; MIDetail.Property.HW_VER = 0; MIDetail.Property.HW_PNH = 0; MIDetail.Property.HW_PNL = 0; MIDetail.Property.HW_FB_TLmValue = 0; MIDetail.Property.HW_FB_ReSPRT = 0; MIDetail.Property.HW_GridSamp_ResValule = 0; MIDetail.Property.HW_ECapValue = 0; MIDetail.Property.Matching_AppFW_PNH = 0; MIDetail.Property.Matching_AppFW_PNL = 0; MIDetail.Property.AppFW_MINVER = 0; MIDetail.Property.HW_CRCValue = 0; MIDetail.Property.CRC_ALL = 0; } /*********************************************** ** Function name: Initialize the Inverter version ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Version_InitInverterRf(void) { memset(&(MIDetail.Property.NRF_HardVersion), 0, 4); memset(&(MIDetail.Property.NRF_SoftVersion), 0, 4); } /*********************************************** ** Function name: ** Descriptions: //Disassembly ID ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_InitPVPannelToMIMajor(void) { uint16_t i; uint16_t j; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { if(UsartNrf_GetInvterType(MIMajor[i].Property.Pre_Id) == Inverter_500) { if((MIMajor[i].Property.Port != MI_500W_A) && (MIMajor[i].Property.Port != MI_500W_B)) { for(j = Dtu3Detail.Property.PortNum; j > i; j--) { memcpy(&MIReal[j + 1], &MIReal[j], sizeof(MIReal[j])); //When 500w is not marked with the 500w type, the real-time data will move one space to the right memcpy(&MIMajor[j + 1], &MIMajor[j], sizeof(MIMajor[j])); } memcpy(&(MIMajor[j + 1].Property.Id[0]), &MIMajor[j].Property.Id[0], sizeof(MIMajor[j].Property.Id)); memcpy(&(MIMajor[j + 1].Property.Pre_Id[0]), &MIMajor[j].Property.Pre_Id[0], sizeof(MIMajor[j].Property.Pre_Id)); MIMajor[j].Property.Port = MI_500W_A; MIMajor[j + 1].Property.Port = MI_500W_B; if(Dtu3Detail.Property.PortNum >= PORT_LEN) { Dtu3Detail.Property.PortNum = PORT_LEN;//Dtu3Detail.Property.PortNum - 1; } i = i + 1; } } else if(UsartNrf_GetInvterType(MIMajor[i].Property.Pre_Id) == Inverter_1000) { if((MIMajor[i].Property.Port != MI_1000W_A) && (MIMajor[i].Property.Port != MI_1000W_B) && (MIMajor[i].Property.Port != MI_1000W_C) && (MIMajor[i].Property.Port != MI_1000W_D)) { for(j = Dtu3Detail.Property.PortNum - 1; j > i; j--) { memcpy(&MIReal[j + 3], &MIReal[j], sizeof(MIReal[j])); memcpy(&MIMajor[j + 3], &MIMajor[j], sizeof(MIMajor[j])); } memcpy(&MIMajor[j + 1].Property.Id[0], &MIMajor[j].Property.Id[0], sizeof(MIMajor[j].Property.Id)); memcpy(&MIMajor[j + 1].Property.Pre_Id[0], &MIMajor[j].Property.Pre_Id[0], sizeof(MIMajor[j].Property.Pre_Id)); memcpy(&MIMajor[j + 2].Property.Id[0], &MIMajor[j].Property.Id[0], sizeof(MIMajor[j].Property.Id)); memcpy(&MIMajor[j + 2].Property.Pre_Id[0], &MIMajor[j].Property.Pre_Id[0], sizeof(MIMajor[j].Property.Pre_Id)); memcpy(&MIMajor[j + 3].Property.Id[0], &MIMajor[j].Property.Id[0], sizeof(MIMajor[j].Property.Id)); memcpy(&MIMajor[j + 3].Property.Pre_Id[0], &MIMajor[j].Property.Pre_Id[0], sizeof(MIMajor[j].Property.Pre_Id)); MIMajor[j].Property.Port = MI_1000W_A; MIMajor[j + 1].Property.Port = MI_1000W_B; MIMajor[j + 2].Property.Port = MI_1000W_C; MIMajor[j + 3].Property.Port = MI_1000W_D; if(Dtu3Detail.Property.PortNum >= PORT_LEN) { Dtu3Detail.Property.PortNum = PORT_LEN; // Dtu3Detail.Property.PortNum - 4; } i = i + 3; } } else { MIMajor[i].Property.Port = MI_250W; } } } /*********************************************** ** Function name: ** Descriptions: //Clear the MIReal structure ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_ClearMIReal(void) { uint16_t i; for(i = 0; i < PORT_LEN; i++) { memset(MIReal[i].Data.PVVol, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.PVCur, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.GridVol, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Freque, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Power, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Temper, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Run_Status, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Fault_Code, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Fault_Num, 0, 2 * sizeof(uint8_t)); //MIReal[i].Data.Collec_Time = 0; MIReal[i].Data.LinkState = 0; MIReal[i].Data.Real_Time = 0; } } /*********************************************** ** Function name: ** Descriptions: //Clear the day's power generation ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_ClearMI_DailyEnergy(void) { uint16_t i; for(i = 0; i < PORT_LEN; i++) { memset(MIReal[i].Data.PVVol, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.PVCur, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.GridVol, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Freque, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Power, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Temper, 0, 2 * sizeof(uint8_t)); MIReal[i].Data.Collec_Time = 0; MIReal[i].Data.LinkState = 0; memset(MIReal[i].Data.Run_Status, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Fault_Code, 0, 2 * sizeof(uint8_t)); memset(MIReal[i].Data.Fault_Num, 0, 2 * sizeof(uint8_t)); MIReal[i].Data.NetCmd = NET_INIT; MIReal[i].Data.DailyEnergy = 0; MIReal[i].Data.Real_Time = 0; MIReal[i].Data.NetStatus = NET_NOCMD; } } void UsartNrf_ClearMIReal_HistoryEnergy(void) { uint16_t i; for(i = 0; i < PORT_LEN; i++) { MIReal[i].Data.HistoryEnergyH = 0; MIReal[i].Data.HistoryEnergyL = 0;; } } /*********************************************** ** Function name: ** Descriptions: //Clear the InverterMajor structure ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_ClearInverterMajor(void) { uint16_t i; for(i = 0; i < PORT_LEN; i++) { memset(&(MIMajor[i]), 0, sizeof(MIMajor[i])); } } /*********************************************** ** Function name: ** Descriptions: //Clear the DtuDetail structure ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_ClearDtuMajor(void) { memset(&(Dtu3Major), 0, sizeof(DtuMajor)); } /*********************************************** ** Function name: ** Descriptions: //Reset interval time ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_SendLoop_ResetBaud() { if((LocalTime_300Ms != 300) && (LocalTime_300Ms != 500)) { if(Uart_CurrentDtuBaud == Device_250K) { LocalTime_300Ms = 500; } else if(Uart_CurrentDtuBaud == Device_2M) { LocalTime_300Ms = 300; } else { LocalTime_300Ms = 300; } } } /*********************************************** ** Function name: ** Descriptions: // Filter port number ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_SendLoop_GetNextSetCmd() { if((MIReal[PortNO].Data.NetStatus == NET_NOT_EXECUTED) || (MIReal[PortNO].Data.NetStatus == LOCAL_NOT_EXECUTED)) { return true; } else if((MIReal[PortNO].Data.NetStatus == NET_EXECUTION_FAILURE) || (MIReal[PortNO].Data.NetStatus == NET_NOCMD) || (MIReal[PortNO].Data.NetStatus == NET_EXECUTION_COMPLETED)) { PortNO++; } else { return true; } for(PortNO = PortNO; PortNO < Dtu3Detail.Property.PortNum;) { if((MIMajor[PortNO].Property.Port != MI_250W) && (MIMajor[PortNO].Property.Port != MI_500W_A) && (MIMajor[PortNO].Property.Port != MI_1000W_A)) { PortNO ++; } else { if(((MIReal[PortNO].Data.NetCmd >= NET_TURN_ON) && (MIReal[PortNO].Data.NetCmd <= NET_RESTART)) || (MIReal[PortNO].Data.NetCmd == NET_INVERTER_HW_INFOR)) { if((MIReal[PortNO].Data.NetStatus == NET_NOT_EXECUTED) || (MIReal[PortNO].Data.NetStatus == LOCAL_NOT_EXECUTED)) { return true; //Filter only the first port left } else if((MIReal[PortNO].Data.NetStatus == NET_EXECUTION_FAILURE) || (MIReal[PortNO].Data.NetStatus == NET_EXECUTION_COMPLETED)) { PortNO++; } else { return true; } } else { PortNO++; } } } if(PortNO >= Dtu3Detail.Property.PortNum) { IsPolling = true; PortNO = 0; UsartNrf_SendLoop_ResetBaud(); return false; } return true; } /*********************************************** ** Function name: ** Descriptions: // Switching interval time ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_SendLoop_SetBaud(bool Stop) { if(Stop == true) { LocalTime_300Ms = 0; return; } if(IsPolling == true) { if(Uart_CurrentDtuBaud == Device_250K) { LocalTime_300Ms = 500; } else if(Uart_CurrentDtuBaud == Device_2M) { LocalTime_300Ms = 300; } else { LocalTime_300Ms = 300; } } else { if(Uart_CurSendMainCmd == BROADCAST) { LocalTime_300Ms = 3000; } else if(Uart_CurSendMainCmd == DOWN_PRO) { if(Uart_CurrentDtuBaud == Device_250K) { if((Uart_SendBuffer[10] & 0xf0) == 0x10) { LocalTime_300Ms = 300; } else { LocalTime_300Ms = 100; } } else if(Uart_CurrentDtuBaud == Device_2M) { if((Uart_SendBuffer[10] & 0xf0) == 0x10) { LocalTime_300Ms = 110; } else { LocalTime_300Ms = 55; } } } else { if(Uart_CurrentDtuBaud == Device_250K) { LocalTime_300Ms = 500; } else if(Uart_CurrentDtuBaud == Device_2M) { LocalTime_300Ms = 300; } else { LocalTime_300Ms = 300; } } } } /*********************************************** ** Function name: Control the real-time data acquisition light on and off ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_LedShow(bool PollRealTimeState, uint8_t NoConllectTime) { uint16_t i; uint16_t SumLinkState = 0; if(((MIReal[0].Data.NetCmd == NET_REGISTER_ID) && (MIReal[0].Data.NetStatus == NET_NOT_EXECUTED)) || (HasTempRegister == true)) { Dtu3Detail.Property.LedState = 1; //Incomplete search HasTempRegister = false; CurNetCmd = NET_INIT; return; } if(PollRealTimeState == false) //When polling fails { if((Uart_CurSendMainCmd == REQ_A_DAT) || (Uart_CurSendMainCmd == REQ_B_DAT) || (Uart_CurSendMainCmd == REQ_A1_DAT_1000) || (Uart_CurSendMainCmd == REQ_A1_DAT_1000) || (Uart_CurSendMainCmd == REQ_A2_DAT_1000) || (Uart_CurSendMainCmd == REQ_B1_DAT_1000) || (Uart_CurSendMainCmd == REQ_B2_DAT_1000) || (Uart_CurSendMainCmd == REQ_ARW_DAT_ALL)) { if(MIReal[PortNO].Data.Collec_Time >= NoConllectTime) { MIReal[PortNO].Data.Collec_Time = NoConllectTime; } else { MIReal[PortNO].Data.Collec_Time++; } } else { } } else // polling data succeeded { MIReal[PortNO].Data.Collec_Time = 0; } if(CurNetCmd == NET_NOPORT) { Dtu3Detail.Property.LedState = 0; return; } else { if(PortNO == (Dtu3Detail.Property.PortNum - 1)) { for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { if(MIReal[i].Data.Collec_Time >= NoConllectTime) { MIReal[i].Data.LinkState = 0; //20 rounds without 1 round of search } } for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { SumLinkState = SumLinkState + MIReal[i].Data.LinkState; } if(SumLinkState >= Dtu3Detail.Property.PortNum) { Dtu3Detail.Property.LedState = 2; //Search all } else { Dtu3Detail.Property.LedState = 1; //Incomplete search } } } } /*********************************************** ** Function name: ** Descriptions: //Get the number of components under this dtu ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_GetDtu3PortNum(void) { uint16_t i; Dtu3Detail.Property.PortNum = 0; Dtu3Detail.Property.InverterNum = 0; Dtu3Detail.Property.Reflux_DtuPanelNum_A = 0; Dtu3Detail.Property.Reflux_DtuPanelNum_B = 0; Dtu3Detail.Property.Reflux_DtuPanelNum_C = 0; for(i = 0; i < PORT_LEN; i++) { if(MIMajor[i].Property.Pre_Id[0] == 0x10) { if(((uint8_t)(MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x10) || ((MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x20)) { if(Dtu3Detail.Property.Zero_Export_Switch == 1) { if(MIMajor[i].Property.Id_In_Phase == 1) { Dtu3Detail.Property.Reflux_DtuPanelNum_A = Dtu3Detail.Property.Reflux_DtuPanelNum_A + 1; } else if(MIMajor[i].Property.Id_In_Phase == 2) { Dtu3Detail.Property.Reflux_DtuPanelNum_B = Dtu3Detail.Property.Reflux_DtuPanelNum_B + 1; } else if(MIMajor[i].Property.Id_In_Phase == 3) { Dtu3Detail.Property.Reflux_DtuPanelNum_C = Dtu3Detail.Property.Reflux_DtuPanelNum_C + 1; } else if(MIMajor[i].Property.Id_In_Phase == 0) { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 1; } } else { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 1; } } else if(((uint8_t)(MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x30) || ((MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x40)) { if(Dtu3Detail.Property.Zero_Export_Switch == 1) { if(MIMajor[i].Property.Id_In_Phase == 1) { Dtu3Detail.Property.Reflux_DtuPanelNum_A = Dtu3Detail.Property.Reflux_DtuPanelNum_A + 2; } else if(MIMajor[i].Property.Id_In_Phase == 2) { Dtu3Detail.Property.Reflux_DtuPanelNum_B = Dtu3Detail.Property.Reflux_DtuPanelNum_B + 2; } else if(MIMajor[i].Property.Id_In_Phase == 3) { Dtu3Detail.Property.Reflux_DtuPanelNum_C = Dtu3Detail.Property.Reflux_DtuPanelNum_C + 2; } else if(MIMajor[i].Property.Id_In_Phase == 0) { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 2; } } else { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 2; } } else if(((uint8_t)(MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x50) || ((uint8_t)(MIMajor[i].Property.Pre_Id[1] & 0xf0) == 0x60)) { if(Dtu3Detail.Property.Zero_Export_Switch == 1) { if(MIMajor[i].Property.Id_In_Phase == 1) { Dtu3Detail.Property.Reflux_DtuPanelNum_A = Dtu3Detail.Property.Reflux_DtuPanelNum_A + 4; } else if(MIMajor[i].Property.Id_In_Phase == 2) { Dtu3Detail.Property.Reflux_DtuPanelNum_B = Dtu3Detail.Property.Reflux_DtuPanelNum_B + 4; } else if(MIMajor[i].Property.Id_In_Phase == 3) { Dtu3Detail.Property.Reflux_DtuPanelNum_C = Dtu3Detail.Property.Reflux_DtuPanelNum_C + 4; } else if(MIMajor[i].Property.Id_In_Phase == 0) { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 4; } } else { Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 4; } } if(Dtu3Detail.Property.PortNum >= PORT_LEN) { Dtu3Detail.Property.PortNum = PORT_LEN; return; } Dtu3Detail.Property.InverterNum ++; if(Dtu3Detail.Property.InverterNum >= PORT_LEN) { return; } } else { break; } } } /*********************************************** ** Function name: forward substitution ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t ForwardSubstitution(uint8_t *result, uint8_t *source, uint8_t length) { uint16_t i; uint16_t j = 0; for(i = 0; i < length; i++) { if((*(source + i)) == 0x7d) { (*(result + j)) = 0x7d; j++; (*(result + j)) = 0x5d; j++; } else if((*(source + i)) == 0x7e) { (*(result + j)) = 0x7d; j++; (*(result + j)) = 0x5e; j++; } else if((*(source + i)) == 0x7f) { (*(result + j)) = 0x7d; j++; (*(result + j)) = 0x5f; j++; } else { (*(result + j)) = (*(source + i)); j++; } } return (j); } /*********************************************** ** Function name: XOR check ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t Get_crc_xor(uint8_t *b_hex, uint16_t len) { uint16_t i; uint8_t crc; crc = 0; #ifdef DEBUG1 if(len > 40) { printf("Get_crc_xor_len:%d\r\n", len); } #endif for(i = 0; i < len; i++) { crc = crc ^ (*(b_hex + i)); } return (crc); } /*********************************************** ** Function name: //Send basic commands ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackBaseCommand(uint8_t *target_adr, uint8_t *rout_adr, uint8_t cmd, uint8_t dat) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX;//ͷ temp_dat[0] = cmd; //command memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = dat; temp_dat[10] = Get_crc_xor(&temp_dat[0], 10); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 11); //Forward Substitution Uart_SendBuffer[(i + 1)] = ETX; //β memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: ** Descriptions: //Clear network command status after booting ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_ClearNetStatusAndCmd(void) { uint8_t i; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { MIReal[i].Data.NetStatus = NET_NOCMD; MIReal[i].Data.NetCmd = NET_INIT; } } void UsartNrf_ClearCollect_TimeAndLinkState(void) { uint8_t i; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { MIReal[i].Data.Collec_Time = 0; MIReal[i].Data.LinkState = 0; } } /*********************************************** ** Function name: ** Descriptions: //Initialize related variables ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_MemInit(void) { uint16_t i; uint8_t Pre_Id[2] = {0, 0}; uint8_t Id[4] = {0, 0, 0, 0}; LocalTime_300Ms = 300; PortNO = 0; memcpy(Pre_Id, Dtu3Major.Property.Pre_Id, 2); memcpy(Id, Dtu3Major.Property.Id, 4); UsartNrf_ClearDtuMajor(); System_DtuMajor_Read(&Dtu3Major); if((memcmp(Pre_Id, Dtu3Major.Property.Pre_Id, 2) != 0) || (memcmp(Id, Dtu3Major.Property.Id, 4) != 0)) { memcpy(Dtu3Major.Property.Pre_Id, Pre_Id, 2); memcpy(Dtu3Major.Property.Id, Id, 4); } UsartNrf_ClearInverterMajor(); InverterMajor_Read(MIMajor); System_DtuDetail_Read(&Dtu3Detail); UsartNrf_ClearMIReal_HistoryEnergy(); InverterReal_Read(MIReal); UsartNrf_ClearMI_DailyEnergy(); UsartNrf_ClearNetStatusAndCmd(); UsartNrf_ClearCollect_TimeAndLinkState(); for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { DailyEnergyTemp[i] = ((((uint32_t)(MIReal[i].Data.HistoryEnergyH)) << 16) | MIReal[i].Data.HistoryEnergyL); } // MIReal[0].Data.NetCmd = NET_DTU_HW_INFOR_RES; // MIReal[0].Data.NetStatus = NET_NOT_EXECUTED; CurNetCmd = NET_DTU_HW_INFOR_RES; IsPolling = false; // Dtu3Detail.Property.Anti_Theft_Switch = 0; // Dtu3Detail.Property.Zero_Export_Switch = 0; if(Dtu3Detail.Property.PortNum > 0) { UsartNrf_Process_LedShow(true, 10); } } /*********************************************** ** Function name: ** Descriptions: // NRF self-test ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_NrfCheckSelf() { static uint32_t SendTime; static uint8_t CheckCnt; uint8_t DtuId[6] = {0, 0, 0, 0, 0, 0}; SendTime = LocalTime; while(1) { if((memcmp(&(DtuId[0]), Dtu3Major.Property.Pre_Id, 2) == 0) && (memcmp(&(DtuId[2]), Dtu3Major.Property.Id, 4) == 0)) { if(CheckCnt <= 2) { if(((LocalTime >= SendTime) && (LocalTime - SendTime >= LocalTime_300Ms)) || ((LocalTime < SendTime) && (LocalTime_900000Ms - SendTime + LocalTime >= LocalTime_300Ms))) { SendTime = LocalTime; Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(&(DtuId[2]), &(DtuId[2]), REQ_RF_RVERSISON, 0); CheckCnt++; USART_ClearITPendingBit(UsartNrf, USART_IT_TC); USART_ClearFlag(UsartNrf, USART_FLAG_TC); UsartNrf_SendLoop_SetBaud(false); USART_SendData(UsartNrf, Uart_SendBuffer[0]); } else { } } else { nRFHasCheck = true; return false; } } else { nRFHasCheck = true; return true; } } } /*********************************************** ** Function name: ** Descriptions: // Initialize NRF peripherals ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_NrfInit(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; #ifdef DTU3PRO RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//2 NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); USART_InitStructure.USART_BaudRate = 125000; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* Configure Usart3*/ USART_Init(USART3, &USART_InitStructure); //Configure Usart3 USART_Cmd(USART3, ENABLE); // Enable Usart3 USART_ClearITPendingBit(USART3, USART_IT_TC); /* Enable the Usart3 */ USART_ITConfig(USART3, USART_IT_TC, ENABLE); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); #else RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); USART_DeInit(USART2); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 38400; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; /* Configure USART2*/ USART_Init(USART2, &USART_InitStructure); //Configure usart2 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//2 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //Serial port interrupt priority configuration // USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); /* Enable the USART2 */ USART_Cmd(USART2, ENABLE); // Enable usart2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // Turn on the gpio clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // Turn on the serial port clock GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 125000; //Baud rate USART_InitStructure.USART_WordLength = USART_WordLength_8b; //Frame length USART_InitStructure.USART_StopBits = USART_StopBits_1; // Stop bit USART_InitStructure.USART_Parity = USART_Parity_No; //Parity check USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Hardware flow USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //Working mode USART_Init(USART2, &USART_InitStructure); //Configure usart2 USART_Cmd(USART2, ENABLE); // Enable usart2 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//2 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //Serial port interrupt priority configuration /* Enable the Usart3 */ // USART_ClearFlag(USART2, USART_FLAG_TC); USART_GetFlagStatus(USART2, USART_FLAG_ORE); USART_ITConfig(USART2, USART_IT_TC, ENABLE); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_ClearITPendingBit(USART2, USART_IT_TC); USART_ClearITPendingBit(USART2, USART_FLAG_TC); #endif return UsartNrf_NrfCheckSelf(); } /*********************************************** ** Function name: ** Descriptions: // Determine whether the receipt is normal ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_SendLoop_ReplyOK(void) { if(Uart_CurSendMainCmd == REQ_A_DAT) { // if((Uart_CurRecMainCmd == ANSWER_REQ_B_DAT) || (Uart_CurRecMainCmd == ANSWER_REQ_B_EVENT)) // { // return true; // } // else // { return false; // } } else if(Uart_CurSendMainCmd == REQ_B_DAT) { // if((Uart_CurRecMainCmd == ANSWER_REQ_B_DAT) || (Uart_CurRecMainCmd == ANSWER_REQ_B_EVENT)) // { // return true; // } // else // { return false; // } } else if(Uart_CurSendMainCmd == REQ_A1_DAT_1000) { if(Uart_CurRecMainCmd == ANSWER_REQ_A1_DAT_1000) { return true; } else { return false; } } else if(Uart_CurSendMainCmd == REQ_B1_DAT_1000) { if(Uart_CurRecMainCmd == ANSWER_REQ_B1_DAT_1000) { return true; } else { return false; } } else if(Uart_CurSendMainCmd == REQ_A2_DAT_1000) { if(Uart_CurRecMainCmd == ANSWER_REQ_A2_DAT_1000) { return true; } else { return false; } } else if(Uart_CurSendMainCmd == REQ_B2_DAT_1000) { if(Uart_CurRecMainCmd == ANSWER_REQ_B2_DAT_1000) { return true; } else { return false; } } else if(Uart_CurSendMainCmd == CONTROL_LOCK_MI__LIMIT_POWER_ONOFF) { if(Uart_CurRecMainCmd == ANSWER_CONTROL_LOCK_MI__LIMIT_POEWR_ONOFF) { if(Uart_CurSendSubCmd == Uart_CurRecSubCmd) { return true; } else { return false; } } return false; } else { if((Uart_CurSendMainCmd | 0X80) == Uart_CurRecMainCmd) { if((MIReal[PortNO].Data.NetCmd == NET_DOWNLOAD_PRO) || (MIReal[PortNO].Data.NetCmd == NET_DOWNLOAD_DAT)) { if((Uart_CurrentReplyState == 2) || (Uart_CurrentReplyState == 3)) { return false; } else { return true; } } else { return true; } } else { return false; } } return false; } /*********************************************** ** Function name: Reverse replacement ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_Backward_substitution1(uint8_t *result, uint8_t *source, uint8_t length) { uint16_t i; uint16_t j = 0; for(i = 0; i < length; i++) { if((*(source + i)) == 0x7d) { if(*(source + i + 1) == 0x5d) { (*(result + j)) = 0x7d; j++; } else if(*(source + i + 1) == 0x5e) { (*(result + j)) = 0x7e; j++; } else if(*(source + i + 1) == 0x5f) { (*(result + j)) = 0x7f; j++; } i++; } else { (*(result + j)) = (*(source + i)); j++; } } return j; } /*********************************************** ** Function name: Polling with lock in anti-theft mode ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackPollRfWithLockCommand(uint8_t *target_adr, uint8_t *rout_adr, uint8_t cmd) { uint8_t i = 0; uint32_t Real_Time; uint8_t temp_dat[UART_LEN]; calendar_obj calendar; RTC_GetWorldTime(&calendar, Dtu3Detail.Property.timezone); memset(temp_dat, 0, sizeof(temp_dat)); memset(Uart_SendBuffer, 0, sizeof(Uart_SendBuffer)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = cmd; //Instruction memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = 0; temp_dat[10] = calendar.w_date;//Rtc_Date.Day; temp_dat[11] = calendar.hour; temp_dat[12] = calendar.min; temp_dat[13] = calendar.sec; //time //password temp_dat[14] = Dtu3Detail.Property.LockNewPassword[0]; temp_dat[15] = Dtu3Detail.Property.LockNewPassword[1]; temp_dat[16] = Dtu3Detail.Property.LockNewPassword[2]; temp_dat[17] = Dtu3Detail.Property.LockNewPassword[3]; //Password temp_dat[18] = 0; temp_dat[19] = 0; temp_dat[20] = 0; temp_dat[21] = 0; temp_dat[22] = 0; // Polling data time interval temp_dat[23] = Get_crc_xor(&temp_dat[0], 23); //CRC check i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 24); // Forward replacement Uart_SendBuffer[(i + 1)] = ETX; memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: Switch on and off ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackSetTurnOnOffCommand(uint8_t *target_adr, uint8_t *rout_adr, uint8_t MainCmd, uint16_t SubCmd) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = MainCmd; //command memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = SubCmd >> 8; temp_dat[10] = SubCmd & 0xff; temp_dat[11] = Get_crc_xor(&temp_dat[0], 11); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 12); //Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //β memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: Anti-theft settings ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackSetLockOnOffCommand(uint8_t *target_adr, uint8_t *rout_adr, int8_t MainCmd, uint16_t SubCmd) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX;// temp_dat[0] = MainCmd; //Control micro-inverse lock memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = SubCmd >> 8; temp_dat[10] = SubCmd & 0XFF; //Sub-command temp_dat[11] = Dtu3Detail.Property.LockOldPassword[0];//Dtu3Detail[PortNO].LockOldPassword[0]; temp_dat[12] = Dtu3Detail.Property.LockOldPassword[1];//Dtu3Detail[PortNO].LockOldPassword[1]; temp_dat[13] = Dtu3Detail.Property.LockOldPassword[2];//Dtu3Detail[PortNO].LockOldPassword[2]; temp_dat[14] = Dtu3Detail.Property.LockOldPassword[3];//Dtu3Detail[PortNO].LockOldPassword[3]; //Old password temp_dat[15] = Dtu3Detail.Property.LockNewPassword[0]; temp_dat[16] = Dtu3Detail.Property.LockNewPassword[1]; temp_dat[17] = Dtu3Detail.Property.LockNewPassword[2]; temp_dat[18] = Dtu3Detail.Property.LockNewPassword[3]; //New password temp_dat[19] = Dtu3Detail.Property.Lock_Time[0]; temp_dat[20] = Dtu3Detail.Property.Lock_Time[1]; //Interval time temp_dat[21] = Get_crc_xor(&temp_dat[0], 21); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 22); // Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: ** Descriptions: Set the micro-inverse power command ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_Send_PackSetPowerLimitCommand(uint8_t *target_adr, uint8_t *rout_adr, int8_t MainCmd, uint16_t SubCmd) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = MainCmd; //Instruction memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); if(MIMajor[PortNO].Property.Acq_Switch == 0) { //1000w shutdown special control, the last 8 digits of the ID are less than 0x50000000, and the micro-inverse control of 1 to 4 is less than 0x50000000. if((MIMajor[PortNO].Property.Id[0] < 0X50) && ((MIMajor[PortNO].Property.Pre_Id[1] == 0X60) || (MIMajor[PortNO].Property.Pre_Id[1] == 0X61))) { temp_dat[9] = SubCmd & 0XFF00 >> 8; //5a5a temp_dat[10] = SubCmd & 0XFF; temp_dat[11] = 11; // temp = 35*4*10=1400=0x0578; temp_dat[12] = 0X05; temp_dat[13] = 0X78; temp_dat[14] = Get_crc_xor(&temp_dat[0], 14); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 15); // Forward replacement } else { temp_dat[9] = SubCmd >> 8; //5a5a temp_dat[10] = SubCmd ; temp_dat[11] = Get_crc_xor(&temp_dat[0], 11); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 12); //Forward replacement } } else { temp_dat[9] = SubCmd & 0XFF00 >> 8; //5a5a temp_dat[10] = SubCmd & 0XFF; temp_dat[11] = MIMajor[PortNO].Property.Power_Limit * 10 / (EVERY_PORT_POWER * (UsartNrf_GetInvterType(MIMajor[PortNO].Property.Pre_Id))); // Power limit percentage temp_dat[12] = MIMajor[PortNO].Property.Power_Limit >> 8; // Limit power to 8 bits high temp_dat[13] = MIMajor[PortNO].Property.Power_Limit & 0x00ff; // Limit power to 8 bits lower temp_dat[14] = Get_crc_xor(&temp_dat[0], 14); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 15); // Forward replacement } Uart_SendBuffer[(i + 1)] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: // Set anti-countercurrent parameters ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackSetRefluxPowerCommand(uint16_t reflux_power, uint8_t MainCmd, uint16_t SubCmd) { uint8_t i = 0; uint16_t j; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = MainCmd; //Instruction memset(&temp_dat[1], 0, 4); memset(&temp_dat[5], 0, 4); // // MIReal[PortNO].Data.NetCmd = NET_TURN_ON; // if(MIReal[PortNO].Data.NetCmd == NET_TURN_ON) //Boot status // { temp_dat[9] = SubCmd & 0XFF00 >> 8; temp_dat[10] = SubCmd & 0XFF; temp_dat[11] = reflux_power * 100 / (EVERY_PORT_POWER * 10 * Dtu3Detail.Property.PortNum); //Power limit percentage temp_dat[12] = reflux_power >> 8; // High power limit 8 bits temp_dat[13] = reflux_power & 0x00ff; // Low power limit 8 bits // } // else // Open low power consumption // { // temp_dat[9] = SubCmd & 0XFF00 >> 8; //5a5a // temp_dat[10] = SubCmd & 0XFF; // temp_dat[11] = 0; // temp_dat[12] = 20&0x00ff; // temp_dat[13] = 20&0xff00>>16; // } temp_dat[14] = Get_crc_xor(&temp_dat[0], 14); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 15); // Forward replacement Uart_SendBuffer[i + 1] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: // Set the air baud rate ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_Send_PackSetNrfBaudRateInTheAir(uint8_t *target_adr, uint8_t *rout_adr, uint8_t Cmd, BaudType Baud) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); memset(Uart_SendBuffer, 0, sizeof(Uart_SendBuffer)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = Cmd; //Instruction memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = Baud; temp_dat[10] = Get_crc_xor(&temp_dat[0], 10); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 11); // Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //β memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: // Guangfa search ID ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_Send_PackSearchMiID(uint8_t *target_adr, uint8_t *rout_adr, uint8_t cmd) { uint8_t i = 0, j = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = cmd; //Instruction memcpy(&temp_dat[1], target_adr, 4); //1234 memcpy(&temp_dat[5], rout_adr, 4); //5678 i = 0; j = 9; //0----8 8*2 temp_dat[10] = Get_crc_xor(&temp_dat[0], ++j); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], j); // Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //β memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } ////////////////////////////////////////////////Upgrade program//////////////////////////////////////////////////////////////////////////////////////////////////////// /*********************************************** ** Function name: ** Descriptions: Upgrade the micro-inverse program (one line of packaging in hex) ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_Send_MiProgram_SigleFrame(uint8_t *target_adr, uint8_t *router_adr, uint8_t *dat, uint8_t nub, uint8_t len) { uint8_t i = 0, j = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); memset(Uart_SendBuffer, 0, sizeof(Uart_SendBuffer)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = DOWN_PRO; //Instruction memcpy(&temp_dat[1], target_adr, 4); //1234 memcpy(&temp_dat[5], router_adr, 4); //5678 temp_dat[9] = nub; i = 0; j = 10; //0----8 8*2 for(i = 0; i < len; i++) { temp_dat[j++] = (*(dat + i)); } temp_dat[j] = Get_crc_xor(temp_dat, j); //CRC i = ForwardSubstitution(&(Uart_SendBuffer[1]), temp_dat, j + 1); // Forward replacement Uart_SendBuffer[i + 1] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: ** Descriptions: Convert single-character ascii to hex ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t SigleCharToHex(char dat) { uint8_t i = 0; if((0x30 <= dat) && (dat <= 0x39)) { i = dat - 0x30; } if((0x41 <= dat) && (dat <= 0x46)) { i = dat - 55; } if((0x61 <= dat) && (dat <= 0x66)) { i = dat - 87; } if(i > 15) { i = 0; } return (i); } /*********************************************** ** Function name: ** Descriptions: Convert two-character ascii to hex ** input parameters: ** output parameters: ** Returned value: *************************************************/ void AsciiToHex(uint8_t *sour, uint8_t *dest, uint8_t len) { uint8_t i; uint8_t temp[74]; for(i = 0; i < len; i++) { temp[i] = SigleCharToHex(*(sour + i)); } for(i = 0; i < (len / 2); i++) { (*(dest + i)) = ((temp[2 * i] << 4) & 0xf0) + (temp[(2 * i) + 1] & 0x0f); } } /*********************************************** ** Function name: CRC and check ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ uint8_t UsartNrf_GetCrcValue_Sum(uint8_t *dat, uint16_t len) { uint16_t i; uint8_t sum; sum = 0; for(i = 0; i < len; i++) { sum = sum + (*(dat + i)); } return (sum); } /*********************************************** ** Function name: ** Descriptions: Determine whether it is a hex upgrade file ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_IsRighUpgateHexFile(void) { while(Index_Pro <= 1024) { if((strncmp((const char *)(&string[Index_Pro]), pro_start3, 5) == 0) || (strncmp((const char *)(&string[Index_Pro]), pro_start1, 4) == 0) || (strncmp((const char *)(&string[Index_Pro]), pro_start2, 5) == 0) || (strncmp((const char *)(&string[Index_Pro]), pro_start0, 5) == 0)) { if(strncmp((const char *)(&string[Index_Pro]), pro_start0, 5) == 0) { Index_Pro = Index_Pro + 5; return true; } else if(strncmp((const char *)(&string[Index_Pro]), pro_start1, 4) == 0) { Index_Pro = Index_Pro + 4; return true; } else if(strncmp((const char *)(&string[Index_Pro]), pro_start2, 5) == 0) { Index_Pro = Index_Pro + 4; return true; } else if(strncmp((const char *)(&string[Index_Pro]), pro_start3, 4) == 0) { Index_Pro = Index_Pro + 5; return true; } } else { Index_Pro++; } } return false; } /*********************************************** ** Function name: ** Descriptions: Determine whether it is the last line of the hex upgrade file ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool IsLastLineInHex(void) { static uint16_t CurIndex = 0; static uint16_t PreIndex = 0; while(Index_Pro < 1460) { if(CurIndex - PreIndex == 24) //?12*2????1? { PreIndex = CurIndex; if(strncmp((const char *)&string[CurIndex], pro_end, 4) == 0) //\r\n--Judge the package at the end { return true; } } CurIndex++; } return false; } /*********************************************** ** Function name: ** Descriptions: Send current row data ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint16_t UsartNrf_Send_PackMiProgram_CurRow(uint8_t *target_adr, uint8_t *rout_adr, uint8_t *pCurRowData, uint16_t CurRowLen) { static uint8_t CurPackageNO = 0; static uint8_t CurRowDataOffset = 0; if(CurRowLen >= 13) { if(CurRowLen == 13) { CurPackageNO = 0; CurRowDataOffset = 0; Uart_SendBufferLen = UsartNrf_Send_MiProgram_SigleFrame(target_adr, rout_adr, pCurRowData + CurRowDataOffset, 0x10, 13); CurRowLen = 0; } else { Uart_SendBufferLen = UsartNrf_Send_MiProgram_SigleFrame(target_adr, rout_adr, pCurRowData + CurRowDataOffset, 0x00 | CurPackageNO, 13); CurRowDataOffset = CurRowDataOffset + 13; CurRowLen = CurRowLen - 13; CurPackageNO++; } } else { Uart_SendBufferLen = UsartNrf_Send_MiProgram_SigleFrame(target_adr, rout_adr, pCurRowData + CurRowDataOffset, 0x10 | CurPackageNO, CurRowLen); CurRowLen = 0; CurPackageNO = 0; CurRowDataOffset = 0; } return CurRowLen; } /*********************************************** ** Function name: ** Descriptions: Prepare a line of hex for the upgrade file ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint16_t UsartNrf_Send_GetMiProgram_CurRow(uint8_t *pCurRowData) { uint16_t CurIndex = 0; //static uint8_t CurPackage= 0; uint16_t j = 0; static uint8_t Data[37 * 4]; while(CurIndex < 37 * 4) { if((strncmp((const char *) & (string[CurIndex]), pro_pack_start, 3) == 0) || (Index_Pro + 10 + 1 >= TotalIndex_Pro)) //\r\n: Start of each line except line 1 { if(Index_Pro + 10 + 1 >= TotalIndex_Pro) { CurIndex = 10; } for(j = 0; j < CurIndex; j++) { if(((string[j] <= '9') && (string[j] >= '0')) || ((string[j] <= 'F') && (string[j] >= 'A')) || ((string[j] <= 'f') && (string[j] >= 'a'))) { Data[j] = string[j]; } } memset(pCurRowData, 0, 37); AsciiToHex(Data, pCurRowData, j); memcpy(Uart_CurSendAddr, pCurRowData, 4); UsartNrf_GetCrcValue_Sum(pCurRowData, j / 2); Index_Pro = CurIndex + Index_Pro + 3; if(Index_Pro == 0xffffffff) { Index_Pro = 0; } //CurIndex = 0; memset(Data, 0, 37 * 4); break; } CurIndex++; } return j / 2; } /*********************************************** ** Function name: ** Descriptions: Update Program ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Send_PackUpdateMiProgram(uint8_t *target_adr, uint8_t *rout_adr) { static uint8_t CurRowData[37]; static uint16_t CurRowLen = 0; static uint32_t BackUpIndex = 0; if(RightHexFile == false) { memset(string, 0, sizeof(string)); TotalIndex_Pro = MI_Program_Get_Length(); MI_Program_Read_Length(string, 0, 512); Index_Pro = 0; RightHexFile = UsartNrf_IsRighUpgateHexFile(); CurRowLen = 0; BackUpIndex = Index_Pro; } if(RightHexFile == true) { if(CurRowLen == 0) { memset(string, 0, 37 * 4); if((Uart_CurrentReplyState != 1) || ((Index_Pro > 0x1E) && (memcmp(Uart_CurSendAddr, Uart_CurrentReplyAddr, 4) != 0)) || ((Uart_CurSendAddr[0] == Uart_CurSendAddr[1]) && (Uart_CurSendAddr[0] == Uart_CurSendAddr[2]) && (Uart_CurSendAddr[0] == Uart_CurSendAddr[3]) && (Uart_CurSendAddr[0] == 0))) { Index_Pro = BackUpIndex; } MI_Program_Read_Length(string, Index_Pro, 37 * 4); BackUpIndex = Index_Pro; CurRowLen = UsartNrf_Send_GetMiProgram_CurRow(CurRowData); } CurRowLen = UsartNrf_Send_PackMiProgram_CurRow(target_adr, rout_adr, CurRowData, CurRowLen); } } /*********************************************** ** Function name: Package and connect to the grid to protect the file ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackGridOnProFile_SigleFrame(uint8_t *target_adr, uint8_t *router_adr, uint8_t *dat, uint8_t nub, uint8_t len) { uint8_t i = 0, j = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); memset(Uart_SendBuffer, 0, sizeof(Uart_SendBuffer)); Uart_SendBuffer[0] = STX; temp_dat[0] = DOWN_DAT; //command memcpy(&temp_dat[1], target_adr, 4); //1234 memcpy(&temp_dat[5], router_adr, 4); //5678 temp_dat[9] = nub; i = 0; j = 10; //0----8 8*2 for(i = 0; i < len; i++) { temp_dat[j++] = (*(dat + i)); } //CRC // j--; temp_dat[j] = Get_crc_xor(&temp_dat[0], j); i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], j + 1); Uart_SendBuffer[(i + 1)] = ETX; memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: ** Descriptions: Send the current line to the grid-connected protection file ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint16_t UsartNrf_Send_PackGridOnProFile_CurText(uint8_t *target_adr, uint8_t *rout_adr, uint8_t *pCurRowData, uint16_t CurRowLen) { static uint8_t CurPackageNO = 0; static uint16_t CurSendPackageNum = 0; if(Index_Dat == 0) { CurPackageNO = 0; CurSendPackageNum = 0; } if(CurRowLen > 16) { Uart_SendBufferLen = UsartNrf_Send_PackGridOnProFile_SigleFrame(target_adr, rout_adr, pCurRowData, CurPackageNO, 16); CurPackageNO++; CurSendPackageNum = 16 * CurPackageNO; return CurSendPackageNum; } else { Uart_SendBufferLen = UsartNrf_Send_PackGridOnProFile_SigleFrame(target_adr, rout_adr, pCurRowData, CurPackageNO | 0x10, CurRowLen); CurSendPackageNum = CurPackageNO * 16 + CurRowLen; CurPackageNO = 0; return CurSendPackageNum; } } /*********************************************** ** Function name: ** Descriptions: // CRC check of grid-connected protection file ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ unsigned int UsartNrf_Send_CRC16_Work(unsigned char *CRC_Buf, unsigned int CRC_Leni) { unsigned int i, j; unsigned int CRC_Sumx; CRC_Sumx = 0xFFFF; for(i = 0; i < CRC_Leni; i++) { CRC_Sumx ^= *(CRC_Buf + i); for(j = 0; j < 8; j++) { if(CRC_Sumx & 0x01) { CRC_Sumx >>= 1; CRC_Sumx ^= 0xA001; } else { CRC_Sumx >>= 1; } } } return (CRC_Sumx); } /*********************************************** ** Function name: ** Descriptions: Package the grid-connected protection program ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackUpdateGridOnProFile(uint8_t *target_adr, uint8_t *rout_adr) { static bool RightGridOnProFile = false; static uint8_t CurRowData[300]; uint16_t CurRowData_16; if(RightGridOnProFile == false) { TotalIndex_Dat = Grid_Profiles_Data_Get_Length(); Grid_Profiles_Data_Read((char *)CurRowData, TotalIndex_Dat, 0); if((UsartNrf_Send_CRC16_Work(CurRowData, TotalIndex_Dat - 2)) == ((CurRowData[TotalIndex_Dat - 2] << 8) | (CurRowData[TotalIndex_Dat - 1]))) { CurRowData_16 = UsartNrf_Get_crc_xor16((u16 *)CurRowData, (TotalIndex_Dat - 2) / 2); CurRowData[TotalIndex_Dat - 1] = CurRowData_16 >> 8; //Low position before high position after CurRowData[TotalIndex_Dat - 2] = CurRowData_16; RightGridOnProFile = true; } } if(RightGridOnProFile == true) { Index_Dat = UsartNrf_Send_PackGridOnProFile_CurText(target_adr, rout_adr, CurRowData + Index_Dat, TotalIndex_Dat - Index_Dat); if(TotalIndex_Dat - Index_Dat <= 0) { RightGridOnProFile = false; Index_Dat = 0; TotalIndex_Dat = 0; // Number of bytes to be sent memset(CurRowData, 0, sizeof(CurRowData)); myfree(TestGridOnFile); } } return TotalIndex_Dat; } /*********************************************** ** Function name: Get the next real-time data polling instruction ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint16_t UsartNrf_GetNextInverterPortOfRealTime(uint16_t PortNum) { static uint16_t i = 0; if((Uart_CurSendMainCmd != 0) && (Uart_CurSendMainCmd != CHANGE_MOD_2M_250K)) { i++; } if((i >= PortNum) || (i >= (PORT_LEN - 1))) { i = 0; } return i; } /*********************************************** ** Function name: Determine the air baud rate based on the micro-inverter ID ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ BaudType GetInveterBaudType(uint8_t *DeviceId) { if((DeviceId[1] & 0x0f) == 1) { return Device_250K; } else if((DeviceId[1] & 0x0f) == 0) { return Device_2M; } return Device_INIT_BAUD; } /*********************************************** ** Function name: Whether the command to poll or set the current inverter was sent successfully ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_HasPollCurInverter(InverterType CurInverterType) { switch(CurInverterType) { case Inverter_250: if((Uart_CurRecMainCmd == ANSWER_REQ_A_DAT) || (Uart_CurRecMainCmd == ANSWER_REQ_A_EVENT)) { return true; } break; case Inverter_500: if((Uart_CurRecMainCmd == ANSWER_REQ_B_EVENT) || (Uart_CurRecMainCmd == ANSWER_REQ_B_DAT)) { return true; } break; case Inverter_1000: if(Uart_CurRecMainCmd == ANSWER_REQ_B2_DAT_1000) { return true; } break; case InitInverterType: return true; break; default: return false; } return false; } /*********************************************** ** Function name: Poll or set whether the current inverter port instruction was sent successfully ** Descriptions: ** input parameters: false--> next loop true--> next component ** output parameters: ? ** Returned value: ? *************************************************/ bool UsartNrf_HasPollCurInverterPort(void) { static bool FirstPoll = true; static uint8_t PollCnt = 0; uint16_t i, j; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { if(((MIReal[i].Data.NetCmd >= NET_TURN_ON) && (MIReal[i].Data.NetCmd <= NET_RESTART) && ((MIReal[i].Data.NetCmd != NET_WAIT_DOWNLOAD_DAT) && (MIReal[i].Data.NetCmd != NET_WAIT_DOWNLOAD_PRO))) && ((MIReal[i].Data.NetStatus == LOCAL_NOT_EXECUTED) || (MIReal[i].Data.NetStatus == NET_NOT_EXECUTED))) { IsPolling = false; PortNO = i; return false; } } if(UsartNrf_SendLoop_ReplyOK() == true) { PollCnt = 0; if((Uart_CurSendMainCmd != 0) && (Uart_CurSendMainCmd != CHANGE_MOD_2M_250K)) { //#ifdef ARW // if(Dtu3Detail.Property.Anti_Theft_Switch == 1) // { // for(j = 0; j < 4; j++) // { // PortNO++; // if((MIMajor[PortNO].Property.Port == MI_250W) || (MIMajor[PortNO].Property.Port == MI_500W_A) || (MIMajor[PortNO].Property.Port == MI_1000W_A)) // { // break; // } // } // } // else // { // PortNO++; // } //#else PortNO++; //#endif if(PortNO >= Dtu3Detail.Property.PortNum) { PortNO = 0; // UsartNrf_ClearMIReal_HistoryEnergy(); // InverterReal_Read(MIReal); Uart_SendBufferLen = 0; Uart_CurSendMainCmd = 0; Uart_CurRecMainCmd = 0; } } return true; //next component } else { PollCnt++; if(PollCnt >= 2) { UsartNrf_Process_LedShow(false, 10); PollCnt = 0; Uart_CurSendMainCmd = 0; Uart_CurRecMainCmd = 0; Uart_SendBufferLen = 0; //#ifdef ARW // if(Dtu3Detail.Property.Anti_Theft_Switch == 1) // { // for(j = 0; j < 4; j++) // { // PortNO++; // if((MIMajor[PortNO].Property.Port == MI_250W) || (MIMajor[PortNO].Property.Port == MI_500W_A) || (MIMajor[PortNO].Property.Port == MI_1000W_A)) // { // break; // } // } // } // else // { // PortNO++; // } //#else PortNO++; //#endif if(PortNO >= Dtu3Detail.Property.PortNum) { PortNO = 0; // UsartNrf_ClearMIReal_HistoryEnergy(); // InverterReal_Read(MIReal); } return true; } return true; } return true; } /*********************************************** ** Function name: Get the micro-inverse model ** Descriptions: ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_GetPollCmdOfRealTime(void) { uint8_t Cmd; switch(MIMajor[PortNO].Property.Port) { case MI_250W: Cmd = REQ_A_DAT; break; case MI_500W_A: Cmd = REQ_A_DAT; break; case MI_500W_B: Cmd = REQ_B_DAT; break; case MI_1000W_A: Cmd = REQ_A1_DAT_1000; break; case MI_1000W_B: Cmd = REQ_A2_DAT_1000; break; case MI_1000W_C: Cmd = REQ_B1_DAT_1000; break; case MI_1000W_D: Cmd = REQ_B2_DAT_1000; break; default: break; } return Cmd; } bool UsartNrf_GetPortNOOfNetCmd(void) { if(MIMajor[PortNO].Property.Port == MI_250W) { PortNO = PortNO + 1; } else if(MIMajor[PortNO].Property.Port == MI_500W_A) { PortNO = PortNO + 2; } else if(MIMajor[PortNO].Property.Port == MI_1000W_A) { PortNO = PortNO + 3; } else { for(PortNO = PortNO; PortNO < Dtu3Detail.Property.PortNum;) { if((MIMajor[PortNO].Property.Port != MI_250W) && (MIMajor[PortNO].Property.Port != MI_500W_A) && (MIMajor[PortNO].Property.Port != MI_1000W_A)) { PortNO = PortNO + 1; } else { return true; } } } if(PortNO >= Dtu3Detail.Property.PortNum) { Uart_SendBufferLen = 0; Uart_CurSendMainCmd = 0; Uart_CurRecMainCmd = 0; IsPolling = true; PortNO = 0; UsartNrf_SendLoop_ResetBaud(); return false; //no need to send } return true; //need to send } /*********************************************** ** Function name: Do you need to resend ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ bool HasSetCurrentInverterOk(void) { static uint8_t NotMatchCnt = 0; static uint8_t NotMatchDownDatCnt = 0; static uint16_t NotMatchDownProCnt = 0; uint8_t CurMIPortNum; uint16_t i = 0; static uint16_t j = 0; if(UsartNrf_SendLoop_ReplyOK() == true) { NotMatchDownDatCnt = 0; NotMatchDownProCnt = 0; Uart_CurRecMainCmd = 0; Uart_SendBufferLen = 0; NotMatchCnt = 0; if((Uart_CurSendMainCmd != 0) && (Uart_CurSendMainCmd != CHANGE_MOD_2M_250K) && ((Uart_CurSendMainCmd != BROADCAST))) { Uart_CurSendMainCmd = 0; return UsartNrf_SendLoop_GetNextSetCmd(); } else if(Uart_CurSendMainCmd == BROADCAST) { MIReal[0].Data.NetStatus = NET_EXECUTION_COMPLETED; IsPolling = true; PortNO = 0; return false;// } else { Uart_CurSendMainCmd = 0; return true; //Baud rate You need to send a network command after receiving the receipt } } else { if((Uart_CurSendMainCmd != 0) && (Uart_CurSendMainCmd != CHANGE_MOD_2M_250K)) { if((Uart_CurSendMainCmd == DOWN_PRO) && (MIReal[PortNO].Data.NetCmd != NET_RESTART)) { if(Uart_CurrentReplyState == 3) { NotMatchDownProCnt = NotMatchDownProCnt + 10; } else { NotMatchDownProCnt++; } MIReal[PortNO].Data.NetStatus = (Index_Pro * 100) / TotalIndex_Pro; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } if(NotMatchDownProCnt > 300) //If you do not receive a receipt for 300 consecutive times, skip the micro-inverse { NotMatchDownProCnt = 0; MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; RightHexFile = false; Uart_CurrentReplyState = 0; return UsartNrf_SendLoop_GetNextSetCmd(); } else { MIReal[PortNO].Data.NetStatus = (Index_Pro * 100) / TotalIndex_Pro; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } return true; } } else if(MIReal[PortNO].Data.NetCmd == NET_DOWNLOAD_DAT) { NotMatchDownDatCnt++; if(NotMatchDownDatCnt > 30) { NotMatchDownDatCnt = 0; MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; myfree(TestGridOnFile); return UsartNrf_SendLoop_GetNextSetCmd(); } else { MIReal[PortNO].Data.NetStatus = (Index_Dat * 100) / TotalIndex_Dat; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } return true; } } else if(MIReal[PortNO].Data.NetCmd == NET_LOCK) { NotMatchCnt++; if(NotMatchCnt > 20)// { NotMatchCnt = 0; MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; return UsartNrf_SendLoop_GetNextSetCmd(); } return true; } else if((MIReal[PortNO].Data.NetCmd == NET_INVERTER_HW_INFOR) || (MIReal[PortNO].Data.NetCmd == NET_TERMINAL_INFOR)) { NotMatchCnt++; if(NotMatchCnt > 3) { NotMatchCnt = 0; if(MIReal[PortNO].Data.NetCmd == NET_INVERTER_HW_INFOR) { MIReal[PortNO].Data.NetStatus = NET_NOT_EXECUTED; MIReal[PortNO].Data.NetCmd = NET_TERMINAL_INFOR; memset(&MIDetail, 0, sizeof(InverterDetail)); //Clear MIDetail InverterDetail_Read(&MIDetail, PortNO, 1); //Read UsartNrf_Process_Version_InitInverter(); //Fill in 0 InverterDetail_Write(&MIDetail, PortNO, 1); // Write 0 return UsartNrf_SendLoop_GetNextSetCmd(); } else if(MIReal[PortNO].Data.NetCmd == NET_TERMINAL_INFOR) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { if((MIReal[i].Data.NetStatus == NET_NOT_EXECUTED) && ((MIReal[i].Data.NetCmd == NET_INVERTER_HW_INFOR) || (MIReal[i].Data.NetCmd == NET_TERMINAL_INFOR))) { j++; } } if(j <= 0) { Dtu3Detail.Property.HasNotPolledVer = true; UsartNrf_ClearNetStatusAndCmd(); } else { j = 0; } memset(&MIDetail, 0, sizeof(InverterDetail)); //Clear MIDetail InverterDetail_Read(&MIDetail, PortNO, 1); //Read UsartNrf_Process_Version_InitInverterRf(); //Fill in 0 InverterDetail_Write(&MIDetail, PortNO, 1); // Write 0 return UsartNrf_SendLoop_GetNextSetCmd(); } } } else if(MIReal[PortNO].Data.NetCmd == NET_LIMIT_POEWR) { NotMatchCnt++; if(NotMatchCnt > 3) { NotMatchCnt = 0; if(MIReal[PortNO].Data.NetStatus == LOCAL_NOT_EXECUTED) { MIReal[PortNO].Data.NetStatus = NET_NOCMD; } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; } return UsartNrf_SendLoop_GetNextSetCmd(); } } else { if((Uart_CurSendMainCmd == REQ_A_DAT) || (Uart_CurSendMainCmd == REQ_B_DAT) || (Uart_CurSendMainCmd == REQ_A1_DAT_1000) || (Uart_CurSendMainCmd == REQ_B1_DAT_1000) || (Uart_CurSendMainCmd == REQ_A2_DAT_1000) || (Uart_CurSendMainCmd == REQ_B2_DAT_1000)) { NotMatchCnt = 0; } NotMatchCnt++; if(NotMatchCnt > 5) //Resend 5 times without response { NotMatchCnt = 0; MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; return UsartNrf_SendLoop_GetNextSetCmd(); } return true; } } else { Uart_CurSendMainCmd = 0; return true; } } return true; //Resend } /*********************************************** ** Function name: ** Descriptions: // Network command to nrf command ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Send_NetCmdToNrfCmd(void) { if((CurNetCmd == NET_DTU_HW_INFOR_RES) || (CurNetCmd == NET_DTU_HW_INFOR)) { MainCmd = REQ_RF_RVERSISON; SubCmd = 0; } else { switch(MIReal[PortNO].Data.NetCmd) { case NET_TURN_ON: SubCmd = CONTROL_ON_SUB; //Boot MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; break; case NET_TURN_OFF: SubCmd = CONTROL_OFF_SUB; //Shut down MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; break; case NET_LIMIT_POEWR: if(MIMajor[PortNO].Property.Acq_Switch == 0) { if((MIMajor[PortNO].Property.Id[0] < 0X50) && ((MIMajor[PortNO].Property.Pre_Id[1] == 0X60) || (MIMajor[PortNO].Property.Pre_Id[1] == 0X61))) { SubCmd = CONTROL_LIMIT_POWER_SUB; // Limit power } else { SubCmd = CONTROL_OFF_SUB; // Limit power } } else { SubCmd = CONTROL_LIMIT_POWER_SUB; // Limit power } MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; break; case NET_SET_PASSWORD: case NET_CANCEL_GUARD: SubCmd = CONTROL_LOCK_MI_SUB; //Set password MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; break; case NET_ZERO_EXPORT: //Anti-countercurrent MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF;; SubCmd = CONTROL_LIMIT_POWER_SUB; break; case NET_DOWNLOAD_DAT: //Download the grid-connected protection file MainCmd = DOWN_DAT; SubCmd = 0; break; case NET_DOWNLOAD_PRO: case NET_RESTART: // Download program / reset MainCmd = DOWN_PRO; SubCmd = 0; break; case NET_CLEAN_GFDI:: // Clear ground fault MainCmd = CLEAR_GFDI; SubCmd = 0; break; case NET_SEARCH_ID: //Search ID MainCmd = BROADCAST; SubCmd = 0; break; case NET_SET_ENERGY: //Set the power generation capacity MainCmd = RE_FISRT__CONFIRM_SET_ENERGY; SubCmd = RE_CONFIRM_SET_ENERGY_SUB; SubCmd = RE_FISRT_SET_ENERGY_SUB;// break; case NET_INVERTER_HW_INFOR: //Query inverter rf hardware information MainCmd = REQ_RF_SVERSISON; SubCmd = 0; break; case NET_DTU_HW_INFOR: // case NET_DTU_HW_INFOR_RES: //DUT rf hardware information MainCmd = REQ_RF_RVERSISON; SubCmd = 0; break; case NET_TERMINAL_INFOR: MainCmd = REQ_VERSISON; // Terminal inverter hardware and software information SubCmd = 0; break; case NET_SWITCH_BAUD: MainCmd = CHANGE_MOD_2M_250K; SubCmd = 0; break; case NET_UNLOCK: MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; SubCmd = CONTROL_UNLOCK_SUB; break; case NET_LOCK: MainCmd = CONTROL_LOCK_MI__LIMIT_POWER_ONOFF; if(MIReal[PortNO].Data.NetStatus == 50) { SubCmd = CONTROL_LOCK_SUB2; } else { SubCmd = CONTROL_LOCK_SUB1; } break; default: break; } } } /*********************************************** ** Function name: ** Descriptions: // Get the next command at boot time ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_GetNextInverterCmdOfVer(void) { uint8_t i; static uint8_t NotMatchCnt = 0; if((UsartNrf_SendLoop_ReplyOK() == true) || (MainCmd == 0) || (NotMatchCnt >= 5)) { Uart_CurSendMainCmd = 0; Uart_CurRecMainCmd = 0; Uart_SendBufferLen = 0; if(MainCmd == 0) { PortNO = 0; MainCmd = REQ_RF_RVERSISON; SubCmd = 0; } else if(MainCmd == REQ_RF_RVERSISON) { if(Dtu3Detail.Property.PortNum <= 0) { return; } } NotMatchCnt = 0; } else { NotMatchCnt++; Uart_CurRecMainCmd = 0; } } /*********************************************** ** Function name: ** Descriptions: // Package reset command ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint16_t UartNrf_Send_PackResertMi(uint8_t *target_adr, uint8_t *rout_adr, uint8_t cmd) { uint8_t i = 0, j = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX; //Header temp_dat[0] = DOWN_PRO; //Instruction memcpy(&temp_dat[1], target_adr, 4); //1234 memcpy(&temp_dat[5], rout_adr, 4); //5678 temp_dat[9] = 0x10; // temp_dat[10] = 0; temp_dat[11] = 0; temp_dat[12] = 0; // temp_dat[13] = 0x12; temp_dat[14] = 0xee; //CRC temp_dat[15] = Get_crc_xor(&temp_dat[0], 15); //Forward replacement i = ForwardSubstitution(&(Uart_SendBuffer[1]), temp_dat, 16); // Forward replacement Uart_SendBuffer[17] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return 18; } /*********************************************** ** Function name: ** Descriptions: // Package Lock / unlock command ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_PackLockAndUnlockCommand(uint8_t *target_adr, uint8_t *rout_adr, int8_t MainCmd, uint16_t SubCmd) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX;// temp_dat[0] = MainCmd; //Control micro-inverse lock memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = SubCmd >> 8; temp_dat[10] = SubCmd & 0XFF; //Sub-command temp_dat[11] = Get_crc_xor(&temp_dat[0], 11); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 12); //Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: ** Descriptions: // DTU information packaging ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ uint8_t UsartNrf_Send_Pack_DTU_DTUPara(uint8_t *target_adr, uint8_t *rout_adr, uint8_t MainCmd, uint8_t SubCmd) { uint8_t i = 0; uint8_t temp_dat[UART_LEN]; uint8_t temp_wifi_ver[3]; uint8_t temp_gprs_ver[4]; memset(temp_dat, 0, sizeof(temp_dat)); Uart_SendBuffer[0] = STX;// temp_dat[0] = MainCmd; memcpy(&temp_dat[1], target_adr, 4); memcpy(&temp_dat[5], rout_adr, 4); temp_dat[9] = SubCmd; memcpy(&temp_dat[10], &(Dtu3Major.Property.DtuHw_Ver[0]), 2); memcpy(&temp_dat[12], &(Dtu3Major.Property.DtuSw_Ver[0]), 2); memcpy(&temp_dat[14], &(Dtu3Major.Property.RfHw_Ver[2]), 2); memcpy(&temp_dat[16], &(Dtu3Major.Property.RfFw_Ver[2]), 2); if((Dtu3Major.Property.Wifi_Vsn[0]) >= '0') { temp_wifi_ver[0] = Dtu3Major.Property.Wifi_Vsn[0] - '0'; } else { temp_wifi_ver[0] = Dtu3Major.Property.Wifi_Vsn[0]; } if((Dtu3Major.Property.Wifi_Vsn[2]) >= '0') { temp_wifi_ver[1] = Dtu3Major.Property.Wifi_Vsn[2] - '0'; } else { temp_wifi_ver[1] = Dtu3Major.Property.Wifi_Vsn[2]; } if((Dtu3Major.Property.Wifi_Vsn[4]) >= '0') { temp_wifi_ver[2] = Dtu3Major.Property.Wifi_Vsn[4] - '0'; } else { temp_wifi_ver[2] = Dtu3Major.Property.Wifi_Vsn[4]; } memcpy(&temp_dat[18], &temp_wifi_ver[0], 3); if((Dtu3Major.Property.Gprs_Ver[7]) >= '0') { temp_gprs_ver[0] = Dtu3Major.Property.Gprs_Ver[7] - '0'; } else { temp_gprs_ver[0] = Dtu3Major.Property.Gprs_Ver[7]; } if((Dtu3Major.Property.Gprs_Ver[8]) >= '0') { temp_gprs_ver[1] = Dtu3Major.Property.Gprs_Ver[8] - '0'; } else { temp_gprs_ver[1] = Dtu3Major.Property.Gprs_Ver[8]; } if((Dtu3Major.Property.Gprs_Ver[9]) >= '0') { temp_gprs_ver[2] = Dtu3Major.Property.Gprs_Ver[9] - '0'; } else { temp_gprs_ver[2] = Dtu3Major.Property.Gprs_Ver[9]; } if((Dtu3Major.Property.Gprs_Ver[10]) >= '0') { temp_gprs_ver[3] = Dtu3Major.Property.Gprs_Ver[10] - '0'; } else { temp_gprs_ver[3] = Dtu3Major.Property.Gprs_Ver[10]; } memcpy(&temp_dat[21], &temp_gprs_ver[2], 2); temp_dat[23] = Dtu3Major.Property.wifi_RSSI; temp_dat[24] = connect_server; temp_dat[25] = Dtu3Major.Property.GPRS_CSQ; temp_dat[26] = Get_crc_xor(&temp_dat[0], 26); //CRC i = ForwardSubstitution(&Uart_SendBuffer[1], &temp_dat[0], 27); // Forward replacement Uart_SendBuffer[(i + 1)] = ETX; //Tail memset(temp_dat, 0, sizeof(temp_dat)); return (i + 2); } /*********************************************** ** Function name: Polling the serial port to send data ** Descriptions: ** input parameters: ** output parameters: ** Returned value: The NET_TURN_ON NET_TURN_OFF NET_DOWNLOAD_DAT NET_DOWNLOAD_PRO NET_SET_ENERGY setting is currently not returned. *************************************************/ void UsartNrf_Send_Loop() { static uint32_t SendTime = 0; uint8_t Cmd; uint8_t i; uint16_t j; if((Uart_CurRecMainCmd != REQ_GET_DTU_PARA) && (((LocalTime >= SendTime) && (LocalTime - SendTime >= LocalTime_300Ms)) || ((LocalTime < SendTime) && (LocalTime_900000Ms - SendTime + LocalTime >= LocalTime_300Ms)))) { SendTime = LocalTime; // if((MIReal[0].Data.NetCmd == NET_NOPORT) && (MIReal[0].Data.NetStatus == NET_EXECUTION_COMPLETED)) if((CurNetCmd == NET_NOPORT) && ((MIReal[0].Data.NetCmd != NET_REGISTER_ID) && (MIReal[0].Data.NetStatus != NET_NOT_EXECUTED))) { if(Dtu3Detail.Property.PortNum > 0) //Tooling registration id { IsPolling = true; // Poll as usual } else { return; } } else { if((MIReal[0].Data.NetCmd == NET_REGISTER_ID) && (MIReal[0].Data.NetStatus == NET_NOT_EXECUTED)) { IsPolling = false; } else if((CurNetCmd == NET_DTU_HW_INFOR_RES) || (CurNetCmd == NET_DTU_HW_INFOR)) { IsPolling = false; } else if((MIReal[PortNO].Data.NetCmd == NET_INIT) && ((MIReal[PortNO].Data.NetStatus == NET_NOCMD) || (MIReal[PortNO].Data.NetStatus == NET_NOT_EXECUTED))) { IsPolling = true; } //Regardless of the rest of the commands } if(IsPolling == false) { if(MIReal[0].Data.NetCmd == NET_REGISTER_ID) { InverterMajor_Delete(); InverterDetail_Delete(); Dtu3Detail.Property.PortNum = 0; UsartNrf_GetDtu3PortNum(); //Get the total number of components System_DtuDetail_Write(&Dtu3Detail); //Number of storage components UsartNrf_InitPVPannelToMIMajor(); //Arrange Id bits InverterMajor_Write(MIMajor, Dtu3Detail.Property.PortNum); //Write the InverterMajor file InverterReal_Delete();// #ifdef DTU3PRO #ifndef DEBUG #ifdef DTU_IAP IWDG_Feed(); #endif #endif #else WDG_Feed(); //Feed the dog #endif DeleteHistoryData(); //Historical data #ifdef DTU3PRO #ifndef DEBUG #ifdef DTU_IAP IWDG_Feed(); #endif #endif #else WDG_Feed(); //Feed the dog #endif UsartNrf_ClearMI_DailyEnergy(); //Clear all real-time data UsartNrf_ClearMIReal_HistoryEnergy(); //Clear historical power generation UsartNrf_ClearNetStatusAndCmd(); //Clear the number of connections and connection flags if(Dtu3Detail.Property.PortNum > 0) { UsartNrf_Process_LedShow(true, 10); } // MIReal[0].Data.NetCmd = NET_DTU_HW_INFOR; // MIReal[0].Data.NetStatus = NET_NOT_EXECUTED; CurNetCmd = NET_DTU_HW_INFOR; MIReal[0].Data.NetCmd = NET_INIT; MIReal[0].Data.NetStatus = NET_EXECUTION_COMPLETED; Dtu3Detail.Property.HasNotPolledVer = false; PortNO = 0; } else if((MIReal[PortNO].Data.NetCmd >= NET_TURN_ON) && (MIReal[PortNO].Data.NetCmd <= NET_RESTART)) { CurNetCmd = NET_INIT; if((GetInveterBaudType(MIMajor[PortNO].Property.Pre_Id) != Uart_CurrentDtuBaud) || (Uart_CurrentDtuBaud == Device_INIT_BAUD)) // Determine whether the current dtu baud rate and the inverter baud rate match { MainCmd = CHANGE_MOD_2M_250K; Uart_SendBufferLen = UsartNrf_Send_PackSetNrfBaudRateInTheAir(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, GetInveterBaudType(MIMajor[PortNO].Property.Pre_Id)); } else { UsartNrf_Send_NetCmdToNrfCmd(); switch(MIReal[PortNO].Data.NetCmd) { case NET_TURN_ON: //CONTROL_LOCK_MI__LIMIT_POWER_ONOFF: //BOOT { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackSetTurnOnOffCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } break; } case NET_TURN_OFF: //Shut down { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackSetTurnOnOffCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } break; } case NET_LIMIT_POEWR: //Limit power { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackSetPowerLimitCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } break; } case NET_LOCK: case NET_UNLOCK: { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackLockAndUnlockCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); // Send polling command } break; } //#ifdef ARW case NET_SET_PASSWORD: { if(Dtu3Detail.Property.Anti_Theft_Switch == 1) { if(HasSetCurrentInverterOk()) { if(MIReal[PortNO].Data.NetCmd == NET_SET_PASSWORD) { Uart_SendBufferLen = UsartNrf_Send_PackSetLockOnOffCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } } } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; IsPolling = true; return; } break; } case NET_CANCEL_GUARD: //Set password { if(Dtu3Detail.Property.Anti_Theft_Switch == 0) { if(HasSetCurrentInverterOk()) { memset(Dtu3Detail.Property.LockOldPassword, 0, 4); memset(Dtu3Detail.Property.LockNewPassword, 0, 4); memset(Dtu3Detail.Property.Lock_Time, 0, 2); Uart_SendBufferLen = UsartNrf_Send_PackSetLockOnOffCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; IsPolling = true; return; } break; } //#endif #ifdef ZEROEXPORT case NET_ZERO_EXPORT: //Anti-countercurrent { if(Dtu3Detail.Property.Zero_Export_Switch == 0) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; IsPolling = true; return; } else { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackSetRefluxPowerCommand(Dtu3Detail.Property.LimitPower_MyPower[0], MainCmd, SubCmd); } } break; } #endif case NET_DOWNLOAD_DAT: //DOWN_DAT when downloading the network-connected protection file { if(HasSetCurrentInverterOk()) { UsartNrf_Send_PackUpdateGridOnProFile(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id); } break; } case NET_DOWNLOAD_PRO: //DOWN_PRO download program { if(HasSetCurrentInverterOk()) { UsartNrf_Send_PackUpdateMiProgram(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id); } break; } case NET_SEARCH_ID: //Search Id (Guangfa command) { if(HasSetCurrentInverterOk()) { for(j = Dtu3Detail.Property.PortNum; j < PORT_LEN; j++) { memset(MIMajor[j].Property.Pre_Id, 0, 2); memset(MIMajor[j].Property.Id, 0, 4); MIMajor[j].Property.Port = MI_NO; } Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, 0); } break; } case NET_CLEAN_GFDI: case NET_SET_ENERGY: { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } break; } case NET_RESTART: { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UartNrf_Send_PackResertMi(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd); } break; } case NET_TERMINAL_INFOR: case NET_INVERTER_HW_INFOR: //Collect version number { if(HasSetCurrentInverterOk()) { Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } break; } default: break; } } Uart_CurSendMainCmd = MainCmd; Uart_CurSendSubCmd = SubCmd; } else if((CurNetCmd == NET_DTU_HW_INFOR_RES) || (CurNetCmd == NET_DTU_HW_INFOR)) { if(HasSetCurrentInverterOk()) { UsartNrf_Send_NetCmdToNrfCmd(); Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, MainCmd, SubCmd); } } Uart_CurSendMainCmd = MainCmd; } if((IsPolling == true) || (MIReal[PortNO].Data.NetCmd == NET_WAIT_DOWNLOAD_DAT) || (MIReal[PortNO].Data.NetCmd == NET_WAIT_DOWNLOAD_PRO)) { if(UsartNrf_HasPollCurInverterPort()) //Query the next component { if((GetInveterBaudType(MIMajor[PortNO].Property.Pre_Id) != Uart_CurrentDtuBaud) || (Uart_CurrentDtuBaud == Device_INIT_BAUD)) // Determine whether the current dtu baud rate and the inverter baud rate match { Uart_CurSendMainCmd = CHANGE_MOD_2M_250K; Uart_SendBufferLen = UsartNrf_Send_PackSetNrfBaudRateInTheAir(Dtu3Major.Property.Id, Dtu3Major.Property.Id, Uart_CurSendMainCmd, GetInveterBaudType(MIMajor[PortNO].Property.Pre_Id)); } else { Uart_CurSendMainCmd = UsartNrf_GetPollCmdOfRealTime(); //Get polling instruction //#ifdef ARW if(Dtu3Detail.Property.Anti_Theft_Switch == 1) { Uart_SendBufferLen = UsartNrf_Send_PackPollRfWithLockCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, Uart_CurSendMainCmd); } else { Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, Uart_CurSendMainCmd, 0); // Send polling command } //#else // Uart_SendBufferLen = UsartNrf_Send_PackBaseCommand(MIMajor[PortNO].Property.Id, MIMajor[PortNO].Property.Id, Uart_CurSendMainCmd, 0); // Send polling command //#endif } } } if(Uart_SendBufferLen <= 0) { return; } USART_ClearITPendingBit(UsartNrf, USART_IT_TC); USART_ClearFlag(UsartNrf, USART_FLAG_TC); UsartNrf_SendLoop_SetBaud(false); USART_SendData(UsartNrf, Uart_SendBuffer[0]); } } void UsartNrf_Process_Inverter250_RealTimeData_ARW(uint8_t *pBuffer) { static bool HasReset = true; uint16_t DailyEnergy = 0; uint16_t i; if(pBuffer[0] == ANSWER_REQ_ARW_DAT_ALL) { UsartNrf_Process_LedShow(true, 10); if(pBuffer[10] == 0X00) { if(UsartNrf_Process_ExceptionFilter(pBuffer, 11, 12, 700) == true) { memcpy(&(MIReal[PortNO].Data.PVVol[0]), &(pBuffer[11]), 2); } if(pBuffer[13] < 150) { memcpy(&(MIReal[PortNO].Data.PVCur[0]), &(pBuffer[13]), 1); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 14, 15, 5000) == true) { memcpy(&(MIReal[PortNO].Data.Power[0]), &(pBuffer[14]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 17, 18, 3000) == true) { DailyEnergy = (uint16_t)pBuffer[17] << 8 | pBuffer[18]; } if(UsartNrf_Process_ExceptionFilter(pBuffer, 20, 21, 7000) == true) { memcpy(&(MIReal[PortNO].Data.GridVol[0]), &(pBuffer[20]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 22, 23, 4000) == true) { memcpy(&(MIReal[PortNO].Data.Freque[0]), &(pBuffer[22]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 24, 25, 2000) == true) { memcpy(&(MIReal[PortNO].Data.Temper[0]), &(pBuffer[24]), 2); } } else if(pBuffer[10] == 0x11) { memcpy(&(MIReal[PortNO].Data.Run_Status[0]), &(pBuffer[11]), 2); memcpy(&(MIReal[PortNO].Data.Fault_Code[0]), &(pBuffer[13]), 2); } MIReal[PortNO].Data.Real_Time = RTC_Getsecond(); //MI daily power generation if(DailyEnergy >= MIReal[PortNO].Data.DailyEnergy) { MIReal[PortNO].Data.DailyEnergy = DailyEnergy; MIReal[PortNO].Data.HistoryEnergyH = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) >> 16; MIReal[PortNO].Data.HistoryEnergyL = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) & 0xffff; } } } void UsartNrf_Process_Inverter500_RealTimeData_ARW(uint8_t *pBuffer) { static bool HasReset = true; uint16_t DailyEnergy = 0; uint16_t i; if(pBuffer[0] == ANSWER_REQ_ARW_DAT_ALL) { UsartNrf_Process_LedShow(true, 10); if(pBuffer[10] == 0X00) { if(UsartNrf_Process_ExceptionFilter(pBuffer, 11, 12, 700) == true) { memcpy(&(MIReal[PortNO].Data.PVVol[0]), &(pBuffer[11]), 2); } if(pBuffer[13] < 150) { memcpy(&(MIReal[PortNO].Data.PVCur[0]), &(pBuffer[13]), 1); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 14, 15, 5000) == true) { memcpy(&(MIReal[PortNO].Data.Power[0]), &(pBuffer[14]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 17, 18, 3000) == true) { DailyEnergy = (uint16_t)pBuffer[17] << 8 | pBuffer[18]; //MI daily power generation if(DailyEnergy >= MIReal[PortNO].Data.DailyEnergy) { MIReal[PortNO].Data.DailyEnergy = DailyEnergy; MIReal[PortNO].Data.HistoryEnergyH = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) >> 16; MIReal[PortNO].Data.HistoryEnergyL = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) & 0xffff; } } if(UsartNrf_Process_ExceptionFilter(pBuffer, 20, 21, 700) == true) { memcpy(&(MIReal[PortNO + 1].Data.PVVol[0]), &(pBuffer[20]), 2); } if(pBuffer[22] < 150) { memcpy(&(MIReal[PortNO + 1].Data.PVCur[0]), &(pBuffer[22]), 1); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 23, 24, 5000) == true) { memcpy(&(MIReal[PortNO + 1].Data.Power[0]), &(pBuffer[23]), 2); } } else if(pBuffer[10] == 0x11) { DailyEnergy = DailyEnergy + ((uint32_t)pBuffer[11] << 24 | (uint32_t)pBuffer[12] << 16 | (uint32_t)pBuffer[13] << 8 | pBuffer[14]); //MI daily power generation if(DailyEnergy >= MIReal[PortNO].Data.DailyEnergy) { MIReal[PortNO].Data.DailyEnergy = DailyEnergy; MIReal[PortNO].Data.HistoryEnergyH = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) >> 16; MIReal[PortNO].Data.HistoryEnergyL = (DailyEnergyTemp[PortNO] + MIReal[PortNO].Data.DailyEnergy) & 0xffff; } if(UsartNrf_Process_ExceptionFilter(pBuffer, 15, 16, 4000) == true) { memcpy(&(MIReal[PortNO].Data.GridVol[0]), &(pBuffer[15]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 17, 18, 7000) == true) { memcpy(&(MIReal[PortNO].Data.Freque[0]), &(pBuffer[17]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 19, 20, 2000) == true) { memcpy(&(MIReal[PortNO].Data.Temper[0]), &(pBuffer[19]), 2); } memcpy(&(MIReal[PortNO].Data.Run_Status[0]), &(pBuffer[21]), 2); memcpy(&(MIReal[PortNO].Data.Fault_Code[0]), &(pBuffer[23]), 2); } MIReal[PortNO].Data.Real_Time = RTC_Getsecond(); } } void UsartNrf_Process_Inverter1000_RealTimeData_ARW(uint8_t *pBuffer) { static bool HasReset = true; uint16_t DailyEnergy[4] = {0}; uint8_t i; if(pBuffer[0] == ANSWER_REQ_ARW_DAT_ALL) { UsartNrf_Process_LedShow(true, 10); if(pBuffer[10] == 0X00) { if(UsartNrf_Process_ExceptionFilter(pBuffer, 11, 12, 700) == true) { memcpy(&(MIReal[PortNO].Data.PVVol[0]), &(pBuffer[11]), 2); } if(pBuffer[13] < 150) { memcpy(&(MIReal[PortNO].Data.PVCur[0]), &(pBuffer[13]), 1); } if(pBuffer[14] < 150) { memcpy(&(MIReal[PortNO + 1].Data.PVCur[0]), &(pBuffer[14]), 1); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 15, 16, 5000) == true) { memcpy(&(MIReal[PortNO].Data.Power[0]), &(pBuffer[15]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 17, 18, 5000) == true) { memcpy(&(MIReal[PortNO + 1].Data.Power[0]), &(pBuffer[17]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 19, 20, 700) == true) { memcpy(&(MIReal[PortNO + 2].Data.PVVol[0]), &(pBuffer[19]), 2); } if(pBuffer[21] < 150) { memcpy(&(MIReal[PortNO + 2].Data.PVCur[0]), &(pBuffer[21]), 1); } if(pBuffer[22] < 150) { memcpy(&(MIReal[PortNO + 3].Data.PVCur[0]), &(pBuffer[22]), 1); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 23, 24, 5000) == true) { memcpy(&(MIReal[PortNO + 2].Data.Power[0]), &(pBuffer[23]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 25, 26, 5000) == true) { memcpy(&(MIReal[PortNO + 3].Data.Power[0]), &(pBuffer[25]), 2); } } else if(pBuffer[10] == 0x01) { DailyEnergy[0] = DailyEnergy[0] + ((uint32_t)pBuffer[11] << 24 | (uint32_t)pBuffer[12] << 16 | (uint32_t)pBuffer[13] << 8 | pBuffer[14]); DailyEnergy[1] = DailyEnergy[1] + ((uint32_t)pBuffer[15] << 24 | (uint32_t)pBuffer[16] << 16 | (uint32_t)pBuffer[17] << 8 | pBuffer[18]); DailyEnergy[2] = DailyEnergy[2] + ((uint32_t)pBuffer[19] << 24 | (uint32_t)pBuffer[20] << 16 | (uint32_t)pBuffer[21] << 8 | pBuffer[22]); DailyEnergy[3] = DailyEnergy[3] + ((uint32_t)pBuffer[23] << 24 | (uint32_t)pBuffer[24] << 16 | (uint32_t)pBuffer[25] << 8 | pBuffer[26]); for(i = 0; i < 4; i++) { if(DailyEnergy[i] >= MIReal[PortNO + i].Data.DailyEnergy) { MIReal[PortNO + i].Data.DailyEnergy = DailyEnergy[i]; MIReal[PortNO + i].Data.HistoryEnergyH = (DailyEnergyTemp[PortNO + i] + MIReal[PortNO + i].Data.DailyEnergy) >> 16; MIReal[PortNO + i].Data.HistoryEnergyL = (DailyEnergyTemp[PortNO + i] + MIReal[PortNO + i].Data.DailyEnergy) & 0xffff; } } //MI daily power generation } else if(pBuffer[10] == 0x12) { if(UsartNrf_Process_ExceptionFilter(pBuffer, 11, 12, 2000) == true) { memcpy(&(MIReal[PortNO].Data.GridVol[0]), &(pBuffer[11]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 13, 14, 7000) == true) { memcpy(&(MIReal[PortNO].Data.Freque[0]), &(pBuffer[13]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 15, 16, 2000) == true) { memcpy(&(MIReal[PortNO].Data.Temper[0]), &(pBuffer[15]), 2); } memcpy(&(MIReal[PortNO].Data.Run_Status[0]), &(pBuffer[17]), 2); memcpy(&(MIReal[PortNO].Data.Fault_Code[0]), &(pBuffer[19]), 2); } MIReal[PortNO].Data.Real_Time = RTC_Getsecond(); } } /***********************************************/ void UsartNrf_Process_SaveHistoryEnergy(void) { static bool HasReset = true; calendar_obj calendar; uint16_t i; RTC_GetWorldTime(&calendar, Dtu3Detail.Property.timezone); if((HasReset == true) && (((calendar.hour == 23) && ((calendar.min >= 50) && (calendar.min <= 59))) && (PortNO >= Dtu3Detail.Property.PortNum - 1))) { UsartNrf_ClearMI_DailyEnergy(); InverterReal_Write(MIReal, Dtu3Detail.Property.PortNum); HasReset = false; } } /*********************************************** ** Function name: Real-time data collection of a single component ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_BaseDataPort(uint8_t *pBuffer, uint8_t i) { uint16_t DailyEnergy = 0; uint32_t TotalPower = 0; uint8_t j; UsartNrf_Process_LedShow(true, 10); switch(MIMajor[PortNO].Property.Port) { case MI_250W: case MI_500W_A: case MI_1000W_A: { j = 0; break; } case MI_500W_B: case MI_1000W_B: { j = 1; break; } case MI_1000W_C: { j = 2; break; } case MI_1000W_D: { j = 3; break; } default: break; } if(UsartNrf_Process_ExceptionFilter(pBuffer, 10, 11, 700) == true) { memcpy(&(MIReal[PortNO - j + i].Data.PVVol[0]), &(pBuffer[10]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 12, 13, 150) == true) { memcpy(&(MIReal[PortNO - j + i].Data.PVCur[0]), &(pBuffer[12]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 14, 15, 4000) == true) { memcpy(&(MIReal[PortNO - j + i].Data.GridVol[0]), &(pBuffer[14]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 16, 17, 7000) == true) { memcpy(&(MIReal[PortNO - j + i].Data.Freque[0]), &(pBuffer[16]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 18, 19, 5000) == true) { memcpy(&(MIReal[PortNO - j + i].Data.Power[0]), &(pBuffer[18]), 2); } if(UsartNrf_Process_ExceptionFilter(pBuffer, 20, 21, 3000) == true) { DailyEnergy = (uint16_t)pBuffer[20] << 8 | pBuffer[21]; } if(UsartNrf_Process_ExceptionFilter(pBuffer, 22, 23, 2000) == true) { memcpy(&(MIReal[PortNO - j + i].Data.Temper[0]), &(pBuffer[22]), 2); } if((pBuffer[1] >= ANSWER_REQ_A1_DAT_1000) && (pBuffer[1] <= ANSWER_REQ_B2_DAT_1000)) { MIReal[PortNO - j + i].Data.Run_Status[1] = pBuffer[24]; MIReal[PortNO - j + i].Data.Fault_Num[1] = pBuffer[25]; MIReal[PortNO - j + i].Data.Fault_Code[1] = pBuffer[26]; } MIReal[PortNO - j + i].Data.Real_Time = RTC_Getsecond(); if(((PortNO == 0) || (PortNO == 1)) && (DailyEnergy > 0)) { printf("1"); } //MI daily power generation if(DailyEnergy >= MIReal[PortNO - j + i].Data.DailyEnergy) { MIReal[PortNO - j + i].Data.DailyEnergy = DailyEnergy; MIReal[PortNO - j + i].Data.HistoryEnergyH = (DailyEnergyTemp[PortNO - j + i] + MIReal[PortNO - j + i].Data.DailyEnergy) >> 16; MIReal[PortNO - j + i].Data.HistoryEnergyL = (DailyEnergyTemp[PortNO - j + i] + MIReal[PortNO - j + i].Data.DailyEnergy) & 0xffff; } } /*********************************************** ** Function name: Event collection when a single component counts ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_BaseEventPort(uint8_t *pBuffer, uint8_t i) { uint8_t j; switch(MIMajor[PortNO].Property.Port) { case MI_250W: case MI_500W_A: { j = 0; break; } case MI_500W_B: { j = 1; break; } default: break; } memcpy(&(MIReal[PortNO - j + i].Data.Run_Status[0]), &(pBuffer[10]), 2); memcpy(&(MIReal[PortNO - j + i].Data.Fault_Code[0]), &(pBuffer[12]), 2); memcpy(&(MIReal[PortNO - j + i].Data.Fault_Num), &(pBuffer[14]), 2); } /*********************************************** ** Function name: Processing 250w micro-inverse receipt information ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter250_RealTimeData(uint8_t *pBuffer) { switch(pBuffer[1]) { case ANSWER_REQ_A_DAT: UsartNrf_Process_BaseDataPort(pBuffer, 0); break; case ANSWER_REQ_A_EVENT: UsartNrf_Process_BaseEventPort(pBuffer, 0); break; default: break; } } /*********************************************** ** Function name: Processing 500w micro-inverse receipt information ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter500_RealTimeData(uint8_t *pBuffer) { switch(pBuffer[1]) { case ANSWER_REQ_A_DAT: //89 UsartNrf_Process_BaseDataPort(pBuffer, 0); break; case ANSWER_REQ_A_EVENT: //88 UsartNrf_Process_BaseEventPort(pBuffer, 0); break; case ANSWER_REQ_B_DAT: //91 UsartNrf_Process_BaseDataPort(pBuffer, 1); break; case ANSWER_REQ_B_EVENT: //92 UsartNrf_Process_BaseEventPort(pBuffer, 1); break; default: break; } } /*********************************************** ** Function name: Guangfa command search id reception and processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter_NetCmd_SearchId(uint8_t *pBuffer) { static uint16_t PortCnt = 0; uint16_t i; if(PortCnt == 0) { PortCnt = Dtu3Detail.Property.PortNum; //Total number of connections } for(i = 0; i < PortCnt; i++) { if(((memcmp(&(pBuffer[10]), MIMajor[i].Property.Pre_Id, 2) != 0) || (memcmp(&(pBuffer[12]), MIMajor[i].Property.Id, 4) != 0)) && ((pBuffer[11] & 0xf0) <= 0x60)) { memcpy(MIMajor[PortCnt].Property.Pre_Id, (&pBuffer[10]), 2); memcpy(MIMajor[PortCnt].Property.Id, (&pBuffer[2]), 4); // The original network id remains unchanged, and the subsequent insert id if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_500) { if((MIMajor[PortCnt].Property.Port != MI_500W_A) && (MIMajor[PortCnt].Property.Port != MI_500W_B)) { memcpy(&(MIMajor[PortCnt + 1].Property.Id[0]), &MIMajor[PortCnt].Property.Id[0], sizeof(MIMajor[PortCnt].Property.Id)); memcpy(&(MIMajor[PortCnt + 1].Property.Pre_Id[0]), &MIMajor[PortCnt].Property.Pre_Id[0], sizeof(MIMajor[PortCnt].Property.Pre_Id)); MIMajor[PortCnt].Property.Port = MI_500W_A; MIMajor[PortCnt + 1].Property.Port = MI_500W_B; Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 2; } } else if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_1000) { if((MIMajor[PortCnt].Property.Port != MI_1000W_A) && (MIMajor[PortCnt].Property.Port != MI_1000W_B) && (MIMajor[PortCnt].Property.Port != MI_1000W_C) && (MIMajor[PortCnt].Property.Port != MI_1000W_D)) { memcpy(&MIMajor[PortCnt + 1].Property.Id[0], &MIMajor[PortCnt].Property.Id[0], sizeof(MIMajor[PortCnt].Property.Id)); memcpy(&MIMajor[PortCnt + 1].Property.Pre_Id[0], &MIMajor[PortCnt].Property.Pre_Id[0], sizeof(MIMajor[PortCnt].Property.Pre_Id)); memcpy(&MIMajor[PortCnt + 2].Property.Id[0], &MIMajor[PortCnt].Property.Id[0], sizeof(MIMajor[PortCnt].Property.Id)); memcpy(&MIMajor[PortCnt + 2].Property.Pre_Id[0], &MIMajor[PortCnt].Property.Pre_Id[0], sizeof(MIMajor[PortCnt].Property.Pre_Id)); memcpy(&MIMajor[PortCnt + 3].Property.Id[0], &MIMajor[PortCnt].Property.Id[0], sizeof(MIMajor[PortCnt].Property.Id)); memcpy(&MIMajor[PortCnt + 3].Property.Pre_Id[0], &MIMajor[PortCnt].Property.Pre_Id[0], sizeof(MIMajor[PortCnt].Property.Pre_Id)); MIMajor[PortCnt].Property.Port = MI_1000W_A; MIMajor[PortCnt + 1].Property.Port = MI_1000W_B; MIMajor[PortCnt + 2].Property.Port = MI_1000W_C; MIMajor[PortCnt + 3].Property.Port = MI_1000W_D; Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 4; } } else if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_250) { MIMajor[PortCnt].Property.Port = MI_250W; Dtu3Detail.Property.PortNum = Dtu3Detail.Property.PortNum + 1; } if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_250) { PortCnt = PortCnt + 1; i = i + 1; } else if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_500) { PortCnt = PortCnt + 2; i = i + 2; } else if(UsartNrf_GetInvterType(MIMajor[PortCnt].Property.Pre_Id) == Inverter_1000) { PortCnt = PortCnt + 4; i = i + 4; } MIReal[PortNO].Data.NetStatus = (PortCnt * 100) / PORT_LEN;; if(PortCnt >= PORT_LEN) { return; } return; } } return; } /*********************************************** ** Function name: Inverter version reception and processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Version_Inverter(uint8_t *pBuffer) { InverterDetail_Read(&MIDetail, PortNO, 1); uint16_t i = 0; static uint16_t j = 0; if(pBuffer[10] == 0x00) { MIDetail.Property.USFWBuild_VER = ((uint16_t)pBuffer[11] << 8) | pBuffer[12]; MIDetail.Property.AppFWBuild_VER = ((uint16_t)pBuffer[13] << 8) | pBuffer[14]; MIDetail.Property.AppFWBuild_YYYY = ((uint16_t)pBuffer[15] << 8) | pBuffer[16]; MIDetail.Property.AppFWBuild_MMDD = ((uint16_t)pBuffer[17] << 8) | pBuffer[18]; MIDetail.Property.AppFWBuild_HHMM = ((uint16_t)pBuffer[19] << 8) | pBuffer[20]; MIDetail.Property.AppFW_PNH = ((uint16_t)pBuffer[21] << 8) | pBuffer[22]; MIDetail.Property.AppFW_PNL = ((uint16_t)pBuffer[23] << 8) | pBuffer[24]; MIDetail.Property.HW_VER = ((uint16_t)pBuffer[25] << 8) | pBuffer[26]; InverterDetail_Write(&MIDetail, PortNO, 1); } else if(pBuffer[10] == 0x01) { MIDetail.Property.HW_PNH = ((uint16_t)pBuffer[11] << 8) | pBuffer[12]; MIDetail.Property.HW_PNL = ((uint16_t)pBuffer[13] << 8) | pBuffer[14]; MIDetail.Property.HW_FB_TLmValue = ((uint16_t)pBuffer[15] << 8) | pBuffer[16]; MIDetail.Property.HW_FB_ReSPRT = ((uint16_t)pBuffer[17] << 8) | pBuffer[18]; MIDetail.Property.HW_GridSamp_ResValule = ((uint16_t)pBuffer[19] << 8) | pBuffer[20]; MIDetail.Property.HW_ECapValue = ((uint16_t)pBuffer[21] << 8) | pBuffer[22]; MIDetail.Property.Matching_AppFW_PNH = ((uint16_t)pBuffer[23] << 8) | pBuffer[24]; MIDetail.Property.Matching_AppFW_PNL = ((uint16_t)pBuffer[25] << 8) | pBuffer[26]; InverterDetail_Write(&MIDetail, PortNO, 1); } else if(pBuffer[10] == 0x12) { MIDetail.Property.AppFW_MINVER = ((uint16_t)pBuffer[11] << 8) | pBuffer[12]; MIDetail.Property.HW_CRCValue = ((uint16_t)pBuffer[13] << 8) | pBuffer[14]; MIDetail.Property.CRC_ALL = ((uint16_t)pBuffer[15] << 8) | pBuffer[16]; InverterDetail_Write(&MIDetail, PortNO, 1); } MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; for(i = 0; i < Dtu3Detail.Property.PortNum; i++) { if((MIReal[i].Data.NetStatus == NET_NOT_EXECUTED) && ((MIReal[i].Data.NetCmd == NET_INVERTER_HW_INFOR) || (MIReal[i].Data.NetCmd == NET_TERMINAL_INFOR))) { j++; } } if(j <= 0) { Dtu3Detail.Property.HasNotPolledVer = true; UsartNrf_ClearNetStatusAndCmd(); } else { j = 0; } } /*********************************************** ** Function name: DTU rf version number reception processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter_Version_DtuRf(uint8_t *pBuffer) { memcpy(&(Dtu3Major.Property.Id), &(pBuffer[13]), 4); memcpy(&(Dtu3Major.Property.Pre_Id), &(pBuffer[11]), 2); if(memcmp(&(pBuffer[18]), Dtu3Major.Property.RfHw_Ver, 4) != 0) { memcpy(&(Dtu3Major.Property.RfHw_Ver), &(pBuffer[17]), 4); } if(memcmp(&(pBuffer[21]), Dtu3Major.Property.RfFw_Ver, 4) != 0) { memcpy(&(Dtu3Major.Property.RfFw_Ver), &(pBuffer[21]), 4); } if(CurNetCmd == NET_DTU_HW_INFOR_RES) //When restarting { if(Dtu3Detail.Property.PortNum <= 0) { // MIReal[0].Data.NetCmd = NET_NOPORT; // MIReal[0].Data.NetStatus = NET_EXECUTION_COMPLETED; CurNetCmd = NET_NOPORT; } else { //MIReal[0].Data.NetStatus = NET_EXECUTION_COMPLETED; CurNetCmd = NET_INIT; } } else if(CurNetCmd == NET_DTU_HW_INFOR) //When networking { for(PortNO = 0; PortNO <= Dtu3Detail.Property.PortNum; PortNO++) { if((MIMajor[PortNO].Property.Port == MI_250W) || (MIMajor[PortNO].Property.Port == MI_500W_A) || (MIMajor[PortNO].Property.Port == MI_1000W_A)) { MIReal[PortNO].Data.NetCmd = NET_INVERTER_HW_INFOR; MIReal[PortNO].Data.NetStatus = NET_NOT_EXECUTED; } } CurNetCmd = NET_INIT; } PortNO = 0; System_DtuMajor_Write(&Dtu3Major); } /*********************************************** ** Function name: rf radio frequency signal processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter_Version_InverterRf(uint8_t *pBuffer) { //memset(&MIDetail,0,sizeof(InverterDetail)); InverterDetail_Read(&MIDetail, PortNO, 1); //Inverter RF hardware and software version memcpy(&(MIDetail.Property.NRF_HardVersion), &(pBuffer[17]), 4); memcpy(&(MIDetail.Property.NRF_SoftVersion), &(pBuffer[21]), 4); InverterDetail_Write(&MIDetail, PortNO, 1); //Inverter RF hardware and software version MIReal[PortNO].Data.NetCmd = NET_TERMINAL_INFOR; MIReal[PortNO].Data.NetStatus = NET_NOT_EXECUTED; } /*********************************************** ** Function name: Micro-inverse lock unlocking receipt processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter_NetCmd_LockOnOff(uint8_t *pBuffer) { if(pBuffer[12] == 0) { memcpy(Dtu3Detail.Property.LockNewPassword, &(pBuffer[13]), 4); memcpy(Dtu3Detail.Property.Lock_Time, &(pBuffer[17]), 2); System_DtuDetail_Write(&Dtu3Detail); } } /*********************************************** ** Function name: Micro-inverse version polling receipt processing ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter_Version(uint8_t *pBuffer) { switch(pBuffer[1]) { case ANSWER_REQ_VERSISON: //Micro inverse version number UsartNrf_Process_Version_Inverter(pBuffer); break; case ANSWER_REQ_RF_RVERSISON: //DTU rf version UsartNrf_Process_Inverter_Version_DtuRf(pBuffer); break; case ANSWER_REQ_RF_SVERSISON: //Micro inverse rf version UsartNrf_Process_Inverter_Version_InverterRf(pBuffer); break; default: break; } } /*********************************************** ** Function name: ** Descriptions: // nrf command processing of tape commands (switch on and off, power limit, lock, unlock) ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UartNrf_Process_Inverter_NetCmd_MultiCommand(uint8_t *pBuffer) { Uart_CurRecSubCmd = ((uint16_t)pBuffer[10] << 8) | pBuffer[11]; if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_LOCK_MI_SUB) //Anti-theft { if(pBuffer[12] == 0) { memcpy(Dtu3Detail.Property.LockNewPassword, &(pBuffer[13]), 4); memcpy(Dtu3Detail.Property.Lock_Time, &(pBuffer[17]), 2); MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED;// System_DtuDetail_Write(&Dtu3Detail); } //Receipt lock micro inverter sub-command else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; } } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_LIMIT_POWER_SUB) { if((MIReal[PortNO].Data.NetCmd == NET_LIMIT_POEWR) && (MIReal[PortNO].Data.NetStatus = LOCAL_NOT_EXECUTED)) //Restrict the charging machine { MIReal[PortNO].Data.NetStatus = NET_NOCMD; } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; //Receipt limit power sub-command } } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_ON_SUB) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; //Boot sub-command } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_OFF_SUB) { if((MIReal[PortNO].Data.NetCmd == NET_LIMIT_POEWR) && (MIReal[PortNO].Data.NetStatus == LOCAL_NOT_EXECUTED)) //Restrict input address { MIReal[PortNO].Data.NetStatus = NET_NOCMD; memset(MIReal[PortNO].Data.Power, 0, 2); } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; //Vertical } } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_LOCK_SUB1) { MIReal[PortNO].Data.NetStatus = 50; } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_LOCK_SUB2) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; } else if((((uint16_t)pBuffer[10] << 8) | pBuffer[11]) == CONTROL_UNLOCK_SUB) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; } } /*********************************************** ** Function name: ** Descriptions: // Process the download program command ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Process_Inverter_NetCmd_DownloadDat(uint8_t *pBuffer) { Uart_CurrentReplyState = pBuffer[10]; if(pBuffer[10] == 1) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; } else { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_FAILURE; } } /*********************************************** ** Function name: ** Descriptions: //Process grid-connected protection files ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Process_Inverter_NetCmd_DownloadPro(uint8_t *pBuffer) { if(MIReal[PortNO].Data.NetCmd == NET_DOWNLOAD_PRO) { if(Index_Pro <= 0x1E) { Uart_CurrentReplyState = 1; } else { Uart_CurrentReplyState = pBuffer[14]; memcpy(Uart_CurrentReplyAddr, &(pBuffer[10]), 4); } if(pBuffer[14] == 1) { MIReal[PortNO].Data.NetStatus = (Index_Pro * 100) / TotalIndex_Pro; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } if((memcmp(Uart_CurSendAddr, Uart_CurrentReplyAddr, 4) == 0) && ((Uart_CurrentReplyAddr[0] == 0) && (Uart_CurrentReplyAddr[1] == 0) && (Uart_CurrentReplyAddr[2] == 0) && (Uart_CurrentReplyAddr[3] == 0x01))) { memset(Uart_CurSendAddr, 0, 4); MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; Uart_CurrentReplyState = 0; RightHexFile = false; } else { UsartNrf_SendLoop_SetBaud(true); MIReal[PortNO].Data.NetStatus = (Index_Pro * 100) / TotalIndex_Pro; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } } } else { MIReal[PortNO].Data.NetStatus = (Index_Pro * 100) / TotalIndex_Pro; if(MIReal[PortNO].Data.NetStatus == 0) { MIReal[PortNO].Data.NetStatus = 1; } } } else if(MIReal[PortNO].Data.NetCmd == NET_RESTART) { MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; } } /*********************************************** ** Function name: ** Descriptions: Tooling to obtain DTU parameters ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Process_DTU_DTUPara(uint8_t *pBuffer) { if((pBuffer[10] == REQ_GET_DTU_PARA_SUB) && (pBuffer[1] == REQ_GET_DTU_PARA)) { memcpy(Dtu3Major.Property.DtuToolAddr, (&pBuffer[6]), 4); } } /*********************************************** ** Function name: ** Descriptions: Set the power generation capacity **********************************************/ void UsartNrf_Process_Inverter_NetCmd_SetEnergy(uint8_t *pBuffer) { if(pBuffer[10] == RE_FISRT_SET_ENERGY_SUB) { ; //Set the power generation sub-command for the first time } else if(pBuffer[10] == RE_CONFIRM_SET_ENERGY_SUB) { ; //Confirm the setting of the power generation sub-command } } ///************************************************/ //** Function name: //** Descriptions: //Total processing command function //** input parameters: ? //** output parameters: ? //** Returned value: ? //*************************************************/ void UsartNrf_Process_Inverter_NetCmd(uint8_t *pBuffer) { switch(pBuffer[1]) { case ANSWER_DOWN_DAT: UsartNrf_Process_Inverter_NetCmd_DownloadDat(pBuffer); break; case ANSWER_DOWN_PRO: UsartNrf_Process_Inverter_NetCmd_DownloadPro(pBuffer); break; case ANSWER_CONTROL_LOCK_MI__LIMIT_POEWR_ONOFF: UartNrf_Process_Inverter_NetCmd_MultiCommand(pBuffer); break; case ANSWER_SET__CONFIRM_ENERGY: UsartNrf_Process_Inverter_NetCmd_SetEnergy(pBuffer); break; case ANSWER_CHANGE_MOD_2M_250K: //Switch to each other 1M/250K Uart_CurrentDtuBaud = pBuffer[10]; break; case ANSWER_BROADCAST: UsartNrf_Process_Inverter_NetCmd_SearchId(pBuffer); break; case ANSWER_CLEAR_GFDI: MIReal[PortNO].Data.NetStatus = NET_EXECUTION_COMPLETED; break; default: break; } } /*********************************************** ** Function name: Processing 1000w micro-inverse receipt information ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Inverter1000_RealTimeData(uint8_t *pBuffer) { switch(pBuffer[1]) { case ANSWER_REQ_A1_DAT_1000: UsartNrf_Process_BaseDataPort(pBuffer, 0); break; case ANSWER_REQ_B1_DAT_1000: UsartNrf_Process_BaseDataPort(pBuffer, 2); break; case ANSWER_REQ_A2_DAT_1000: UsartNrf_Process_BaseDataPort(pBuffer, 1); break; case ANSWER_REQ_B2_DAT_1000: UsartNrf_Process_BaseDataPort(pBuffer, 3); break; default: break; } } /*********************************************** ** Function name: Main loop for processing serial port data ** Descriptions: ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_Process_Loop() { uint8_t SubData[MAX_SUB_DATA_LEN]; uint8_t DataLength; static uint32_t SendTime = 0; if((Uart_ProcessBuffer[0] == STX) && (Uart_ProcessBuffer[Uart_ReceiveBufferLen - 1] == ETX)) // { SendTime = LocalTime; memset(SubData, 0, MAX_SUB_DATA_LEN); DataLength = UsartNrf_Backward_substitution1(&(SubData[1]), &Uart_ProcessBuffer[1], Uart_ReceiveBufferLen - 2); #ifdef DEBUG1 if((DataLength == 0) || (DataLength > 35)) { printf("UReceiveLen:%d--DataLength:%d\r\n", Uart_ReceiveBufferLen, DataLength); } #endif Uart_ReceiveBufferLen = 0; SubData[0] = STX; SubData[DataLength + 1] = ETX; #ifdef DEBUG1 if(0 == DataLength) { printf("Get_crc_xor14\r\n"); } #endif if(Get_crc_xor(&(SubData[1]), DataLength - 1) == SubData[DataLength]) // { if(SubData[1] == REQ_GET_DTU_PARA) { UsartNrf_Process_DTU_DTUPara(SubData); //Tooling board test program Uart_SendBufferLen = UsartNrf_Send_Pack_DTU_DTUPara(Dtu3Major.Property.Id, Dtu3Major.Property.DtuToolAddr, ANSWER_REQ_GET_DTU_PARA, ANSWER_REQ_GET_DTU_PARA_SUB); USART_ClearITPendingBit(UsartNrf, USART_IT_TC); USART_ClearFlag(UsartNrf, USART_FLAG_TC); UsartNrf_SendLoop_SetBaud(false); USART_SendData(UsartNrf, Uart_SendBuffer[0]); Uart_CurRecMainCmd = REQ_GET_DTU_PARA; } else { if((((uint32_t)MIMajor[PortNO].Property.Id[0]) | MIMajor[PortNO].Property.Id[1] | MIMajor[PortNO].Property.Id[2] | MIMajor[PortNO].Property.Id[3] == 0) || (memcmp(Dtu3Major.Property.Id, &(SubData[2]), 4) == 0) || (memcmp(MIMajor[PortNO].Property.Id, &(SubData[2]), 4) == 0)) { Uart_CurRecMainCmd = SubData[1]; if(Dtu3Detail.Property.PortNum <= 0) { UsartNrf_Process_Inverter_Version(SubData); } else { if((Uart_CurRecMainCmd != ANSWER_REQ_RF_RVERSISON) && (Uart_CurRecMainCmd != ANSWER_CHANGE_MOD_2M_250K) && (Uart_CurRecMainCmd != BROADCAST)) { MIReal[PortNO].Data.LinkState = 1; } if(UsartNrf_GetInvterType(MIMajor[PortNO].Property.Pre_Id) == Inverter_250) { UsartNrf_Process_Inverter250_RealTimeData(SubData); UsartNrf_Process_Inverter_NetCmd(SubData); UsartNrf_Process_Inverter_Version(SubData); } else if((UsartNrf_GetInvterType(MIMajor[PortNO].Property.Pre_Id)) == Inverter_500) { UsartNrf_Process_Inverter500_RealTimeData(SubData); UsartNrf_Process_Inverter_NetCmd(SubData); UsartNrf_Process_Inverter_Version(SubData); } else if((UsartNrf_GetInvterType(MIMajor[PortNO].Property.Pre_Id)) == Inverter_1000) { UsartNrf_Process_Inverter1000_RealTimeData(SubData); UsartNrf_Process_Inverter_NetCmd(SubData); UsartNrf_Process_Inverter_Version(SubData); } } } } } } else { if(Uart_CurRecMainCmd == REQ_GET_DTU_PARA) { if(((LocalTime >= SendTime) && (LocalTime - SendTime >= 1000)) || ((LocalTime < SendTime) && (LocalTime_900000Ms - SendTime + LocalTime >= 1000))) { SendTime = LocalTime; Uart_CurRecMainCmd = ANSWER_REQ_GET_DTU_PARA; } } } UsartNrf_Process_SaveHistoryEnergy(); } //After processing, the network command must be cleared; /*********************************************** ** Function name: ** Descriptions: // Special handling of serial port interruption when DTU3pro is turned on ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void UsartNrf_Process_PowerOnGetDtuId() { uint8_t SubData[MAX_SUB_DATA_LEN]; uint8_t DataLength; DataLength = UsartNrf_Backward_substitution1(&(SubData[1]), &Uart_ProcessBuffer[1], Uart_ReceiveBufferLen - 2); Uart_ReceiveBufferLen = 0; SubData[0] = STX; SubData[DataLength + 1] = ETX; #ifdef DEBUG1 if(0 == DataLength) { printf("Get_crc_xor15\r\n"); } #endif if(Get_crc_xor(&(SubData[1]), DataLength - 1) == SubData[DataLength]) // { if(SubData[1] == ANSWER_REQ_RF_RVERSISON) { memcpy(&(Dtu3Major.Property.Id), &(SubData[13]), 4); memcpy(&(Dtu3Major.Property.Pre_Id), &(SubData[11]), 2); } } } /*********************************************** ** Function name: ** Descriptions: // DTU3pro serial port interrupt handling ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ #ifdef DTU3PRO void USART3_IRQHandler() { static uint8_t Uart_ReceiveBuffer[UART_LEN]; static uint8_t *pData = Uart_ReceiveBuffer; static uint8_t i = 1; static uint16_t Uart_ReceiveBufferLenTemp = 0; if(USART_GetFlagStatus(USART3, USART_IT_RXNE) != RESET) { *(pData) = USART_ReceiveData(USART3); if(Uart_ReceiveBuffer[0] == STX) { if(*pData == ETX) { Uart_ReceiveBufferLenTemp++; memset(Uart_ProcessBuffer, 0, UART_LEN); memcpy(Uart_ProcessBuffer, Uart_ReceiveBuffer, Uart_ReceiveBufferLenTemp); memset(Uart_ReceiveBuffer, 0, UART_LEN); Uart_ReceiveBufferLen = Uart_ReceiveBufferLenTemp; Uart_ReceiveBufferLenTemp = 0; pData = Uart_ReceiveBuffer; if(Uart_ReceiveBufferLen <= 4) { memset(Uart_ReceiveBuffer, 0, UART_LEN); pData = Uart_ReceiveBuffer; Uart_ReceiveBufferLen = 0; } if(nRFHasCheck != true) { UsartNrf_Process_PowerOnGetDtuId(); } } else { pData++; Uart_ReceiveBufferLenTemp++; if(Uart_ReceiveBufferLenTemp >= UART_LEN) { memset(Uart_ReceiveBuffer, 0, UART_LEN); pData = Uart_ReceiveBuffer; Uart_ReceiveBufferLenTemp = 0; } } } else { Uart_ReceiveBufferLenTemp = 0; pData = Uart_ReceiveBuffer; } USART_ClearITPendingBit(USART3, USART_IT_RXNE); USART_ClearITPendingBit(USART3, USART_FLAG_RXNE); } if(USART_GetFlagStatus(USART3, USART_FLAG_TC) != RESET) { if(i < (Uart_SendBufferLen)) { USART_SendData(USART3, Uart_SendBuffer[i]); i++; } else { i = 1; Uart_SendBufferLen = 0; } USART_ClearITPendingBit(USART3, USART_IT_TC); USART_ClearITPendingBit(USART3, USART_FLAG_TC); } USART_ClearITPendingBit(USART3, USART_IT_ORE); USART_ClearITPendingBit(USART3, USART_IT_IDLE); //USART2->DR; // Whether you need to make relevant configuration during initialization to use the serial port interrupt. } #else /*********************************************** ** Function name: ** Descriptions: // DTU3Lite serial port interrupt handling ** input parameters: ? ** output parameters: ? ** Returned value: ? *************************************************/ void USART2_IRQHandler() { static uint8_t Uart_ReceiveBuffer[UART_LEN]; static uint8_t *pData = Uart_ReceiveBuffer; static uint8_t i = 1; static uint16_t Uart_ReceiveBufferLenTemp = 0; if(USART_GetFlagStatus(USART2, USART_IT_RXNE) != RESET) { *(pData) = USART_ReceiveData(USART2); if(Uart_ReceiveBuffer[0] == STX) { if(*pData == ETX) { Uart_ReceiveBufferLenTemp++; memset(Uart_ProcessBuffer, 0, UART_LEN); memcpy(Uart_ProcessBuffer, Uart_ReceiveBuffer, Uart_ReceiveBufferLenTemp); memset(Uart_ReceiveBuffer, 0, UART_LEN); Uart_ReceiveBufferLen = Uart_ReceiveBufferLenTemp; Uart_ReceiveBufferLenTemp = 0; pData = Uart_ReceiveBuffer; if(Uart_ReceiveBufferLen <= 4) { memset(Uart_ReceiveBuffer, 0, UART_LEN); pData = Uart_ReceiveBuffer; Uart_ReceiveBufferLen = 0; } if(nRFHasCheck != true) { UsartNrf_Process_PowerOnGetDtuId(); } } else { pData++; Uart_ReceiveBufferLenTemp++; if(Uart_ReceiveBufferLenTemp >= UART_LEN) { memset(Uart_ReceiveBuffer, 0, UART_LEN); pData = Uart_ReceiveBuffer; Uart_ReceiveBufferLenTemp = 0; } } } else { Uart_ReceiveBufferLenTemp = 0; pData = Uart_ReceiveBuffer; } USART_ClearITPendingBit(USART2, USART_IT_RXNE); USART_ClearITPendingBit(USART2, USART_FLAG_RXNE); } if(USART_GetFlagStatus(USART2, USART_FLAG_TC) != RESET) { if(i < (Uart_SendBufferLen)) { USART_SendData(USART2, Uart_SendBuffer[i]); i++; } else { i = 1; Uart_SendBufferLen = 0; } USART_ClearITPendingBit(USART2, USART_IT_TC); USART_ClearITPendingBit(USART2, USART_FLAG_TC); } USART_ClearITPendingBit(USART2, USART_IT_ORE); USART_ClearITPendingBit(USART2, USART_IT_IDLE); //USART2->DR; // Whether you need to make relevant configuration during initialization to use the serial port interrupt. } #endif /*********************************************** ** Function name: ** Descriptions: UsartNrf send and receive main loop function ** input parameters: ** output parameters: ** Returned value: *************************************************/ void UsartNrf_SendProcessLoop() { UsartNrf_Send_Loop(); UsartNrf_Process_Loop(); }