Эх сурвалжийг харах

Merge branch 'master' into DD360 and release V1.06

Jerry_Wang 4 жил өмнө
parent
commit
6954825f7c
54 өөрчлөгдсөн 6690 нэмэгдсэн , 5137 устгасан
  1. 589 418
      EVSE/Modularization/Infypwr_PsuCommObj.c
  2. 93 7
      EVSE/Modularization/Infypwr_PsuCommObj.h
  3. 7 1
      EVSE/Modularization/Makefile
  4. 31 27
      EVSE/Modularization/Module_4g.c
  5. 2 2
      EVSE/Modularization/Module_EventLogging.c
  6. 327 0
      EVSE/Modularization/Module_InitUpgrade.c
  7. 60 1
      EVSE/Modularization/WebService.c
  8. 2 2
      EVSE/Modularization/ocpp20/JsonParser.c
  9. 303 191
      EVSE/Modularization/ocpp20/MessageHandler.c
  10. 2 2
      EVSE/Modularization/ocpp20/MessageHandler.h
  11. 24 13
      EVSE/Modularization/ocpp20/Module_OcppBackend20.c
  12. 13 3
      EVSE/Modularization/ocpp20/Module_OcppBackend20.h
  13. 254 145
      EVSE/Modularization/ocppfiles/MessageHandler.c
  14. 12 1
      EVSE/Modularization/ocppfiles/Module_OcppBackend.c
  15. 9 0
      EVSE/Modularization/ocppfiles/Module_OcppBackend.h
  16. 0 615
      EVSE/Projects/AW-CCS/Apps/LCM/Image.h
  17. 1050 796
      EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c
  18. 0 890
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm.c
  19. 0 153
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm.h
  20. 202 0
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.c
  21. 268 0
      EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h
  22. 0 852
      EVSE/Projects/AW-CCS/Apps/LCM/qrcode.c
  23. 0 106
      EVSE/Projects/AW-CCS/Apps/LCM/qrcode.h
  24. 9 2
      EVSE/Projects/AW-CCS/Apps/Makefile
  25. 115 1
      EVSE/Projects/AW-CCS/Apps/Module_Debug.c
  26. 2 1
      EVSE/Projects/AW-CCS/Apps/Module_FactoryConfig.c
  27. 6 3
      EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c
  28. BIN
      EVSE/Projects/AW-CCS/Apps/Module_PowerSharing
  29. 871 0
      EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.c
  30. 119 0
      EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.h
  31. 228 145
      EVSE/Projects/AW-CCS/Apps/main.c
  32. 71 73
      EVSE/Projects/AW-CCS/Apps/main.h
  33. 107 0
      EVSE/Projects/AW-Regular/Apps/Module_Debug.c
  34. 1 1
      EVSE/Projects/AW-Regular/Apps/Module_FactoryConfig.c
  35. 8 6
      EVSE/Projects/AW-Regular/Apps/Module_InternalComm.c
  36. 871 57
      EVSE/Projects/AW-Regular/Apps/main.c
  37. 56 25
      EVSE/Projects/DO360/Apps/Config.h
  38. 142 50
      EVSE/Projects/DO360/Apps/Module_EvComm.c
  39. 8 0
      EVSE/Projects/DO360/Apps/Module_EvComm.h
  40. 19 41
      EVSE/Projects/DO360/Apps/Module_EventLogging.c
  41. 21 75
      EVSE/Projects/DO360/Apps/Module_InternalComm.c
  42. 18 2
      EVSE/Projects/DO360/Apps/Module_PrimaryComm.c
  43. 68 35
      EVSE/Projects/DO360/Apps/Module_PsuComm.c
  44. 592 337
      EVSE/Projects/DO360/Apps/main.c
  45. BIN
      EVSE/Projects/DO360/Images/ramdisk.gz
  46. 16 3
      EVSE/Projects/Noodoe/Apps/main.c
  47. BIN
      EVSE/Projects/Noodoe/Images/ramdisk.gz
  48. 76 40
      EVSE/Projects/define.h
  49. 1 1
      EVSE/rootfs/etc/logrotate.d/evse
  50. 1 0
      EVSE/rootfs/root/.gitignore
  51. BIN
      EVSE/rootfs/root/OcppBackend20
  52. 13 13
      Makefile
  53. 1 1
      board-support/u-boot-2017.01+gitAUTOINC+340fb36f04-g340fb36f04/.config
  54. 2 0
      board-support/u-boot-2017.01+gitAUTOINC+340fb36f04-g340fb36f04/include/configs/am335x_evm.h

+ 589 - 418
EVSE/Modularization/Infypwr_PsuCommObj.c

@@ -39,19 +39,15 @@ void PRINTF_LIB_FUNC(char *string, ...)
 
 float IEEE_754_to_float(const byte raw[4])
 {
-    int sign = (raw[0] >> 7) ? -1 : 1;
+    float fValue = 0;
+    byte *pbyte = (byte *)&fValue;
 
-    byte exponent = (raw[0] << 1) + (raw[1] >> 7) - 126;
+    *(pbyte + 0) = raw[3];
+    *(pbyte + 1) = raw[2];
+    *(pbyte + 2) = raw[1];
+    *(pbyte + 3) = raw[0];
 
-    unsigned int fraction_bits = ((raw[1] & 0x7F) << 16) + (raw[2] << 8) + raw[3];
-
-    float fraction = 0.5f;
-    for (byte ii = 0; ii < 24; ++ii)
-        fraction += ldexpf((fraction_bits >> (23 - ii)) & 1, -(ii + 1));
-
-    float significand = sign * fraction;
-
-    return ldexpf(significand, exponent);
+    return fValue;
 }
 
 void IEEE_754_to_bytes(float target, byte *bytes2)
@@ -248,7 +244,7 @@ void ReceiveDataFromCanBus()
 {
 	int nbytes;
 	struct can_frame frame;
-	int intCmd = 0;
+	PwrFrame *PwrFrameMsg;
 	byte group, address;
 	byte _totalModuleCount = 0;
 	bool colFinished = false;
@@ -270,304 +266,305 @@ void ReceiveDataFromCanBus()
 
 		if (nbytes > 0)
 		{
-			if (isFilterValue(frame.can_id & 0xFFFF0000) == YES)
-				continue;
-
-//			if (frame.can_id == 0x82caf000 || frame.can_id == 0x82caf001 ||
-//					frame.can_id == 0x82c1f000 || frame.can_id == 0x82c1f001 ||
-//					frame.can_id == 0x82ccf000 || frame.can_id == 0x82ccf001 ||
-//					frame.can_id == 0x9901ff00 || frame.can_id == 0x9902ff00 || frame.can_id == 0x9903ff00 ||
-//					frame.can_id == 0x9901ff01 || frame.can_id == 0x9902ff01 || frame.can_id == 0x9903ff01 ||
-//					frame.can_id == 0x82c7f000 || frame.can_id == 0x82c7f001)
-//			{}
-//			else
-//				printf("can_id = %x \n", frame.can_id);
-
-			frame.can_id = frame.can_id & CAN_EFF_MASK;
-			intCmd = frame.can_id & 0x00FF0000;
-			intCmd |= INFYPWR_GROUP_SHIFT | intCmd;
-
-			switch (intCmd)
-			{
-				case WALK_IN_MODE:
-				case INFYPWR_GROUP_SHIFT | WALK_IN_MODE:
-				{
-					//address = frame.can_id & 0x000000FF;
-//					printf("walk in response address = %d, [0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d, [5] = %d, [6] = %d, [7] = %d \n"
-//							, address,
-//							frame.data[0], frame.data[1],
-//							frame.data[2], frame.data[3],
-//							frame.data[4], frame.data[5],
-//							frame.data[6], frame.data[7]);
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | STATUS:
-				{
-					group = frame.data[2];
-					byte SN = frame.can_id & 0x000000FF;
-					bool isfind = false;
-
-					if (group < 2 && !colFinished)
-					{
-						for(byte _index = 0; _index < infy_pow_info[group].psuCount; _index++)
-						{
-							if (infy_pow_info[group].serialNumber[_index] == SN)
-							{
-								isfind = true;
-								break;
-							}
-						}
-
-						if (!isfind)
-						{
-							infy_pow_info[group].serialNumber[infy_pow_info[group].psuCount] = SN;
-							infy_pow_info[group].targetNumber[infy_pow_info[group].psuCount] = infy_pow_info[group].psuCount;
-							infy_pow_info[group].psuCount++;
-						}
-
-						byte subPcount = 0;
-						for (byte i = 0; i < 2; i++)
-						{
-							subPcount += infy_pow_info[i].psuCount;
-						}
-
-						if (subPcount > 0 && subPcount == _totalModuleCount)
-							colFinished = true;
-					}
-
-					short temp = frame.data[4];
-					int status = (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7];
-
-					return_status(group, SN, temp, status);
-					//PRINTF_LIB_FUNC("group = %d, address = %d, temp = %d \n", group, address, temp);
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_COUNT:
-				{
-					// 回傳模組數量
-					group = frame.can_id & 0x000000FF;
-
-					byte count = frame.data[2];
-					if (group == SYSTEM_CMD)
-					{
-						_totalModuleCount = count;
-					}
-
-					return_module_count(group, count);
-					//PRINTF_LIB_FUNC("group = %d, count = %d \n", group, count);
-				}
-					break;
-
-				case MODULE_CAP:
-				case INFYPWR_GROUP_SHIFT | MODULE_CAP:
-				{
-					if (!colFinished)
-						break;
-
-					// 回傳輸出能力 : 最大電壓、最小電壓、最大電流、額定功率
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					short maxVol = ((frame.data[0] << 8) + frame.data[1]) * 10;
-					short minVol = ((frame.data[2] << 8) + frame.data[3]) * 10;
-					short maxCur = (frame.data[4] << 8) + frame.data[5];
-					short totalPow = ((frame.data[6] << 8) + frame.data[7]) / 10;
-
-					return_available_cap(address, maxVol, minVol, maxCur, totalPow);
-//					PRINTF_LIB_FUNC("address = %d, maxVol = %d, minVol = %d, maxCur = %d, totalPow = %d \n",
-//							address, maxVol, minVol, maxCur, totalPow);
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_OUTPUT_VOL_CUR:
-				{
-					// 回傳當前輸出電壓電流
-					address = frame.can_id & 0x000000FF;
-
-					int outputVol = ((frame.data[0] << 24) + (frame.data[1] << 16) + (frame.data[2] << 8) + frame.data[3]) / 100;
-					int outputCur = ((frame.data[4] << 24) + (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7]) / 100;
-
-					return_get_output(address, outputVol, outputCur);
-					//PRINTF_LIB_FUNC("address = %d, outputVol = %d, outputCur = %d \n", address, outputVol, outputCur);
-				}
-					break;
-				case INFYPWR_GROUP_SHIFT | MODULE_OUTPUT_VOL_CUR_FLOAT:
-				{
-					group = frame.can_id & 0x000000FF;
-
-					byte vol[4], cur[4];
-					memcpy(vol, frame.data, 4);
-					memcpy(cur, frame.data + 4, 4);
-
-					float _Vol = IEEE_754_to_float(vol);
-					float _Cur = IEEE_754_to_float(cur);
-
-					return_get_output_float(group, _Vol, _Cur);
-				}
-					break;
-				case INFYPWR_GROUP_SHIFT | MODULE_IAVAILABLE:
-				case MODULE_IAVAILABLE:
-				{
-					if (!colFinished)
-						break;
-
-					// 回傳降載後的電流
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					unsigned short vextVol = ((frame.data[0] << 8) + frame.data[1]);
-					unsigned short iAvailCur = ((frame.data[2] << 8) + frame.data[3]);
-
-					return_iavail_info(address, iAvailCur, vextVol);
-					//PRINTF_LIB_FUNC("address = %d, iAvailCur = %d \n", address, iAvailCur);
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_MIS_INFO:
-				{
-					if (!colFinished)
-						break;
-
-					address = frame.can_id & 0x000000FF;
-					float ReturnValue;
-					byte value[4];
-					byte type;
-
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					memcpy(value, frame.data + 4, sizeof(value));
-					ReturnValue = IEEE_754_to_float(value);
-					if (frame.data[0] == ((FAN_SPEED_CMD >> 8) & 0xFF) && frame.data[1] == (FAN_SPEED_CMD & 0xFF))
-					{
-						type = 1;
-						return_mis_info(address, ReturnValue, type);
-						//PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
-					}
-					else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
-					{
-						type = 2;
-						return_mis_info(address, ReturnValue, type);
-						//PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
-					}
-					else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
-					{
-						type = 3;
-						return_mis_info(address, ReturnValue, type);
-						//PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
-					}
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_VER:
-				{
-					if (!colFinished)
-						break;
-
-					// 回傳版號 : 無系統回覆功能
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					short dcSwVer = ((frame.data[0] << 8) + frame.data[1]);
-					short pfcSwVer = ((frame.data[2] << 8) + frame.data[3]);
-					short hwVer = ((frame.data[4] << 8) + frame.data[5]);
-
-					return_fw_version(address, dcSwVer, pfcSwVer, hwVer);
-					//PRINTF_LIB_FUNC("address = %d, DC %d, PFC %d, HW %d \n", address, dcSwVer, pfcSwVer, hwVer);
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_BARCODE:
-				{
-					// 回傳BarCode
-				}
-					break;
-
-				case INFYPWR_GROUP_SHIFT | MODULE_INPUT:
-				{
-					if (!colFinished)
-						break;
-
-					// 回傳三向輸入電壓
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					short abVol = ((frame.data[0] << 8) + frame.data[1]) / 10;
-					short bcVol = ((frame.data[2] << 8) + frame.data[3]) / 10;
-					short caVol = ((frame.data[4] << 8) + frame.data[5]) / 10;
-
-					return_input_vol(address, abVol, bcVol, caVol);
-					//PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
-				}
-					break;
-				case INFYPWR_GROUP_SHIFT | AUTO_OUTPUT_TEMP:
-				{
-					if (!colFinished)
-						break;
-
-					/*Test mode used*/
-					// 回傳輸出值與入風口溫度
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					short outputVol = ((frame.data[0] << 8) + frame.data[1]);
-					short outputCur = ((frame.data[2] << 8) + frame.data[3]);
-					short outputPow = ((frame.data[4] << 8) + frame.data[5]);
-					byte temp = frame.data[6];
-
-					return_output_temp(address, outputVol, outputCur, outputPow, temp);
-					//PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
-				}
-					break;
-				case INFYPWR_GROUP_SHIFT | AUTO_MODULE_STATUS:
-				{
-					if (!colFinished)
-						break;
-
-					/*Test mode used*/
-					// 回傳輸出值與入風口溫度
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					byte isErr =  (frame.data[0] >> 0) & 0x01;
-					byte status = (frame.data[0] >> 1) & 0x01;
-					byte err1 = frame.data[2];
-					byte err2 = frame.data[3];
-					byte err3 = frame.data[4];
-					byte err4 = frame.data[5];
-
-					return_module_status(address, isErr, status, err1, err2, err3, err4);
-					//PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
-				}
-					break;
-				case INFYPWR_GROUP_SHIFT | AUTO_MODULE_INPUT:
-				{
-					if (!colFinished)
-						break;
-
-					/*Test mode used*/
-					// 回傳輸出值與入風口溫度
-					address = frame.can_id & 0x000000FF;
-					if(!GetRealIndexByGroup(&address))
-						break;
-
-					short vR = ((frame.data[0] << 8) + frame.data[1]);
-					short vS = ((frame.data[2] << 8) + frame.data[3]);
-					short vT = ((frame.data[4] << 8) + frame.data[5]);
-
-					return_module_input(address, vR, vS, vT);
-					//PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
-				}
-					break;
-			}
+            PwrFrameMsg = (PwrFrame *)&frame.can_id;
+            address = PwrFrameMsg->InfyBits.SourceAddress;
+
+            if(PwrFrameMsg->InfyBits.DestinationAddress != NEXTON_ADD)
+            {
+                if(PwrFrameMsg->InfyBits.DestinationAddress != INFY_ADD_CSU || PwrFrameMsg->InfyBits.Error != Infy_MsgErr_Normal)
+                {
+                    continue;
+                }
+
+                switch (PwrFrameMsg->InfyBits.CmdValue)
+                {
+                    case PSU_WCmd_ModuleWalkIn:
+                    {
+                        //address = frame.can_id & 0x000000FF;
+    //					printf("walk in response address = %d, [0] = %d, [1] = %d, [2] = %d, [3] = %d, [4] = %d, [5] = %d, [6] = %d, [7] = %d \n"
+    //							, address,
+    //							frame.data[0], frame.data[1],
+    //							frame.data[2], frame.data[3],
+    //							frame.data[4], frame.data[5],
+    //							frame.data[6], frame.data[7]);
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleStatus:
+                    {
+                        group = frame.data[2];
+                        byte SN = address;
+                        bool isfind = false;
+
+                        if (group < 2 && !colFinished)
+                        {
+                            for(byte _index = 0; _index < infy_pow_info[group].psuCount; _index++)
+                            {
+                                if (infy_pow_info[group].serialNumber[_index] == SN)
+                                {
+                                    isfind = true;
+                                    break;
+                                }
+                            }
+
+                            if (!isfind)
+                            {
+                                infy_pow_info[group].serialNumber[infy_pow_info[group].psuCount] = SN;
+                                infy_pow_info[group].targetNumber[infy_pow_info[group].psuCount] = infy_pow_info[group].psuCount;
+                                infy_pow_info[group].psuCount++;
+                            }
+
+                            byte subPcount = 0;
+                            for (byte i = 0; i < 2; i++)
+                            {
+                                subPcount += infy_pow_info[i].psuCount;
+                            }
+
+                            if (subPcount > 0 && subPcount == _totalModuleCount)
+                                colFinished = true;
+                        }
+
+                        short temp = frame.data[4];
+                        int status = (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7];
+
+                        return_status(group, SN, temp, status);
+                        //PRINTF_LIB_FUNC("group = %d, address = %d, temp = %d \n", group, address, temp);
+                    }
+                        break;
+
+                    case PSU_RCmd_SysModuleCount:
+                    {
+                        // 回傳模組數量
+                        group = address;
+
+                        byte count = frame.data[2];
+                        if (group == SYSTEM_CMD)
+                        {
+                            _totalModuleCount = count;
+                        }
+
+                        return_module_count(group, count);
+                        //PRINTF_LIB_FUNC("group = %d, count = %d \n", group, count);
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleCapability:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        // 回傳輸出能力 : 最大電壓、最小電壓、最大電流、額定功率
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        short maxVol = ((frame.data[0] << 8) + frame.data[1]) * 10;
+                        short minVol = ((frame.data[2] << 8) + frame.data[3]) * 10;
+                        short maxCur = (frame.data[4] << 8) + frame.data[5];
+                        short totalPow = ((frame.data[6] << 8) + frame.data[7]) / 10;
+
+                        return_available_cap(address, maxVol, minVol, maxCur, totalPow);
+    //					PRINTF_LIB_FUNC("address = %d, maxVol = %d, minVol = %d, maxCur = %d, totalPow = %d \n",
+    //							address, maxVol, minVol, maxCur, totalPow);
+                    }
+                        break;
+
+                    case PSU_RCmd_SysOutputVolCur:
+                    {
+                        // 回傳當前輸出電壓電流
+                        //address = frame.can_id & 0x000000FF;
+
+                        int outputVol = ((frame.data[0] << 24) + (frame.data[1] << 16) + (frame.data[2] << 8) + frame.data[3]) / 100;
+                        int outputCur = ((frame.data[4] << 24) + (frame.data[5] << 16) + (frame.data[6] << 8) + frame.data[7]) / 100;
+
+                        return_get_output(address, outputVol, outputCur);
+                        //PRINTF_LIB_FUNC("address = %d, outputVol = %d, outputCur = %d \n", address, outputVol, outputCur);
+                    }
+                        break;
+                    case PSU_RCmd_SysOutputVolCur_F:
+                    {
+                        group = address;
+
+                        byte vol[4], cur[4];
+                        memcpy(vol, frame.data, 4);
+                        memcpy(cur, frame.data + 4, 4);
+
+                        float _Vol = IEEE_754_to_float(vol);
+                        float _Cur = IEEE_754_to_float(cur);
+
+                        return_get_output_float(group, _Vol, _Cur);
+                    }
+                        break;
+                    case PSU_RCmd_ModuleIAvailable:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        // 回傳降載後的電流
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        unsigned short vextVol = ((frame.data[0] << 8) + frame.data[1]);
+                        unsigned short iAvailCur = ((frame.data[2] << 8) + frame.data[3]);
+
+                        return_iavail_info(address, iAvailCur, vextVol);
+                        //PRINTF_LIB_FUNC("address = %d, iAvailCur = %d \n", address, iAvailCur);
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleMiscInfo:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        //address = frame.can_id & 0x000000FF;
+                        float ReturnValue;
+                        byte value[4];
+                        byte type;
+
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        memcpy(value, frame.data + 4, sizeof(value));
+                        ReturnValue = IEEE_754_to_float(value);
+                        if (frame.data[0] == ((FAN_SPEED_CMD >> 8) & 0xFF) && frame.data[1] == (FAN_SPEED_CMD & 0xFF))
+                        {
+                            type = 1;
+                            return_mis_info(address, ReturnValue, type);
+                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
+                        }
+                        else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
+                        {
+                            type = 2;
+                            return_mis_info(address, ReturnValue, type);
+                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
+                        }
+                        else if (frame.data[0] == ((TEMP_DC_CMD >> 8) & 0xFF) && frame.data[1] == (TEMP_DC_CMD & 0xFF))
+                        {
+                            type = 3;
+                            return_mis_info(address, ReturnValue, type);
+                            //PRINTF_LIB_FUNC("address = %d, FanSpeed = %f \n", address, FanSpeed);
+                        }
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleVersion:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        // 回傳版號 : 無系統回覆功能
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        short dcSwVer = ((frame.data[0] << 8) + frame.data[1]);
+                        short pfcSwVer = ((frame.data[2] << 8) + frame.data[3]);
+                        short hwVer = ((frame.data[4] << 8) + frame.data[5]);
+
+                        return_fw_version(address, dcSwVer, pfcSwVer, hwVer);
+                        //PRINTF_LIB_FUNC("address = %d, DC %d, PFC %d, HW %d \n", address, dcSwVer, pfcSwVer, hwVer);
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleBarcode:
+                    {
+                        // 回傳BarCode
+                    }
+                        break;
+
+                    case PSU_RCmd_ModuleInputVoltage:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        // 回傳三向輸入電壓
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        short abVol = ((frame.data[0] << 8) + frame.data[1]) / 10;
+                        short bcVol = ((frame.data[2] << 8) + frame.data[3]) / 10;
+                        short caVol = ((frame.data[4] << 8) + frame.data[5]) / 10;
+
+                        return_input_vol(address, abVol, bcVol, caVol);
+                        //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
+                    }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            else
+            {
+                switch(PwrFrameMsg->NextonBits.CmdValue)
+                {
+                    case Nexton_PSU_DcOutputValue:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        /*Test mode used*/
+                        // 回傳輸出值與入風口溫度
+                        address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        short outputVol = ((frame.data[0] << 8) + frame.data[1]);
+                        short outputCur = ((frame.data[2] << 8) + frame.data[3]);
+                        short outputPow = ((frame.data[4] << 8) + frame.data[5]);
+                        byte temp = frame.data[6];
+
+                        return_output_temp(address, outputVol, outputCur, outputPow, temp);
+                        //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
+                    }
+                        break;
+                    case Nexton_PSU_StatusEvent:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        /*Test mode used*/
+                        // 回傳輸出值與入風口溫度
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        byte isErr =  (frame.data[0] >> 0) & 0x01;
+                        byte status = (frame.data[0] >> 1) & 0x01;
+                        byte err1 = frame.data[2];
+                        byte err2 = frame.data[3];
+                        byte err3 = frame.data[4];
+                        byte err4 = frame.data[5];
+
+                        return_module_status(address, isErr, status, err1, err2, err3, err4);
+                        //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
+                    }
+                        break;
+                    case Nexton_PSU_AcInputValue:
+                    {
+                        if (!colFinished)
+                            break;
+
+                        /*Test mode used*/
+                        // 回傳輸出值與入風口溫度
+                        //address = frame.can_id & 0x000000FF;
+                        if(!GetRealIndexByGroup(&address))
+                            break;
+
+                        short vR = ((frame.data[0] << 8) + frame.data[1]);
+                        short vS = ((frame.data[2] << 8) + frame.data[3]);
+                        short vT = ((frame.data[4] << 8) + frame.data[5]);
+
+                        return_module_input(address, vR, vS, vT);
+                        //PRINTF_LIB_FUNC("address = %d, abVol = %d, bcVol = %d, caVol = %d \n", address, abVol, bcVol, caVol);
+                    }
+                        break;
+                    default:
+                        break;
+                }
+            }
 		}
 		else
 			usleep(10000);
@@ -579,18 +576,19 @@ void ReceiveDataFromCanBus()
 //================================================
 void SendCmdToPsu(int cmd, byte *data, byte dataLen)
 {
+    PwrFrame PwrFrameMsg;
     struct can_frame frame;
 
     //設定 CANBSU 2.0B 長封包
-    cmd = cmd | 0x80000000;
+    PwrFrameMsg.PwrMessage = cmd | 0x80000000;
 
-    frame.can_id = cmd;
+    frame.can_id = PwrFrameMsg.PwrMessage;
     frame.can_dlc = dataLen;
     memcpy(frame.data, data, dataLen);
 
     write(CanFd, &frame, sizeof(struct can_frame));
     // 群命令才 delay
-    if ((cmd & 0x0000FF00) == INFYPWR_BROADCAST)
+    if (PwrFrameMsg.InfyBits.DestinationAddress == INFY_ADD_BROADCAST)
     	usleep(CMD_DELAY_TIME);
 }
 
@@ -619,58 +617,88 @@ bool InitialCommunication()
 void SwitchPower(byte group, byte value)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | SWITCH_POWER;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModulePowerOnOff;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	// 1 : 關機
 	// 0 : 開機
 	data[0] = value;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void SleepMode(byte group, byte value)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | SLEEP_MODE;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSleepMode;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	// 1 : 休眠
 	// 0 : 起床
 	data[0] = value;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void FlashLed(byte group, byte value)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | FLASH_LED;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleFlashLed;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	// 1 : 閃爍
 	// 0 : 正常
 	data[0] = value;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void PresentOutputVol(byte group, int voltage, int current)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | PRESENT_OUT_VOL;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_SetOutput;
+
 	int Vol = voltage * 100;
 	int Cur = current * 100;
 
@@ -687,41 +715,58 @@ void PresentOutputVol(byte group, int voltage, int current)
 	data[6] = (Cur >> 8) & 0xFF;
 	data[7] = Cur & 0xFF;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void FanNoiseInfo(byte group, byte value)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MIS_INFO;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleSetMiscInfo;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
 	// 風扇低噪音
-	data[0] = 0x11;
-	data[1] = 0x13;
+    data[0] = ((SetMiscInfo_FanMode >> 8) & 0xFF);
+    data[1] = (SetMiscInfo_FanMode & 0xFF);
 
 	// 0xA0 power poriority mode
 	// 0xA1 denoise mode
 	// 0xA2 quiet mode
 	data[7] = value;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
-}
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
 
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
+}
 
 void SetWalkInConfig(byte group, byte enable, byte sec)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | WALK_IN_MODE;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_ModuleWalkIn;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 	unsigned short _Sec = sec * 100;
@@ -732,13 +777,19 @@ void SetWalkInConfig(byte group, byte enable, byte sec)
 	data[6] = (_Sec >> 8) & 0xFF;
 	data[7] = _Sec & 0xFF;
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= (group << 8) | INFYPWR_DEFAULT;
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
 
 	//printf("walk in cmd = %x \n", cmd);
-	SendCmdToPsu(cmd, data, sizeof(data));
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switch, byte _interRelay)
@@ -769,13 +820,18 @@ void SetDirModulePresentOutput(byte group, int voltage, int current, byte _switc
 void SetDipSwitchMode()
 {
     byte data[8];
-    uint cmd = INFYPWR_CMD | DIP_SWITCH_MODE;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_WCmd_DipSwitchMode;
 
     memset(data, 0x00, ARRAY_SIZE(data));
     data[0] = 0x01;
 
-    cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-    SendCmdToPsu(cmd, data, sizeof(data));
+    PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    PwrFrameMsg.InfyBits.DestinationAddress = INFY_ADD_BROADCAST;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 /**********************************************************************************/
 /***                                                                            ***/
@@ -785,174 +841,289 @@ void SetDipSwitchMode()
 void GetStatus(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | STATUS;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleStatus;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetFanSpeed(byte group)
 {
-	uint cmd;
 	byte data[8];
-
-	cmd = INFYPWR_CMD | MODULE_MIS_INFO;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
 	data[0] = (FAN_SPEED_CMD >> 8) & 0xFF;
 	data[1] = FAN_SPEED_CMD & 0xFF;
 
-	if (group == (INFYPWR_BROADCAST >> 8))
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetDcTemperature(byte group)
 {
-	uint cmd;
 	byte data[8];
-
-	cmd = INFYPWR_CMD | MODULE_MIS_INFO;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
 	data[0] = (TEMP_DC_CMD >> 8) & 0xFF;
 	data[1] = TEMP_DC_CMD & 0xFF;
 
-	if (group == (INFYPWR_BROADCAST >> 8))
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetPfcTemperature(byte group)
 {
-	uint cmd;
 	byte data[8];
-
-	cmd = INFYPWR_CMD | MODULE_MIS_INFO;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleMiscInfo;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
 	data[0] = (TEMP_PFC_CMD >> 8) & 0xFF;
 	data[1] = TEMP_PFC_CMD & 0xFF;
 
-	if (group == (INFYPWR_BROADCAST >> 8))
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleCount(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_COUNT;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysModuleCount;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleVer(byte group)
 {
 	// 無系統廣播功能
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_VER;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleVersion;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
 	//PRINTF_LIB_FUNC("GetModuleVer cmd = %x\n", cmd);
-	SendCmdToPsu(cmd, data, sizeof(data));
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleCap(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_CAP;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleCapability;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
 	//PRINTF_LIB_FUNC("GetModuleCap cmd = %x\n", cmd);
-	SendCmdToPsu(cmd, data, sizeof(data));
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleBarCode(byte group)
 {
 	// 無系統廣播功能
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_BARCODE;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleBarcode;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleInput(byte group)
 {
 	// 無系統廣播功能
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_INPUT;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleInputVoltage;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+	SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleIavailable(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_IAVAILABLE;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_ModuleIAvailable;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleOutput(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_OUTPUT_VOL_CUR;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysOutputVolCur;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 void GetModuleOutputF(byte group)
 {
 	byte data[8];
-	uint cmd = INFYPWR_CMD | MODULE_OUTPUT_VOL_CUR_FLOAT;
+    PwrFrame PwrFrameMsg;
+    PwrFrameMsg.PwrMessage = 0;
+    PwrFrameMsg.InfyBits.CmdValue = PSU_RCmd_SysOutputVolCur_F;
 
 	memset(data, 0x00, ARRAY_SIZE(data));
 
-	if (group == SYSTEM_CMD)
-		cmd |= INFYPWR_BROADCAST | INFYPWR_DEFAULT;
-	else
-		cmd |= INFYPWR_GROUP_SHIFT | (group << 8) | INFYPWR_DEFAULT;
-	SendCmdToPsu(cmd, data, sizeof(data));
+    if (group == INFY_ADD_BROADCAST)
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_SINGLE_MODULE;
+    }
+    else
+    {
+        PwrFrameMsg.InfyBits.DeviceValue = DEVICE_NO_GROUP_MODULE;
+    }
+    PwrFrameMsg.InfyBits.DestinationAddress = group;
+    PwrFrameMsg.InfyBits.SourceAddress = INFY_ADD_CSU;
+
+    SendCmdToPsu(PwrFrameMsg.PwrMessage, data, sizeof(data));
 }
 
 /**********************************************************************************/

+ 93 - 7
EVSE/Modularization/Infypwr_PsuCommObj.h

@@ -45,7 +45,12 @@
 
 #define INFYPWR_GROUP_SHIFT		0x00400000
 
-#define SYSTEM_CMD				0x3F
+#define SYSTEM_CMD                  0x3F
+#define DEVICE_NO_SINGLE_MODULE     0x0A
+#define DEVICE_NO_GROUP_MODULE      0x0B
+#define INFY_ADD_BROADCAST          0x3F
+#define INFY_ADD_CSU                0xF0
+#define NEXTON_ADD                  0xFF
 
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define CMD_DELAY_TIME 		25000
@@ -53,13 +58,34 @@
 #define TEMP_DC_CMD			0x1107
 #define TEMP_PFC_CMD		0x1108
 
-typedef unsigned char 		byte;
-typedef unsigned short 	word;
-typedef unsigned int 		unit;
+typedef unsigned char       byte;
+typedef unsigned short      word;
+typedef unsigned int        unit;
 
 int 						CanFd;
 pid_t 						recFork;
 
+typedef union
+{
+    unsigned int PwrMessage;
+    struct
+    {
+        unsigned int SourceAddress:8;                   // source address
+        unsigned int DestinationAddress:8;              // destination address
+        unsigned int CmdValue:6;                        // command value
+        unsigned int DeviceValue:4;                     // 0x0A: for module command, 0x0B group command
+        unsigned int Error:3;                           // error code
+        unsigned int res:3;
+    }InfyBits;
+    struct
+    {
+        unsigned int SourceAddress:8;                   // source address
+        unsigned int DestinationAddress:8;              // destination address
+        unsigned int CmdValue:13;                       // command value
+        unsigned int res:3;
+    }NextonBits;
+}PwrFrame;
+
 enum PSU_POWER_CMD
 {
 	PSU_POWER_ON = 		0,
@@ -80,9 +106,9 @@ enum PSU_FLASH_CMD
 
 enum PSU_FAN_NOISE_CMD
 {
-	PSU_FAN_NOISE_BY_POWER = 		0xA0,
-	PSU_FAN_NOISE_BY_DENOISE = 		0xA1,
-	PSU_FAN_NOISE_BY_QUIET = 		0xA2
+    PSU_FAN_NOISE_BY_POWER =        0xA0,       // power poriority mode
+    PSU_FAN_NOISE_BY_DENOISE =      0xA1,       // denoise mode
+    PSU_FAN_NOISE_BY_QUIET =        0xA2,       // quiet mode
 };
 
 enum PSU_SET_CMD
@@ -118,6 +144,66 @@ enum PSU_GET_CMD
     AUTO_MODULE_INPUT =             0x00030000,
 };
 
+typedef enum
+{
+    Infy_MsgErr_Normal          = 0x00,
+    Infy_MsgErr_Reserved1       = 0x01,
+    Infy_MsgErr_CmdInvalid      = 0x02,
+    Infy_MsgErr_DataInvalid     = 0x03,
+    Infy_MsgErr_InvalidAdd      = 0x04,
+    Infy_MsgErr_Reserved2       = 0x05,
+    Infy_MsgErr_Reserved3       = 0x06,
+    Infy_MsgErr_StartProcess    = 0x07,
+}InfyMessageError;
+
+typedef enum
+{
+    PSU_RCmd_SysOutputVolCur_F      = 0x01,
+    PSU_RCmd_SysModuleCount         = 0x02,
+    PSU_RCmd_ModuleOutputVolCur_F   = 0x03,     // no use
+    PSU_RCmd_ModuleStatus           = 0x04,
+    PSU_RCmd_ModuleInputVoltage     = 0x06,
+    PSU_RCmd_ModuleVersion          = 0x07,
+    PSU_RCmd_SysOutputVolCur        = 0x08,
+    PSU_RCmd_ModuleOutputVolCur     = 0x09,     // no use
+    PSU_RCmd_ModuleCapability       = 0x0A,
+    PSU_RCmd_ModuleBarcode          = 0x0B,
+    PSU_RCmd_ModuleIAvailable       = 0x0C,
+    PSU_RCmd_ModuleMiscInfo         = 0x0E,
+    PSU_WCmd_ModuleSetMiscInfo      = 0x0F,
+    PSU_WCmd_ModuleWalkIn           = 0x13,
+    PSU_WCmd_ModuleFlashLed         = 0x14,
+    PSU_WCmd_ModuleSetGroup         = 0x16,
+    PSU_WCmd_ModuleSleepMode        = 0x19,
+    PSU_WCmd_ModulePowerOnOff       = 0x1A,
+    PSU_WCmd_SetOutput              = 0x1B,
+    PSU_WCmd_ModuleSetOutput        = 0x1C,
+    PSU_WCmd_DipSwitchMode          = 0x1F,
+}InfyPwrCommand;
+
+typedef enum
+{
+    Nexton_PSU_ChargingRequest      = 0x1801,
+    Nexton_PSU_DcOutputValue        = 0x1901,
+    Nexton_PSU_StatusEvent          = 0x1902,
+    Nexton_PSU_AcInputValue         = 0x1903,
+}NextonPwrCommand;
+
+typedef enum
+{
+    GetMiscInfo_DcTemperature       = 0x1107,
+    GetMiscInfo_PfcTemperature      = 0x1108,
+    GetMiscInfo_FanSpeed            = 0x1201,
+}GetMiscInfoCommand;
+
+typedef enum
+{
+    SetMiscInfo_FanMode             = 0x1113,
+    SetMiscInfo_FanSpeed            = 0x1201,
+    SetMiscInfo_CurrentLimit        = 0x1205,
+    SetMiscInfo_SendTemperature     = 0x1301,
+}SetMiscInfoCommand;
+
 union FloatingPointIEEE754
 {
 	struct

+ 7 - 1
EVSE/Modularization/Makefile

@@ -4,7 +4,7 @@ export PATH=/bin:/sbin:/usr/bin:$(SDK_PATH_TARGET)/usr/bin:$PATH
 #define library variable
 Lib_SQLite3 = "-L../../../Modularization/ocppfiles" -lsqlite3
 
-all: clean Module_RFIDLib Module_Wifi WebServiceLib Ocpp16 Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj Module_EventLogging Module_ProduceUtils Module_PhBackend Ocpp20
+all: clean Module_RFIDLib Module_Wifi WebServiceLib Ocpp16 Phihong_PsuCommObj Module_4g Module_UpgradeLib Infypwr_PsuCommObj Module_EventLogging Module_ProduceUtils Module_PhBackend Ocpp20 Module_InitUpgrade
 
 
 clean:
@@ -103,3 +103,9 @@ Module_PhBackend:
 	rm -f Module_PhBackend.o
 	mv -f Module_PhBackend ../rootfs/root
 
+Module_InitUpgrade:
+	rm -f Module_InitUpgrade
+	$(CC) -D $(Project) -I ../Projects -O0 -g3 -Wall -c -fmessage-length=0 -o Module_InitUpgrade.o Module_InitUpgrade.c
+	$(CC) -o Module_InitUpgrade Module_InitUpgrade.o
+	rm -f Module_InitUpgrade.o
+	mv -f Module_InitUpgrade ../rootfs/root

+ 31 - 27
EVSE/Modularization/Module_4g.c

@@ -80,7 +80,7 @@ void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
 
 char *portName[3] 				= {"/dev/ttyUSB2", "/dev/ttyUSB2", "/dev/ttyACM2"};
 char *valid_Internet[2] 		= {"8.8.8.8", "180.76.76.76"};
-char *Version_And_Date[2]		= {"V0.07","2020-11-26"};
+char *Version_And_Date[2]		= {"V0.08","2021-02-23"};
 pid_t	pid;
 
 struct dongle_info
@@ -157,16 +157,12 @@ int InitShareMemory()
 	//creat ShmSysConfigAndInfo
 	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
     {
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
-		#endif
 		result = FAIL;
 	}
     else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     {
-    	#ifdef SystemLogMessage
     	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
-		#endif
     	result = FAIL;
    	 }
     else
@@ -175,16 +171,12 @@ int InitShareMemory()
    	 //creat ShmStatusCodeData
    	 if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
     {
-		#ifdef SystemLogMessage
    		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
-		#endif
    		result = FAIL;
 	}
     else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
     {
-    	#ifdef SystemLogMessage
     	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
-		#endif
     	result = FAIL;
    	}
     else
@@ -193,16 +185,12 @@ int InitShareMemory()
    	//creat ShmOCPP16Data
 	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data),  0777)) < 0)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmget ShmOCPP16Data NG");
-		#endif
 		result = FAIL;
 	}
 	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("shmat ShmOCPP16Data NG");
-		#endif
 		result = FAIL;
 	}
 	else
@@ -239,21 +227,15 @@ int Check4GModem(void)
 
     if(result == DONGLE_QUECTEL)
     {
-		#ifdef SystemLogMessage
     	DEBUG_WARN("Quectel 4G modem be found\n");
-		#endif
     }
     else if(result == DONGLE_UBLOX)
     {
-		#ifdef SystemLogMessage
     	DEBUG_WARN("Ublox 4G modem be found\n");
-		#endif
     }
     else
     {
-		#ifdef SystemLogMessage
     	DEBUG_WARN("No 4G modem be found\n");
-		#endif
     }
 
     return result;
@@ -343,7 +325,7 @@ int isReadInfo(void)
 					{
 						substr(tmp, tmp, 5, strlen(tmp)-5);
 					}
-
+					memset(Dongle.MANUFACTURER, 0x00, ARRAY_SIZE(Dongle.MANUFACTURER));
 					strncpy(Dongle.MANUFACTURER, tmp, strlen(tmp));
 				}
 				else
@@ -364,7 +346,7 @@ int isReadInfo(void)
 					{
 						substr(tmp, tmp, 5, strlen(tmp)-5);
 					}
-
+					memset(Dongle.MODELNAME, 0x00, ARRAY_SIZE(Dongle.MODELNAME));
 					strncpy(Dongle.MODELNAME, tmp, strlen(tmp));
 				}
 				else
@@ -385,7 +367,7 @@ int isReadInfo(void)
 					{
 						substr(tmp, tmp, 5, strlen(tmp)-5);
 					}
-
+					memset(Dongle.REVISION, 0x00, ARRAY_SIZE(Dongle.REVISION));
 					strncpy(Dongle.REVISION, tmp, strlen(tmp));
 				}
 				else
@@ -406,7 +388,7 @@ int isReadInfo(void)
 					{
 						substr(tmp, tmp, 5, strlen(tmp)-5);
 					}
-
+					memset(Dongle.IMEI, 0x00, ARRAY_SIZE(Dongle.IMEI));
 					strncpy(Dongle.IMEI, tmp, strlen(tmp));
 				}
 				else
@@ -485,6 +467,7 @@ int isReadInfo(void)
 					memset(tmp, 0, sizeof tmp);
 					memcpy(tmp, rx, strcspn(rx,"OK"));
 					memset(rx, 0, sizeof rx);
+					memset(Dongle.MANUFACTURER, 0x00, ARRAY_SIZE(Dongle.MANUFACTURER));
 					strncpy(Dongle.MANUFACTURER, tmp+2, 6);
 				}
 				else
@@ -499,6 +482,7 @@ int isReadInfo(void)
 					memset(tmp, 0, sizeof tmp);
 					memcpy(tmp, rx, strcspn(rx,"OK"));
 					memset(rx, 0, sizeof rx);
+					memset(Dongle.MODELNAME, 0x00, ARRAY_SIZE(Dongle.MODELNAME));
 					strncpy(Dongle.MODELNAME , tmp+2, 9);
 				}
 				else
@@ -513,6 +497,7 @@ int isReadInfo(void)
 					memset(tmp, 0, sizeof tmp);
 					memcpy(tmp, rx, strcspn(rx, "OK"));
 					memset(rx, 0, sizeof rx);
+					memset(Dongle.REVISION, 0x00, ARRAY_SIZE(Dongle.REVISION));
 					strncpy(Dongle.REVISION, tmp+2, 5);
 				}
 				else
@@ -528,6 +513,7 @@ int isReadInfo(void)
 					memcpy(tmp, rx, strcspn(rx, "OK"));
 					memset(rx, 0, sizeof rx);
 					trim_s(tmp,Length);
+					memset(Dongle.IMEI, 0x00, ARRAY_SIZE(Dongle.IMEI));
 					strncpy(Dongle.IMEI, tmp, strlen(tmp));
 				}
 				else
@@ -618,7 +604,7 @@ int isReadSimInfo(void)
 						{
 							substr(tmp, tmp, 6, strlen(tmp)-6);
 						}
-
+						memset(Dongle.IMSI, 0x00, ARRAY_SIZE(Dongle.IMSI));
 						strncpy(Dongle.IMSI, tmp, strlen(tmp));
 					}
 				}
@@ -641,6 +627,7 @@ int isReadSimInfo(void)
 					{
 						memcpy(tmp, rx, strcspn(rx, "OK"));
 						memset(rx, 0, sizeof rx);
+						memset(Dongle.ICCID, 0x00, ARRAY_SIZE(Dongle.ICCID));
 						strncpy(Dongle.ICCID, tmp + strcspn(tmp, ":") + 2, 20);
 					}
 				}
@@ -687,7 +674,7 @@ int isReadSimInfo(void)
 						{
 							substr(tmp, tmp, 6, strlen(tmp)-6);
 						}
-
+						memset(Dongle.IMSI, 0x00, ARRAY_SIZE(Dongle.IMSI));
 						strncpy(Dongle.IMSI, tmp, strlen(tmp));
 					}
 				}
@@ -710,6 +697,7 @@ int isReadSimInfo(void)
 					{
 						memcpy(tmp, rx, strcspn(rx, "OK"));
 						memset(rx, 0, sizeof rx);
+						memset(Dongle.ICCID, 0x00, ARRAY_SIZE(Dongle.ICCID));
 						strncpy(Dongle.ICCID, tmp + strcspn(tmp, ":") + 2, 20);
 					}
 				}
@@ -721,9 +709,7 @@ int isReadSimInfo(void)
 	}
 	else
 	{
-		#ifdef SystemLogMessage
 		DEBUG_ERROR("%s open fail.\n", portName[Dongle.Model]);
-		#endif
 		result = FAIL;
 	}
 
@@ -1198,10 +1184,22 @@ int main(void)
 					Dongle.cnt_SearchModuleFail = 0;
 					if(isReadInfo() == PASS)
 					{
+						if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, Dongle.MODELNAME) != 0)
+							memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName));
 						memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModelName, Dongle.MODELNAME, sizeof Dongle.MODELNAME);
+
+						if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, Dongle.REVISION) != 0)
+							memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer));
 						memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSoftwareVer, Dongle.REVISION, sizeof Dongle.REVISION);
+
+						if(strcmp((char*)ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, Dongle.REVISION) != 0)
+							memset(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev));
 						memcpy(ShmSysConfigAndInfo->SysInfo.TelcomModemFwRev, Dongle.REVISION, sizeof Dongle.REVISION);
+
+						if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, Dongle.IMEI) != 0)
+							memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei));
 						memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemImei, Dongle.IMEI, sizeof Dongle.IMEI);
+
 						ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi = Dongle.CSQ;
 						ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomModemMode = Dongle.MODE;
 
@@ -1220,7 +1218,13 @@ int main(void)
 						if(isReadSimInfo() == PASS)
 						{
 							ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimStatus = 1;
+
+							if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, Dongle.ICCID) != 0)
+								memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid));
 							memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimIccid, Dongle.ICCID, sizeof Dongle.ICCID);
+
+							if(strcmp((char*)ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, Dongle.IMSI) != 0)
+								memset(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, 0x00, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi));
 							memcpy(ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomSimImsi, Dongle.IMSI, sizeof Dongle.IMSI);
 
 							DEBUG_INFO("========================================\n");

+ 2 - 2
EVSE/Modularization/Module_EventLogging.c

@@ -467,7 +467,7 @@ int main(void)
 						if(((tmp>>BitCount)&0x01)==0)//Recovered
 						{
 							EventCodeTmp[0]='1';
-							ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount]&=(0<<BitCount);
+							ShmStatusCodeData->AlarmCode.PreviousAlarmVal[ByteCount]&=~(1<<BitCount);
 							RemoveFaultCodeToBuf(EventCodeDisp);
 						}
 						else
@@ -499,7 +499,7 @@ int main(void)
 						if(((tmp>>BitCount)&0x01)==0)//Recovered
 						{
 							EventCodeTmp[0]='1';
-							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount]&=(0<<BitCount);
+							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount]&=~(1<<BitCount);
 							RemoveFaultCodeToBuf(EventCodeDisp);
 						}
 						else

+ 327 - 0
EVSE/Modularization/Module_InitUpgrade.c

@@ -0,0 +1,327 @@
+/*
+ * Module_InitUpgrade.c
+ *
+ *  Created on: 2021/01/29
+ *      Author: foluswen
+ */
+
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include 	<errno.h>
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<sys/types.h>
+#include 	<sys/socket.h>
+#include 	<netinet/in.h>
+#include 	<netdb.h>
+#include 	<error.h>
+#include 	<signal.h>
+#include	"define.h"
+
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+
+#define is_error(ptr) 				((unsigned long)ptr > (unsigned long)-4000L)
+#define ARRAY_SIZE(A)				(sizeof(A) / sizeof(A[0]))
+#define PASS						1
+#define FAIL			   			-1
+#define ON							1
+#define OFF							0
+#define YES							1
+#define NO							0
+#define true			    		1
+#define false						0
+#define MtdBlockSize				0x600000
+
+struct SysConfigAndInfo		*ShmSysConfigAndInfo;
+struct StatusCodeData 		*ShmStatusCodeData;
+
+
+//==========================================
+// Common routine
+//==========================================
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	struct timeval tv;
+	va_list args;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	CurrentTime = time((time_t*)NULL);
+	tm=localtime(&CurrentTime);
+	gettimeofday(&tv, NULL); // get microseconds, 10^-6
+
+
+	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]Module_InitUpgradeLog",
+				tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
+				buffer,
+				tm->tm_year+1900,tm->tm_mon+1);
+
+#ifdef SystemLogMessage
+	system(Buf);
+#endif
+
+#ifdef ConsloePrintLog
+	printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
+#endif
+
+	return rc;
+}
+
+int DiffTimeb(struct timeb ST, struct timeb ET)
+{
+	//return milli-second
+	unsigned int StartTime,StopTime;
+
+	StartTime=(unsigned int)ST.time;
+	StopTime=(unsigned int)ET.time;
+	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
+}
+
+int runShellCmd(const char*cmd)
+{
+	int result = FAIL;
+	char buf[256];
+	FILE *fp;
+
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			DEBUG_INFO("%s\n", buf);
+		}
+
+		result = PASS;
+	}
+	pclose(fp);
+
+	return result;
+}
+
+int StoreUsrConfigData(struct SysConfigData *UsrData)
+{
+	int result = PASS;
+	int fd,wrd;
+	unsigned int i,Chk;
+	unsigned char *ptr, *BufTmp;
+
+	Chk=0;
+	ptr=(unsigned char *)UsrData;
+	if((BufTmp=malloc(MtdBlockSize))!=NULL)
+	{
+		memset(BufTmp,0,MtdBlockSize);
+		memcpy(BufTmp,ptr,sizeof(struct SysConfigData));
+		for(i=0;i<MtdBlockSize-4;i++)
+			Chk+=*(BufTmp+i);
+		memcpy(BufTmp+MtdBlockSize-4, &Chk, 4);
+
+		// Output configuration to file.
+		fd = open("/mnt/EvseConfig.bin", O_RDWR|O_CREAT);
+		if (fd < 0)
+		{
+			DEBUG_ERROR("open /mnt/EvseConfig.bin NG\n");
+
+			free(BufTmp);
+			return 0;
+		}
+		wrd=write(fd, BufTmp, MtdBlockSize);
+		close(fd);
+		if(wrd<MtdBlockSize)
+		{
+			DEBUG_ERROR("write /mnt/EvseConfig.bin NG\n");
+
+			free(BufTmp);
+			return 0;
+		}
+		DEBUG_INFO("EvseConfig write to file in /mnt OK.\n");
+
+
+		DEBUG_INFO("Erase /dev/mtd10.\n");
+		runShellCmd("flash_erase /dev/mtd10 0 12");
+		DEBUG_INFO("Write /dev/mtd10.\n");
+		runShellCmd("nandwrite -p /dev/mtd10 /mnt/EvseConfig.bin");
+
+		DEBUG_INFO("Erase /dev/mtd11.\n");
+		runShellCmd("flash_erase /dev/mtd11 0 12");
+		DEBUG_INFO("Write /dev/mtd11.\n");
+		runShellCmd("nandwrite -p /dev/mtd11 /mnt/EvseConfig.bin");
+
+
+		system("rm -f /mnt/EvseConfig.bin");
+		DEBUG_INFO("EvseConfig write to flash OK\n");
+	}
+	else
+	{
+		DEBUG_ERROR("alloc BlockSize NG\r\n");
+			result = FAIL;
+	}
+
+	if(BufTmp!=NULL)
+		free(BufTmp);
+
+	return result;
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//Initial ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
+    	result = FAIL;
+   	 }
+    else
+    {}
+
+   	//Initial ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
+   		result = FAIL;
+	}
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
+    	result = FAIL;
+   	}
+    else
+    {}
+
+
+    return result;
+}
+
+//==========================================
+// Main process
+//==========================================
+int main(void)
+{
+	char cmd[512] = {0};
+	uint8_t retryCnt = 0;
+
+	// Initial share memory
+	if(InitShareMemory() == FAIL)
+	{
+		DEBUG_ERROR("InitShareMemory NG\n");
+
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
+		}
+		sleep(5);
+		return 0;
+	}
+
+	for(;;)
+	{
+		if((strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) >= 14) &&
+		   ShmSysConfigAndInfo->SysInfo.InternetConn &&
+		   ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade)
+		{
+			system("ping 8.8.8.8 &");
+
+			// Delete old file if exist
+			runShellCmd("rm -f /mnt/LatestImage.zip");
+
+			// Download file by model name
+			DEBUG_INFO("Download %s latest image file.\n", ShmSysConfigAndInfo->SysConfig.ModelName);
+			memset(cmd, 0x00, ARRAY_SIZE(cmd));
+			sprintf(cmd, "wget --tries=3 -O /mnt/LatestImage.zip -c ftp://ui:ph123456@ftp.phihong.com.tw/Upgrade/%s/LatestImage.zip -T 120", ShmSysConfigAndInfo->SysConfig.ModelName);
+			//DEBUG_INFO("%s\n", cmd);
+
+			if(system(cmd) == 0)
+			{
+				DEBUG_INFO("File download success\n");
+
+				DEBUG_INFO("Unzip download file\n");
+				runShellCmd("unzip -oq /mnt/LatestImage.zip -d /mnt");
+
+				DEBUG_INFO("OFF first upgrade request\n");
+				ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade = OFF;
+				if(StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig))
+				{
+					DEBUG_INFO("ShmSysConfigAndInfo->SysConfig update success\n");
+				}
+				else
+				{
+					DEBUG_INFO("ShmSysConfigAndInfo->SysConfig update fail\n");
+				}
+
+				DEBUG_INFO("Trigger upgrade request\n");
+				ShmSysConfigAndInfo->SysInfo.FirmwareUpdate = ON;
+			}
+			else
+			{
+				DEBUG_ERROR("Image download fail\n");
+				if(retryCnt > 10)
+				{
+					DEBUG_INFO("File download retry over 10 times, disable upgrade request.\n");
+					ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade = OFF;
+					if(StoreUsrConfigData(&ShmSysConfigAndInfo->SysConfig))
+					{
+						DEBUG_INFO("ShmSysConfigAndInfo->SysConfig update success\n");
+					}
+					else
+					{
+						DEBUG_INFO("ShmSysConfigAndInfo->SysConfig update fail\n");
+					}
+				}
+				else
+				{
+					retryCnt += 1;
+				}
+			}
+
+			// Delete download file
+			runShellCmd("rm -f /mnt/LatestImage.zip");
+			system("pkill ping");
+		}
+
+		sleep(10);
+	}
+
+	return FAIL;
+}

+ 60 - 1
EVSE/Modularization/WebService.c

@@ -1744,7 +1744,12 @@ int main(int argc, char *argv[]) {
 				StartDateTime[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StartDateTime);
 				StopDateTime[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StopDateTime);
 				StartMethod[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StartMethod);
-				ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp == 0){
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp-60);
+				}
 				CcsGunQty++;
 			}
 			else if(connectorType1 == 2){//GB
@@ -1764,6 +1769,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StopDateTime);
 				StartMethod[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StartMethod);
 				ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp-60);
+				}
 				GbGunQty++;
 			}
 			else if(connectorType1 == 3){//CHAdeMO
@@ -1783,6 +1794,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[0] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StopDateTime);
 				StartMethod[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StartMethod);
 				ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[0] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp-60);
+				}
 				CHAdeMOGunQty++;
 			}
 			else if(connectorType1 == 4){//AC
@@ -1823,6 +1840,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StopDateTime);
 				StartMethod[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StartMethod);
 				ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp-60);
+				}
 				CcsGunQty++;
 			}
 			else if(connectorType2 == 2){//GB
@@ -1842,6 +1865,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StopDateTime);
 				StartMethod[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StartMethod);
 				ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp-60);
+				}
 				GbGunQty++;
 			}
 			else if(connectorType2 == 3){//CHAdeMO
@@ -1861,6 +1890,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[1] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StopDateTime);
 				StartMethod[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StartMethod);
 				ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[1] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp-60);
+				}
 				CHAdeMOGunQty++;
 			}
 			else if(connectorType2 == 4){//AC
@@ -1901,6 +1936,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[2] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StopDateTime);
 				StartMethod[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].StartMethod);
 				ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.CcsChargingData[CcsGunQty].ConnectorTemp-60);
+				}
 				CcsGunQty++;
 			}
 			else if(connectorType3 == 2){//GB
@@ -1920,6 +1961,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[2] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StopDateTime);
 				StartMethod[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].StartMethod);
 				ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.GbChargingData[GbGunQty].ConnectorTemp-60);
+				}
 				GbGunQty++;
 			}
 			else if(connectorType3 == 3){//CHAdeMO
@@ -1939,6 +1986,12 @@ int main(int argc, char *argv[]) {
 				StopDateTime[2] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StopDateTime);
 				StartMethod[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].StartMethod);
 				ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp == 0 ){
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[2] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ChademoChargingData[CHAdeMOGunQty].ConnectorTemp-60);
+				}
 				CHAdeMOGunQty++;
 			}
 			else if(connectorType3 == 4){//AC
@@ -1981,6 +2034,12 @@ int main(int argc, char *argv[]) {
 				DDStopDateTime[i] = json_object_new_string((char *)&ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.StopDateTime);
 				DDStartMethod[i] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.StartMethod);
 				DDConnectorTemp[i] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.ConnectorTemp);
+				if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.ConnectorTemp == 0 ){
+					ConnectorTemp[i] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.ConnectorTemp);
+				}
+				else{
+					ConnectorTemp[i] = json_object_new_int(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].GeneralChargingData.ConnectorTemp-60);
+				}
 			}
 		}
 		//network

+ 2 - 2
EVSE/Modularization/ocpp20/JsonParser.c

@@ -37,7 +37,7 @@ static char *requestNames[] = { "CancelReservation",
 								"PublishFirmware",
 								"RemoteStartTransaction",
 								"RemoteStopTransaction",
-								"ReserveNowTransaction",
+								"ReserveNow",
 								"Reset",
 								"SendLocalList",
 								"SetChargingProfile",
@@ -130,7 +130,7 @@ static FunCallPtr funcalls[] = {handleCancelReservationRequest,
 								handlePublishFirmwareRequest,
 								handleRemoteStartTransactionRequest,
 								handleRemoteStopTransactionRequest,
-								handleReserveNowTransactionRequest,
+								handleReserveNowRequest,
 								handleResetRequest,
 								handleSendLocalListRequest,
 								handleSetChargingProfileRequest,

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 303 - 191
EVSE/Modularization/ocpp20/MessageHandler.c


+ 2 - 2
EVSE/Modularization/ocpp20/MessageHandler.h

@@ -932,7 +932,7 @@ int handleInstallCertificateRequest(char *uuid, char *payload);
 int handlePublishFirmwareRequest(char *uuid, char *payload);
 int handleRemoteStartTransactionRequest(char *uuid, char *payload);
 int handleRemoteStopTransactionRequest(char *uuid, char *payload);
-int handleReserveNowTransactionRequest(char *uuid, char *payload);
+int handleReserveNowRequest(char *uuid, char *payload);
 int handleResetRequest(char *uuid, char *payload);
 int handleSendLocalListRequest(char *uuid, char *payload);
 int handleSetChargingProfileRequest(char *uuid, char *payload);
@@ -990,7 +990,7 @@ int ftpDownLoadFile(char *location, char *user, char *password, int port, char *
 void *UpdateFirmwareProcess(void* data);
 void* GetDiagnosticsProcess(void* data);
 int httpUploadFile(char *location, char *path, char *filename,char *url);
-int ftpFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename);
+int ftpUploadFile(char *location, char *user, char *password, int port, char *path, char *fnamePlusPath,char *filename);
 int get_file_contents(const char* filename, char** outbuffer);
 void LWS_Send(char * str);
 void LWS_SendNow(char * str);

+ 24 - 13
EVSE/Modularization/ocpp20/Module_OcppBackend20.c

@@ -28,8 +28,8 @@ static int OfflineTransactionQueueNum = 0;  // Number of offline transactions
 static int OfflineTransaction = 0;
 static int IsUsing = FALSE;
 
-char OcppPath[160]={0};
-char OcppProtocol[10]={0},OcppHost[50]={0}, OcppTempPath[50]={0};
+char OcppPath[384]={0};
+char OcppProtocol[10]={0},OcppHost[128]={0}, OcppTempPath[256]={0};
 int OcppPort=0;
 unsigned char StartTransactionIdTagTemp[20]={0};
 uint32_t startTimeDog;
@@ -37,6 +37,7 @@ uint32_t startTimeQueue;
 uint8_t	isWebsocketSendable = 1;
 uint8_t	counterLwsRestart = 0;;
 uint8_t counterQueueSent = 0;
+uint8_t	counterConnect = 0;
 
 //=================================
 // Common routine
@@ -204,6 +205,7 @@ static int OCPP20Callback(struct lws *wsi, enum lws_callback_reasons reason, voi
 
 			//connected
 			ConnectionEstablished=1;
+			SetOcppConnStatus(TRUE);
 
 			queueNotEmpty = queue_operation(QUEUE_OPERATION_SHOWFRONT,frontUUID, frontData);
 
@@ -358,6 +360,7 @@ void* ConnectWsServer(void* data)  //int ConnectWsServer()
 	struct lws_context_creation_info ContextInfo;
 	struct lws_client_connect_info ConnInfo;
 	int use_ssl=0;
+	counterConnect += 1;
 
 	// If internet available synchronize datetime with ntp server
 	if(GetInternetConn() == 1)
@@ -465,6 +468,9 @@ void* ConnectWsServer(void* data)  //int ConnectWsServer()
 		goto end;
 	}
 
+	counterConnect=0;
+	DEBUG_INFO("counterConnect: %d\n", counterConnect);
+
 end:
 	pthread_exit(NULL/*(void *) fname*/);
 }
@@ -481,7 +487,7 @@ int isQueueOverSize()
 		fseek(fp, 0L, SEEK_END);
 		file_size = ftell(fp);
 
-		if(file_size > (500*1024*1024))
+		if(file_size > (100*1024*1024))
 		{
 			result = TRUE;
 
@@ -834,7 +840,7 @@ int sentqueue(){
 	FILE *fp;
 	int result = FALSE; // 1: TRUE  0:FALSE
 	char str[QUEUE_MESSAGE_LENGTH]={0};
-	char rmFileCmd[100]={0};
+	char cmdBuf[100]={0};
 	struct stat stats;
 	json_object *queueJson;
 
@@ -850,26 +856,25 @@ int sentqueue(){
 	else
 	{
 		//DEBUG_INFO("\n OCPP directory not exist, create dir \n");
-		sprintf(rmFileCmd,"mkdir -p %s","/Storage/OCPP");
-		system(rmFileCmd);
+		sprintf(cmdBuf,"mkdir -p %s","/Storage/OCPP");
+		system(cmdBuf);
 	}
 
-	memset(rmFileCmd, 0, ARRAY_SIZE(rmFileCmd));
-
 	/* opening file for reading */
 	fp = fopen("/Storage/OCPP/TransactionRelatedQueue" , "r");
-	if(fp == NULL) {
-		DEBUG_INFO("Error opening file");
+	if(fp == NULL)
+	{
+		DEBUG_ERROR("Error opening file");
 		return FALSE;
 	}
 
 	if( fgets (str, QUEUE_MESSAGE_LENGTH, fp)!=NULL )
 	{
-		queueJson = json_tokener_parse(str+2);
+		queueJson = json_tokener_parse(str);
 
 		if(!is_error(queueJson))
 		{
-			LWS_Send(str+2);
+			LWS_Send(str);
 		}
 		json_object_put(queueJson);
 
@@ -991,6 +996,12 @@ void* processWatchdog()
 			startTimeDog = time((time_t*)NULL);
 		}
 		
+		if(counterConnect >= 2)
+		{
+			DEBUG_INFO("Connect OCPP server timeout over 3 count.\n");
+			system("pkill OcppBackend");
+		}
+
 		/*
 		if(system("pidof -s Module_PhBackend > /dev/null") != 0)
 		{
@@ -1114,7 +1125,7 @@ int main(void)
 	char rmFileCmd[100]={0};
 	struct stat stats;
 
-	DEBUG_INFO("Module_OcppBackend task initialization...\n");
+	DEBUG_INFO("Module_OcppBackend20 task initialization...\n");
 	//lws_set_log_level(LLL_PARSER | LLL_HEADER | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO | LLL_DEBUG | LLL_EXT | LLL_CLIENT | LLL_LATENCY  , NULL);
 
 	if(ProcessShareMemory()== FAIL)

+ 13 - 3
EVSE/Modularization/ocpp20/Module_OcppBackend20.h

@@ -61,6 +61,16 @@ typedef enum {
 	ON
 }Switch_Value;
 
+enum GUN_TYPE
+{
+	GUN_TYPE_UNKNOWN=0,
+	GUN_TYPE_CHAdeMO,
+	GUN_TYPE_CCS,
+	GUN_TYPE_GBT,
+	GUN_TYPE_DO,
+	GUN_TYPE_AC
+};
+
 #ifndef SPEC_LATEST_SUPPORTED
 	#define SPEC_LATEST_SUPPORTED 	13
 #endif
@@ -145,10 +155,10 @@ extern struct lws 					*wsi_client;
 extern struct lws_context 			*context;
 extern unsigned char 				SendBuffer[1024*20];
 extern int 							SendBufLen;
-extern char 						OcppPath[160];
+extern char 						OcppPath[384];
 extern char 						OcppProtocol[10];
-extern char 						OcppHost[50];
-extern char 						OcppTempPath[50];
+extern char 						OcppHost[128];
+extern char 						OcppTempPath[256];
 extern int 							OcppPort;
 extern unsigned char 				StartTransactionIdTagTemp[20];
 extern pthread_mutex_t 				lock_send;

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 254 - 145
EVSE/Modularization/ocppfiles/MessageHandler.c


+ 12 - 1
EVSE/Modularization/ocppfiles/Module_OcppBackend.c

@@ -36,8 +36,9 @@ unsigned char StartTransactionIdTagTemp[20]={0};
 uint32_t startTimeDog;
 uint32_t startTimeQueue;
 uint8_t	isWebsocketSendable = 1;
-uint8_t	counterLwsRestart = 0;;
+uint8_t	counterLwsRestart = 0;
 uint8_t counterQueueSent = 0;
+uint8_t	counterConnect = 0;
 
 sqlite3 *db;
 char *errMsg = NULL;
@@ -416,6 +417,7 @@ void* ConnectWsServer(void* data)  //int ConnectWsServer()
 	struct lws_context_creation_info ContextInfo;
 	struct lws_client_connect_info ConnInfo;
 	int use_ssl=0;
+	counterConnect += 1;
 
 	// If internet available synchronize datetime with ntp server
 	if(GetInternetConn() == 1)
@@ -523,6 +525,9 @@ void* ConnectWsServer(void* data)  //int ConnectWsServer()
 		goto end;
 	}
 
+	counterConnect=0;
+	DEBUG_INFO("counterConnect: %d\n", counterConnect);
+
 end:
 	pthread_exit(NULL/*(void *) fname*/);
 }
@@ -1264,6 +1269,12 @@ void* processWatchdog()
 
 			startTimeDog = time((time_t*)NULL);
 		}
+
+		if(counterConnect >= 2)
+		{
+			DEBUG_INFO("Connect OCPP server timeout over 3 count.\n");
+			system("pkill OcppBackend");
+		}
 		
 		/*
 		if(system("pidof -s Module_PhBackend > /dev/null") != 0)

+ 9 - 0
EVSE/Modularization/ocppfiles/Module_OcppBackend.h

@@ -76,6 +76,15 @@
 #define QUEUE_OPERATION_STORE		5
 #define QUEUE_MESSAGE_LENGTH		3584
 
+enum GUN_TYPE
+{
+	GUN_TYPE_UNKNOWN=0,
+	GUN_TYPE_CHAdeMO,
+	GUN_TYPE_CCS,
+	GUN_TYPE_GBT,
+	GUN_TYPE_DO,
+	GUN_TYPE_AC
+};
 
 struct yuarel {
 	char *scheme; /* scheme, without ":" and "//" */

+ 0 - 615
EVSE/Projects/AW-CCS/Apps/LCM/Image.h

@@ -1,615 +0,0 @@
-/*
- * Image.h
- *
- *  Created on: 2020�9る3ら
- *      Author: foluswen
- */
-
-#ifndef IMAGE_H_
-#define IMAGE_H_
-
-uint8_t LAN_Icon[2][7] = {
-		{ 0xfe, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xfe},
-		{ 0xfe, 0x82, 0xba, 0xaa, 0xba, 0x82, 0xfe}
-
-};
-uint8_t RF_Icon[6][21] = {
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xea, 0xa0, 0x0e, 0xaa, 0xa0, 0xea, 0xaa, 0xa0, 0xaa, 0xaa, 0xa0, 0xee, 0xee, 0xe0},
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xea, 0xa0, 0x0e, 0xaa, 0xa0, 0xea, 0xaa, 0xa0, 0xea, 0xaa, 0xa0, 0xee, 0xee, 0xe0},
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xea, 0xa0, 0x0e, 0xaa, 0xa0, 0xee, 0xaa, 0xa0, 0xee, 0xaa, 0xa0, 0xee, 0xee, 0xe0},
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xea, 0xa0, 0x0e, 0xea, 0xa0, 0xee, 0xea, 0xa0, 0xee, 0xea, 0xa0, 0xee, 0xee, 0xe0},
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xee, 0xa0, 0x0e, 0xee, 0xa0, 0xee, 0xee, 0xa0, 0xee, 0xee, 0xa0, 0xee, 0xee, 0xe0},
-	{0x00, 0x00, 0xe0, 0x00, 0x0e, 0xa0, 0x00, 0xee, 0xa0, 0x0e, 0xee, 0xa0, 0xee, 0xee, 0xa0, 0xee, 0xee, 0xa0, 0xee, 0xee, 0xe0}
-};
-
-uint8_t img_init[] = {
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x01, 0xf8, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00,
-		  0x03, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xfc, 0x00, 0x00, 0x00,
-		  0x06, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, 0x00, 0x00,
-		  0x06, 0x00, 0xfc, 0x7c, 0x79, 0xfa, 0x7e, 0x3f, 0x00, 0x00, 0x3f, 0xe0, 0x1f, 0xe0, 0x00, 0x00,
-		  0x04, 0x00, 0xc4, 0xcc, 0x63, 0x3a, 0x62, 0x67, 0x00, 0x00, 0x7c, 0x00, 0x01, 0xf8, 0x00, 0x00,
-		  0x04, 0x00, 0x86, 0x04, 0x42, 0x1a, 0x43, 0x43, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x3e, 0x00, 0x00,
-		  0x04, 0x00, 0x86, 0x3e, 0x42, 0x1a, 0x43, 0x43, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x1e, 0x00, 0x00,
-		  0x06, 0x00, 0x86, 0xe6, 0x42, 0x1a, 0x43, 0x43, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x07, 0x80, 0x00,
-		  0x06, 0x04, 0x86, 0x86, 0x42, 0x1a, 0x43, 0x43, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00,
-		  0x03, 0x1c, 0x86, 0xce, 0x43, 0x3a, 0x43, 0x67, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00,
-		  0x01, 0xf8, 0x86, 0x7e, 0x41, 0xf2, 0x43, 0x3e, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x30, 0x00, 0x01, 0x00, 0x00, 0xe0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x00, 0x66, 0x00, 0xf0, 0x00, 0x03, 0x00, 0x00, 0x30, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x3c, 0x00, 0xe0, 0x00, 0x03, 0x00, 0x00, 0x31, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x06, 0x00, 0x00, 0x11, 0x88,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x88,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x88,
-		  0x03, 0xf1, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x88,
-		  0x06, 0x19, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x98,
-		  0x04, 0x09, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x03, 0xfc,
-		  0x06, 0x03, 0xcf, 0xbc, 0x8f, 0x9f, 0x80, 0x0f, 0xf0, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x03, 0xfc,
-		  0x07, 0xc1, 0x19, 0x90, 0x98, 0x98, 0x80, 0x1e, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x03, 0xfc,
-		  0x00, 0xf9, 0x00, 0x90, 0x90, 0x90, 0xc0, 0x38, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x03, 0xfc,
-		  0x00, 0x19, 0x07, 0xd0, 0x90, 0x90, 0xc0, 0x70, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x03, 0xfc,
-		  0x00, 0x0d, 0x1c, 0xd0, 0x90, 0xd0, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xfc,
-		  0x04, 0x09, 0x10, 0xd0, 0x90, 0xd0, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x01, 0xf8,
-		  0x07, 0x19, 0x19, 0xd0, 0x99, 0x90, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf0,
-		  0x03, 0xf1, 0xcf, 0xdc, 0x8f, 0x90, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0xf0,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x06, 0x00, 0x00, 0x80, 0x00, 0x08, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x80, 0x01, 0x80, 0x00, 0x3e, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xc0, 0x01, 0x00, 0x00, 0x3f, 0x00, 0x60,
-		  0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xc0, 0x02, 0x00, 0x00, 0x7f, 0x01, 0xc0,
-		  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xc0, 0x02, 0x00, 0x00, 0x7f, 0x01, 0xc0,
-		  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xbf, 0x80,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xc0, 0x7f, 0xff, 0xfe, 0xff, 0xbf, 0x80,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xcf, 0xff, 0xff, 0xff, 0x7f, 0x3e, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xdf, 0xff, 0xff, 0xff, 0x7f, 0x30, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xd8, 0x00, 0x00, 0x07, 0x7f, 0x30, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xb0, 0x00, 0x00, 0x03, 0x3e, 0x60, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0x30, 0x00, 0x00, 0x03, 0x1e, 0x60, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x70, 0x00, 0x00, 0x01, 0xc0, 0xc0, 0x00,
-		  0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00,
-		  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00,
-		  0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
-		  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_rfid[] = {
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf8, 0x00,
-		0x00, 0x00, 0x00, 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0f, 0x80, 0x00, 0x00, 0x01, 0xe0, 0x03, 0xe0,
-		0x00, 0x00, 0x03, 0x81, 0xc0, 0xf0, 0x00, 0x00, 0x07, 0x0f, 0xf8, 0x78, 0x00, 0x00, 0x0e, 0x3f, 0xfe, 0x38,
-		0x00, 0x00, 0x1c, 0x78, 0x0f, 0x1c, 0x00, 0x00, 0x1c, 0xe0, 0x03, 0x8c, 0x00, 0x00, 0x18, 0xc3, 0xe1, 0xce,
-		0x00, 0x00, 0x31, 0xc7, 0xf9, 0xce, 0x00, 0x00, 0x26, 0x02, 0x38, 0xc6, 0x00, 0x00, 0x2f, 0xfe, 0x18, 0xc6,
-		0x00, 0x00, 0x2f, 0xff, 0x98, 0xc6, 0x00, 0x00, 0x2f, 0xff, 0xb8, 0xc6, 0x00, 0x00, 0x0f, 0xff, 0xb9, 0xce,
-		0x00, 0x03, 0xef, 0xff, 0x71, 0xce, 0x00, 0x0f, 0xdf, 0xff, 0x03, 0x8c, 0x00, 0x1f, 0xdf, 0xff, 0x07, 0x1c,
-		0x00, 0x1f, 0x1f, 0xff, 0x3e, 0x38, 0x00, 0x3e, 0xdf, 0xff, 0x7c, 0x78, 0x00, 0x7e, 0x1f, 0xff, 0x60, 0xf0,
-		0x00, 0xfd, 0xdf, 0xfe, 0x01, 0xe0, 0x01, 0xfc, 0x3f, 0xfe, 0x0f, 0x80, 0x03, 0xfe, 0xb0, 0x7e, 0xff, 0x00,
-		0x07, 0xff, 0x07, 0xbe, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xde, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x1e, 0x00, 0x00,
-		0x3f, 0xff, 0xf8, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0xe1, 0xfc, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00,
-		0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_handshake_1[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x07, 0xff, 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x3f, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
-		  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00,
-		  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1e, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0xff, 0xcf, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xc7, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x1f, 0xe7, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_handshake_2[]={
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x07, 0xff, 0xc0, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x3f, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x70, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
-		  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1f, 0xc0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x30, 0x00, 0x3f, 0xe0, 0x00,
-		  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x7f, 0x00, 0xff, 0xf0, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0xff, 0x00, 0xff, 0xf8, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0xff, 0x00, 0xfc, 0x1c, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0xff, 0x00, 0xfe, 0x1e, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0xff, 0x00, 0xff, 0xcf, 0x00,
-		  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x7f, 0x00, 0x3f, 0xc7, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x30, 0x00, 0x1f, 0xe7, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x7f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_maintain[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x00, 0x00, 0x00, 0xc3, 0xff, 0xfc, 0x30, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x01, 0x91, 0x18, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x03, 0x30, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x06, 0x20, 0x8c, 0x00, 0x00, 0x00, 0x98, 0x00, 0x01, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x04, 0x60, 0xc4, 0x00, 0x00, 0x00, 0x90, 0x3f, 0xc0, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x04, 0x60, 0x46, 0x00, 0x41, 0x80, 0x90, 0x3f, 0xe0, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x60, 0x46, 0x00, 0xe1, 0xc0, 0x90, 0x1b, 0xe0, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x60, 0x42, 0x01, 0xe1, 0x60, 0x90, 0x3d, 0xc0, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x41, 0xa0, 0x90, 0x24, 0x00, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0f, 0xff, 0xfe, 0x03, 0x41, 0xa0, 0x98, 0x3c, 0x01, 0x90, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x02, 0x61, 0xa0, 0x88, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x03, 0x80, 0x3c, 0x02, 0x33, 0x20, 0x8e, 0x00, 0x07, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0d, 0xff, 0xf2, 0x03, 0x1c, 0x20, 0x83, 0xff, 0xfc, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x01, 0x08, 0x60, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x01, 0x80, 0x40, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x00, 0xc1, 0xc0, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x61, 0x80, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x61, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x01, 0xc0, 0x30, 0x00, 0x61, 0x00, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x71, 0xe0, 0x00, 0x61, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x61, 0x00, 0xff, 0xe7, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x00, 0xff, 0xcf, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x07, 0xff, 0xfc, 0x00, 0x61, 0x00, 0xff, 0x8f, 0x7f, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x61, 0x00, 0xff, 0x27, 0x5f, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x32, 0x40, 0x29, 0x80, 0x41, 0x80, 0xff, 0x72, 0x7f, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x62, 0xc0, 0x68, 0xc0, 0xc0, 0xc0, 0xff, 0xf8, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x42, 0xc0, 0x68, 0x61, 0x80, 0x60, 0xff, 0xf8, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc2, 0xc0, 0x68, 0x63, 0x00, 0x20, 0xff, 0xf2, 0x7f, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc2, 0xc0, 0x68, 0x23, 0x1c, 0x20, 0xff, 0xc7, 0x3f, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc2, 0xff, 0xe8, 0x22, 0x36, 0x20, 0xff, 0xff, 0xbf, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc2, 0x7f, 0xec, 0x22, 0x61, 0x20, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc6, 0x00, 0x04, 0x23, 0x61, 0x20, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc4, 0x00, 0x04, 0x21, 0x61, 0x60, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc4, 0xff, 0xe4, 0x21, 0xe1, 0x40, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc4, 0xc0, 0x64, 0x20, 0xe1, 0x80, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc4, 0xc0, 0x64, 0x20, 0x40, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0xc4, 0xc0, 0x64, 0x20, 0x00, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x20, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_verify[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xce, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xfc, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xf8, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xf9, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe7, 0xf3, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe7, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-
-uint8_t img_verify_ok[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xff, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xbe, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x1c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x88, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe7, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe3, 0xe3, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf7, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_verify_fail[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0xdf, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x8e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xe0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe7, 0xc0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe3, 0x8c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x9e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_alert[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x03, 0x80, 0x03, 0xc0, 0x06, 0xe0, 0x06, 0xe0,
-		  0x0e, 0xf0, 0x0e, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x3e, 0xfc, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_energy[] = {
-		  0x00, 0xe0, 0x00, 0x00, 0xe0, 0x00, 0x0f, 0xfc, 0x00, 0x1f, 0xfe, 0x00, 0x10, 0x02, 0x00,
-		  0x13, 0xfa, 0x00, 0x13, 0xfa, 0x00, 0x13, 0xfa, 0x00, 0x13, 0xfa, 0x00, 0x13, 0xfa, 0x00,
-		  0x13, 0xf8, 0x00, 0x13, 0xf8, 0x00, 0x13, 0xe0, 0x00, 0x13, 0xc3, 0x80, 0x13, 0xdf, 0x30,
-		  0x13, 0x9f, 0x78, 0x13, 0x18, 0x78, 0x13, 0x18, 0x38, 0x13, 0x1c, 0x38, 0x10, 0x1c, 0x78,
-		  0x10, 0x19, 0xf0, 0x1f, 0xcb, 0xe0, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_cost[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x03, 0xe7, 0xc0, 0x07, 0xc3, 0xe0,
-		  0x0f, 0xc0, 0xf0, 0x1f, 0x80, 0x78, 0x1e, 0x00, 0x78, 0x3e, 0x1f, 0xfc, 0x3e, 0x1f, 0xfc,
-		  0x3e, 0x01, 0xfc, 0x3f, 0x00, 0xfc, 0x3f, 0xc0, 0x7c, 0x3f, 0xe0, 0x7c, 0x3f, 0xf8, 0x7c,
-		  0x3e, 0x18, 0x7c, 0x1e, 0x00, 0x78, 0x0e, 0x01, 0xf0, 0x0f, 0xc3, 0xf0, 0x07, 0xc3, 0xe0,
-		  0x01, 0xff, 0x80, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_time[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x7f, 0xc0, 0x00, 0x00, 0x60,
-		  0x00, 0x00, 0x30, 0x00, 0x00, 0x18, 0x00, 0x00, 0x0c, 0x18, 0x00, 0x0c, 0x1c, 0x01, 0x04,
-		  0x3c, 0x02, 0x04, 0x3e, 0x0c, 0x06, 0x08, 0x0c, 0x06, 0x08, 0x00, 0x04, 0x08, 0x00, 0x04,
-		  0x0c, 0x00, 0x0c, 0x04, 0x00, 0x0c, 0x06, 0x00, 0x18, 0x03, 0x00, 0x30, 0x00, 0xc0, 0x60,
-		  0x00, 0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_price[] = {
-		  0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x10, 0x00, 0x23, 0x00, 0x03, 0xff, 0xc0, 0x23, 0x00,
-		  0x07, 0xff, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0xff, 0x80,
-		  0x3f, 0xc7, 0xf8, 0xff, 0x80, 0x3f, 0x81, 0xfc, 0xc0, 0x80, 0x7f, 0x00, 0xfe, 0xc0, 0x80,
-		  0x7e, 0x10, 0xfe, 0xc0, 0x80, 0x7e, 0x0d, 0xfe, 0x40, 0x00, 0xff, 0x01, 0xfe, 0x63, 0x00,
-		  0xff, 0x00, 0xfe, 0x3f, 0x00, 0x7f, 0xc0, 0xfe, 0x08, 0x00, 0x7e, 0x3c, 0xfe, 0x08, 0x00,
-		  0x7e, 0x10, 0xfe, 0x08, 0x00, 0x3e, 0x00, 0xfc, 0x08, 0x00, 0x3f, 0xc7, 0xfc, 0x08, 0x00,
-		  0x3f, 0xc7, 0xf8, 0x08, 0x00, 0x1f, 0xe7, 0xf8, 0x08, 0x00, 0x0f, 0xff, 0xf0, 0x18, 0x00,
-		  0x07, 0xff, 0xe0, 0x18, 0x00, 0x00, 0xff, 0x00, 0xc0, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
-};
-
-uint8_t img_icon_b0[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_b20[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x80, 0x00, 0x00, 0x00, 0x10, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x10, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f,
-		  0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f,
-		  0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x80, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_b40[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x9f, 0x80, 0x00, 0x00, 0x10, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x10, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f,
-		  0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f,
-		  0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x1f, 0x9f, 0x9f, 0x80, 0x00, 0x00, 0x10,
-		  0x9f, 0x9f, 0x80, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_b60[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x10, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x10, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f,
-		  0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f,
-		  0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x1f, 0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x10,
-		  0x9f, 0x9f, 0x9f, 0x80, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_b80[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x10, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x10, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x1f, 0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x10,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x80, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_b100[] = {
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x90, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x90, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x90,
-		  0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x90, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, 0x00, 0x10,
-		  0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-};
-
-uint8_t img_icon_complete[] = {
-		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x00, 0x00,
-		  0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00,
-		  0x00, 0x00, 0x3f, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x86, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8e, 0x00, 0x00,
-		  0xff, 0xfe, 0x70, 0x0e, 0x3f, 0xff, 0x00, 0x00, 0x70, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x78, 0x3e, 0x00, 0x00,
-		  0x00, 0x00, 0x3c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00,
-		  0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-
-
-#endif /* IMAGE_H_ */

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1050 - 796
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c


+ 0 - 890
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm.c

@@ -1,890 +0,0 @@
-/*
- * lcmComm.c
- *
- *  Created on: 2019年5月8日
- *      Author: foluswen
- */
-#include 	<sys/time.h>
-#include 	<sys/timeb.h>
-#include    <sys/types.h>
-#include    <sys/stat.h>
-#include 	<sys/types.h>
-#include 	<sys/ioctl.h>
-#include 	<sys/socket.h>
-#include 	<sys/ipc.h>
-#include 	<sys/shm.h>
-#include 	<sys/shm.h>
-#include 	<sys/mman.h>
-#include 	<linux/wireless.h>
-#include 	<arpa/inet.h>
-#include 	<netinet/in.h>
-
-#include 	<unistd.h>
-#include 	<stdarg.h>
-#include    <stdio.h>      /*標準輸入輸出定義*/
-#include    <stdlib.h>     /*標準函數庫定義*/
-#include    <unistd.h>     /*Unix 標準函數定義*/
-#include    <fcntl.h>      /*檔控制定義*/
-#include    <termios.h>    /*PPSIX 終端控制定義*/
-#include    <errno.h>      /*錯誤號定義*/
-#include 	<errno.h>
-#include 	<string.h>
-#include	<time.h>
-#include	<ctype.h>
-#include 	<ifaddrs.h>
-#include 	<math.h>
-#include 	"lcmComm.h"
-
-#define ARRAY_SIZE(A)			(sizeof(A) / sizeof(A[0]))
-#define PASS					1
-#define FAIL					-1
-#define YES						1
-#define NO						0
-
-SYS_FLAG sysFlag;
-
-//================================
-// Basic routine
-//================================
-void displayMessage(uint8_t *data, uint16_t len, uint8_t isRX)
-{
-	uint8_t output[8192];
-
-	memset(output, 0x00, ARRAY_SIZE(output));
-	sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
-	for(uint16_t idx = 0;idx<len;idx++)
-	{
-		sprintf((char*)output, "%s%02x ", output, data[idx]);
-	}
-
-	DEBUG_INFO("%s\n", output);
-}
-
-uint16_t crc16(uint8_t* data, uint16_t length)
-{
-	uint16_t reg_crc = 0xFFFF;
-
-	while(length--)
-	{
-		reg_crc ^= *data++;
-		for(uint8_t j=0;j<8;j++)
-		{
-			if(reg_crc& 0x01) /* LSB(b0)=1 */
-				reg_crc=(reg_crc>>1) ^ 0xA001;
-			else
-				reg_crc=reg_crc>>1;
-		}
-	}
-
-	return reg_crc;
-}
-
-int tranceive(int32_t fd, uint8_t *tx, uint16_t tx_len)
-{
-	int result = FAIL;
-	uint8_t rx[5];
-	uint8_t rx_len;
-	uint16_t chksum;
-
-	memset(rx, 0x00, ARRAY_SIZE(rx));
-
-	tcflush(fd,TCIOFLUSH);
-	displayMessage(tx, tx_len, NO);
-	if(write(fd, tx, tx_len) >= ARRAY_SIZE(tx))
-	{
-		rx_len = read(fd, rx, ARRAY_SIZE(rx));
-		if(rx_len > 0)
-			displayMessage(rx, rx_len, YES);
-		else
-			DEBUG_INFO("RX: NULL\n");
-
-		chksum=crc16(&rx[0], ARRAY_SIZE(rx)-2);
-
-		if((rx_len >= 5) &&
-		   (((chksum>>0)&0xff) == rx[3]) &&
-		   (((chksum>>8)&0xff) == rx[4]) &&
-		   (rx[1] == 0x00))
-		{
-			result = PASS;
-		}
-		else
-		{
-			DEBUG_WARN("Serial command read fail, checksum: 0x%04x.\n", chksum);
-		}
-	}
-	else
-	{
-		DEBUG_WARN("Serial command write fail.\n");
-	}
-
-	return result;
-}
-
-//================================
-// Application routine
-//================================
-int8_t clearScreen(int32_t fd, uint8_t isPartial, uint16_t startX, uint16_t startY, uint16_t width, uint16_t height)
-{
-	int8_t result = FAIL;
-	uint8_t tx[(isPartial?10:12)];
-	uint16_t chksum;
-
-	if(isPartial)
-	{
-		tx[0] = 0xa1;
-		tx[1] = (startX>>0)&0xff;
-		tx[2] = (startX>>8)&0xff;
-		tx[3] = (startY>>0)&0xff;
-		tx[4] = (startY>>8)&0xff;
-		tx[5] = (width>>0)&0xff;
-		tx[6] = (width>>8)&0xff;
-		tx[7] = (height>>0)&0xff;
-		tx[8] = (height>>8)&0xff;
-		tx[9] = (isPartial?0x01:0x00);
-		chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-		tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-		tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-	}
-	else
-	{
-		tx[0] = 0xa1;
-		tx[1] = (startX>>0)&0xff;
-		tx[2] = (startX>>8)&0xff;
-		tx[3] = (startY>>0)&0xff;
-		tx[4] = (startY>>8)&0xff;
-		tx[5] = (width>>0)&0xff;
-		tx[6] = (width>>8)&0xff;
-		tx[7] = (height>>0)&0xff;
-		tx[8] = (height>>8)&0xff;
-		tx[9] = (isPartial?0x01:0x00);
-
-		chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-		tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-		tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-	}
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t setContrast(int32_t fd, uint8_t startBrightness, uint8_t stopBrightness, uint8_t interval)
-{
-	int8_t result = FAIL;
-	uint8_t tx[6];
-	uint16_t chksum;
-
-	tx[0] = 0xa2;
-	tx[1] = startBrightness;
-	tx[2] = stopBrightness;
-	tx[3] = interval;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t setPower(int32_t fd, uint8_t isOn)
-{
-	int8_t result = FAIL;
-	uint8_t tx[4];
-	uint16_t chksum;
-
-	tx[0] = 0xa3;
-	tx[1] = (isOn?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t dispGraphic(int32_t fd, uint8_t isCover, uint16_t startX, uint16_t startY, uint8_t graphicID)
-{
-	int8_t result = FAIL;
-	uint8_t tx[10];
-	uint16_t chksum;
-
-	tx[0] = 0xb1;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (graphicID>>0)&0xff;
-	tx[6] = (graphicID>>8)&0xff;
-	tx[7] = (isCover?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t dispGraphicConfig(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endXX, uint16_t endY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[29];
-	uint16_t chksum;
-
-	tx[0] = 0xb4;
-	tx[1] = 0xf3;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (endXX>>0)&0xff;
-	tx[8] = (endXX>>8)&0xff;
-	tx[9] = (endY>>0)&0xff;
-	tx[10] = (endY>>8)&0xff;
-	tx[11] = 0x09;
-	tx[12] = 0x24;
-	tx[13] = 0xff;
-	tx[14] = 0xff;
-	tx[15] = 0xff;
-	tx[16] = 0xff;
-	tx[17] = 0x00;
-	tx[18] = 0x00;
-	tx[19] = 0x00;
-	tx[20] = 0x00;
-	tx[21] = 0x00;
-	tx[22] = 0x00;
-	tx[23] = 0x00;
-	tx[24] = 0x00;
-	tx[25] = 0x00;
-	tx[26] = (isCover?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(30000);
-	return result;
-}
-
-int8_t dispGraphicArea(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endXX, uint16_t endY, uint8_t graphicID)
-{
-	int8_t result = FAIL;
-	uint8_t tx[31];
-	uint16_t chksum;
-
-	tx[0] = 0xb4;
-	tx[1] = 0xf2;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (endXX>>0)&0xff;
-	tx[8] = (endXX>>8)&0xff;
-	tx[9] = (endY>>0)&0xff;
-	tx[10] = (endY>>8)&0xff;
-	tx[11] = 0x49;
-	tx[12] = 0x24;
-	tx[13] = 0xff;
-	tx[14] = 0xff;
-	tx[15] = 0xff;
-	tx[16] = 0xff;
-	tx[17] = 0x00;
-	tx[18] = 0x00;
-	tx[19] = 0x00;
-	tx[20] = 0x00;
-	tx[21] = 0x00;
-	tx[22] = 0x00;
-	tx[23] = 0x00;
-	tx[24] = 0x00;
-	tx[25] = 0x00;
-	tx[26] = (graphicID>>0)&0xff;
-	tx[27] = (graphicID>>8)&0xff;
-	tx[28] = (isCover?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(30000);
-	return result;
-}
-
-int8_t dispGraphicPartial(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t bmpX, uint16_t bmpY, uint16_t bmpW, uint16_t bmpH, uint8_t graphicID)
-{
-	int8_t result = FAIL;
-	uint8_t tx[20];
-	uint16_t chksum;
-
-	tx[0] = 0xb4;
-	tx[1] = 0x45;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (bmpX>>0)&0xff;
-	tx[8] = (bmpX>>8)&0xff;
-	tx[9] = (bmpY>>0)&0xff;
-	tx[10] = (bmpY>>8)&0xff;
-	tx[11] = (bmpW>>0)&0xff;
-	tx[12] = (bmpW>>8)&0xff;
-	tx[13] = (bmpH>>0)&0xff;
-	tx[14] = (bmpH>>8)&0xff;
-	tx[15] = (graphicID>>0)&0xff;
-	tx[16] = (graphicID>>8)&0xff;
-	tx[17] = (isCover?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(30000);
-	return result;
-}
-
-int8_t dispCharacter(int32_t fd, uint16_t startX, uint16_t startY, uint16_t font, uint8_t *data, uint8_t msgLen)
-{
-	int8_t result = FAIL;
-	uint8_t tx[9+msgLen];
-	uint16_t chksum;
-
-	tx[0] = 0xc1;
-
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (font>>0)&0xff;
-	memcpy(&tx[6], &data[0], msgLen);
-	tx[ARRAY_SIZE(tx)-3] = 0x00;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t dispCharacterConfig(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endXX, uint16_t endY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[29];
-	uint16_t chksum;
-
-	tx[0] = 0xc4;
-	tx[1] = 0xf3;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (endXX>>0)&0xff;
-	tx[8] = (endXX>>8)&0xff;
-	tx[9] = (endY>>0)&0xff;
-	tx[10] = (endY>>8)&0xff;
-	tx[11] = 0x09;
-	tx[12] = 0x24;
-	tx[13] = 0xff;
-	tx[14] = 0xff;
-	tx[15] = 0xff;
-	tx[16] = 0xff;
-	tx[17] = 0x00;
-	tx[18] = 0x00;
-	tx[19] = 0x00;
-	tx[20] = 0x00;
-	tx[21] = 0x00;
-	tx[22] = 0x00;
-	tx[23] = 0x00;
-	tx[24] = 0x00;
-	tx[25] = 0x00;
-	tx[26] = (isCover?0x01:0x00);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	//result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(30000);
-	return result;
-}
-
-int8_t dispCharacterArea(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint16_t font, uint8_t *data, uint8_t msgLen)
-{
-	int8_t result = FAIL;
-	uint8_t tx[30+msgLen];
-	uint16_t chksum;
-
-	tx[0] = 0xc4;
-	tx[1] = 0xf2;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (endX>>0)&0xff;
-	tx[8] = (endX>>8)&0xff;
-	tx[9] = (endY>>0)&0xff;
-	tx[10] = (endY>>8)&0xff;
-	tx[11] = 0x49;
-	tx[12] = 0x24;
-	tx[13] = 0xff;
-	tx[14] = 0xff;
-	tx[15] = 0xff;
-	tx[16] = 0xff;
-	tx[17] = 0x00;
-	tx[18] = 0x00;
-	tx[19] = 0x00;
-	tx[20] = 0x00;
-	tx[21] = 0x00;
-	tx[22] = 0x00;
-	tx[23] = 0x00;
-	tx[24] = 0x00;
-	tx[25] = 0x00;
-	tx[26] = (font>>0)&0xff;
-	memcpy(&tx[27], &data[0], msgLen);
-	tx[ARRAY_SIZE(tx)-3] = 0x00;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(25000);
-	return result;
-}
-
-int8_t dispCharacterScroll(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint16_t font, uint8_t isToRight, uint8_t speed, uint8_t *data, uint8_t msgLen)
-{
-	int8_t result = FAIL;
-	uint8_t tx[31+msgLen];
-	uint16_t chksum;
-
-	tx[0] = 0xc5;
-	tx[1] = 0xf2;
-	tx[2] = (areaId>=19?19:areaId);
-	tx[3] = (startX>>0)&0xff;
-	tx[4] = (startX>>8)&0xff;
-	tx[5] = (startY>>0)&0xff;
-	tx[6] = (startY>>8)&0xff;
-	tx[7] = (endX>>0)&0xff;
-	tx[8] = (endX>>8)&0xff;
-	tx[9] = (endY>>0)&0xff;
-	tx[10] = (endY>>8)&0xff;
-	tx[11] = 0x49;
-	tx[12] = 0x24;
-	tx[13] = 0xff;
-	tx[14] = 0xff;
-	tx[15] = 0xff;
-	tx[16] = 0xff;
-	tx[17] = 0x00;
-	tx[18] = 0x00;
-	tx[19] = 0x00;
-	tx[20] = 0x00;
-	tx[21] = 0x00;
-	tx[22] = 0x00;
-	tx[23] = 0x00;
-	tx[24] = 0x00;
-	tx[25] = 0x00;
-	tx[26] = (isToRight?0x01:0x00);
-	tx[27] = ((speed<25)?25:speed);
-	tx[28] = (font>>0)&0xff;
-
-	memcpy(&tx[30], &data[0], msgLen);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t dispCharacterBlink(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t font, uint8_t type, uint16_t time, uint8_t *data, uint8_t msgLen)
-{
-	int8_t result = FAIL;
-	uint8_t tx[12+msgLen];
-	uint16_t chksum;
-
-	tx[0] = 0xc3;
-	tx[1] = (areaId>=19?19:areaId);
-	tx[2] = (startX>>0)&0xff;
-	tx[3] = (startX>>8)&0xff;
-	tx[4] = (startY>>0)&0xff;
-	tx[5] = (startY>>8)&0xff;
-	tx[6] = (font>>0)&0xff;
-	tx[7] = type;
-	tx[8] = (time>>0)&0xff;
-	tx[9] = (time>>8)&0xff;
-	memcpy(&tx[10], &data[0], msgLen);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawAll(int32_t fd)
-{
-	int8_t result = FAIL;
-	uint8_t tx[7];
-	uint16_t chksum;
-
-	tx[0] = 0xd0;
-	tx[1] = 0xff;
-	tx[2] = 0xff;
-	tx[3] = 0xff;
-	tx[4] = 0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawPoint(int32_t fd, uint16_t startX, uint16_t startY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[7];
-	uint16_t chksum;
-
-	tx[0] = 0xd6;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawRect(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t isFill)
-{
-	int8_t result = FAIL;
-	uint8_t tx[11];
-	uint16_t chksum;
-
-	tx[0] = (isFill?0xd1:0xd4);
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (endX>>0)&0xff;
-	tx[6] = (endX>>8)&0xff;
-	tx[7] = (endY>>0)&0xff;
-	tx[8] = (endY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawRectCorner(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t radius, uint8_t isFill)
-{
-	int8_t result = FAIL;
-	uint8_t tx[12];
-	uint16_t chksum;
-
-	tx[0] = (isFill?0xd2:0xd5);
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (endX>>0)&0xff;
-	tx[6] = (endX>>8)&0xff;
-	tx[7] = (endY>>0)&0xff;
-	tx[8] = (endY>>8)&0xff;
-	tx[9] = (radius>15?15:radius);
-	tx[6] = 0xff;
-	tx[7] = 0xff;
-	tx[8] = 0xff;
-	tx[9] = 0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawRectMesh(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[11];
-	uint16_t chksum;
-
-	tx[0] = 0xd3;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (endX>>0)&0xff;
-	tx[6] = (endX>>8)&0xff;
-	tx[7] = (endY>>0)&0xff;
-	tx[8] = (endY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawLine(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[11];
-	uint16_t chksum;
-
-	tx[0] = 0xda;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (endX>>0)&0xff;
-	tx[6] = (endX>>8)&0xff;
-	tx[7] = (endY>>0)&0xff;
-	tx[8] = (endY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t drawRfSignal(int32_t fd, uint8_t strength, uint8_t is4G)
-{
-	int8_t result = PASS;
-	uint16_t startX = (is4G?109:(sysFlag.isEnable4G?83:109));
-	uint16_t startY = 0;
-
-	dispGraphic(fd, YES, startX, startY, IMG_ADDR_RF_0+strength);
-	dispCharacter(fd, startX-5, startY+2, FONT_ASCII_4X6, (uint8_t*)(is4G?"T":"W"), strlen((is4G?"T":"W")));
-
-	return result;
-}
-
-int8_t bgConfig(int32_t fd, uint16_t startX, uint16_t startY, uint16_t idxPic)
-{
-	int8_t result = FAIL;
-	uint8_t tx[9];
-	uint16_t chksum;
-
-	tx[0] = 0xb5;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (idxPic>>0)&0xff;
-	tx[6] = (idxPic>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t bgOperation(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t isRestore)
-{
-	int8_t result = FAIL;
-	uint8_t tx[12];
-	uint16_t chksum;
-
-	tx[0] = 0xb6;
-	tx[1] = (startX>>0)&0xff;
-	tx[2] = (startX>>8)&0xff;
-	tx[3] = (startY>>0)&0xff;
-	tx[4] = (startY>>8)&0xff;
-	tx[5] = (endX>>0)&0xff;
-	tx[6] = (endX>>8)&0xff;
-	tx[7] = (endY>>0)&0xff;
-	tx[8] = (endY>>8)&0xff;
-	tx[9] = isRestore;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-int8_t picUploadStart(int32_t fd, uint16_t imgIdx, uint16_t width, uint16_t height)
-{
-	int8_t result = FAIL;
-	uint8_t tx[11];
-	uint16_t chksum;
-
-	tx[0] = 0xe1;
-	tx[1] = (imgIdx>>0)&0xff;
-	tx[2] = (imgIdx>>8)&0xff;
-	tx[3] = (width>>0)&0xff;
-	tx[4] = (width>>8)&0xff;
-	tx[5] = (height>>0)&0xff;
-	tx[6] = (height>>8)&0xff;
-	tx[7] = 0x01;
-	tx[8] = 0x01;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(100000);
-	return result;
-}
-
-int8_t picUploadData(int32_t fd, uint16_t imgIdx, uint32_t startAddress, uint8_t *data, uint16_t length)
-{
-	int8_t result = FAIL;
-	uint8_t tx[11+length];
-	uint16_t chksum;
-
-	tx[0] = 0xe2;
-	tx[1] = (imgIdx>>0)&0xff;
-	tx[2] = (imgIdx>>8)&0xff;
-	tx[3] = (startAddress>>0)&0xff;
-	tx[4] = (startAddress>>8)&0xff;
-	tx[5] = (startAddress>>16)&0xff;
-	tx[6] = (startAddress>>24)&0xff;
-	tx[7] = (length>>0)&0xff;
-	tx[8] = (length>>8)&0xff;
-	memcpy(&tx[9], &data[0], length);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(100000);
-	return result;
-}
-
-int8_t graphicSave(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[12];
-	uint16_t chksum;
-
-	tx[0] = 0xae;
-	tx[1] = 0x02;
-	tx[2] = (startX>>0)&0xff;
-	tx[3] = (startX>>8)&0xff;
-	tx[4] = (startY>>0)&0xff;
-	tx[5] = (startY>>8)&0xff;
-	tx[6] = (endX>>0)&0xff;
-	tx[7] = (endX>>8)&0xff;
-	tx[8] = (endY>>0)&0xff;
-	tx[9] = (endY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(50000);
-	return result;
-}
-
-int8_t graphicLoad(int32_t fd, uint16_t startX, uint16_t startY)
-{
-	int8_t result = FAIL;
-	uint8_t tx[8];
-	uint16_t chksum;
-
-	tx[0] = 0xae;
-	tx[1] = 0x04;
-	tx[2] = (startX>>0)&0xff;
-	tx[3] = (startX>>8)&0xff;
-	tx[4] = (startY>>0)&0xff;
-	tx[5] = (startY>>8)&0xff;
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	//usleep(50000);
-	return result;
-}
-
-int8_t qrCodeOperation(int32_t fd, uint16_t startX, uint16_t startY, uint8_t *data, uint16_t msgLen)
-{
-	int8_t result = FAIL;
-	uint8_t tx[15+msgLen];
-	uint16_t chksum;
-
-	tx[0] = 0xdc;
-	tx[1] = 0x01;
-	tx[2] = (startX>>0)&0xff;
-	tx[3] = (startX>>8)&0xff;
-	tx[4] = (startY>>0)&0xff;
-	tx[5] = (startY>>8)&0xff;
-	tx[6] = 0x03;
-	tx[7] = 0x09;
-	tx[8] = 0xff;
-	tx[9] = 0x00;
-	tx[10] = 0x00;
-	tx[11] = (msgLen>>0)&0xff;
-	tx[12] = (msgLen>>8)&0xff;
-	memcpy(&tx[13], &data[0], msgLen);
-
-	chksum = crc16(&tx[0], ARRAY_SIZE(tx)-2);
-	tx[ARRAY_SIZE(tx)-2] = (chksum>>0)&0xff;
-	tx[ARRAY_SIZE(tx)-1] = (chksum>>8)&0xff;
-
-	result = tranceive(fd, tx, ARRAY_SIZE(tx));
-
-	return result;
-}
-
-
-
-

+ 0 - 153
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm.h

@@ -1,153 +0,0 @@
-/*
- * lcmComm.h
- *
- *  Created on: 2019¦~5¤ë8¤é
- *      Author: foluswen
- */
-
-#ifndef LCMCOMM_H_
-#define LCMCOMM_H_
-
-#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
-#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
-#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
-
-#define ALIGN_H_LEFT                                  (1<<0)
-#define ALIGN_H_CENTER                                (1<<1)
-#define ALIGN_H_RIGHT                                 (1<<2)
-#define ALIGN_V_TOP                                   (1<<3)
-#define ALIGN_V_CENTER                                (1<<4)
-#define ALIGN_V_BOTTOM                                (1<<5)
-#define ALIGN_BOTTOM_RIGHT                            (ALIGN_V_BOTTOM|ALIGN_H_RIGHT)
-#define ALIGN_BOTTOM_CENTER                           (ALIGN_V_BOTTOM|ALIGN_H_CENTER)
-#define ALIGN_BOTTOM_LEFT                             (ALIGN_V_BOTTOM|ALIGN_H_LEFT)
-#define ALIGN_CENTER_RIGHT                            (ALIGN_V_CENTER|ALIGN_H_RIGHT)
-#define ALIGN_CENTER                                  (ALIGN_V_CENTER|ALIGN_H_CENTER)
-#define ALIGN_CENTER_LEFT                             (ALIGN_V_CENTER|ALIGN_H_LEFT)
-#define ALIGN_TOP_RIGHT                               (ALIGN_V_TOP|ALIGN_H_RIGHT)
-#define ALIGN_TOP_CENTER                              (ALIGN_V_TOP|ALIGN_H_CENTER)
-#define ALIGN_TOP_LEFT                                (ALIGN_V_TOP|ALIGN_H_LEFT)
-
-#define FONT_JIS_16X16									0
-#define FONT_JIS_24X24									1
-#define FONT_CHT_16X16									2
-#define FONT_CHT_24X24									3
-#define FONT_CHS_16X16									4
-#define FONT_CHS_24X24									5
-#define FONT_UNICODE_16X16								6
-#define FONT_UNICODE_24X24								7
-#define FONT_ASCII_4X6									8
-#define FONT_ASCII_5X8									9
-#define FONT_ASCII_5X12									10
-#define FONT_ASCII_6X8									11
-#define FONT_ASCII_6X10									12
-#define FONT_ASCII_7X12									13
-#define FONT_ASCII_8X8									14
-#define FONT_ASCII_8X12									15
-#define FONT_ASCII_8X12C								16
-#define FONT_ASCII_8X14									17
-#define FONT_ASCII_8X15									18
-#define FONT_ASCII_10X16								19
-#define FONT_ASCII_12X16								20
-#define FONT_ASCII_12X20								21
-#define FONT_AIRAL_12									26
-#define FONT_AIRAL_14									27
-#define FONT_AIRAL_16									28
-#define FONT_AIRAL_20									29
-#define FONT_AIRAL_24									30
-
-enum IMAGE_ADDRESS
-{
-	IMG_ADDR_INIT=1,
-	IMG_ADDR_TAP_RFID,
-	IMG_ADDR_HANDSHAKE_1,
-	IMG_ADDR_HANDSHAKE_2,
-	IMG_ADDR_MAINTIAN,
-	IMG_ADDR_VERIFY,
-	IMG_ADDR_VERIFYOK,
-	IMG_ADDR_VERIFYFAIL,
-	IMG_ADDR_ICON_ALERT,
-	IMG_ADDR_ICON_ENERGY,
-	IMG_ADDR_ICON_COST,
-	IMG_ADDR_ICON_TIME,
-	IMG_ADDR_ICON_PRICE,
-	IMG_ADDR_ICON_B0,
-	IMG_ADDR_ICON_B20,
-	IMG_ADDR_ICON_B40,
-	IMG_ADDR_ICON_B60,
-	IMG_ADDR_ICON_B80,
-	IMG_ADDR_ICON_B100,
-	IMG_ADDR_ICON_COMPLETE,
-	IMG_ADDR_ICON_LAN_OFF,
-	IMG_ADDR_ICON_LAN_ON,
-	IMG_ADDR_RF_0,
-	IMG_ADDR_RF_1,
-	IMG_ADDR_RF_2,
-	IMG_ADDR_RF_3,
-	IMG_ADDR_RF_4,
-	IMG_ADDR_RF_5,
-	IMG_ADDR_QRCODE,
-};
-
-enum AREA_ID
-{
-	AREAD_ID_0=0,
-	AREAD_ID_1,
-	AREAD_ID_2,
-	AREAD_ID_3,
-	AREAD_ID_4,
-	AREAD_ID_5,
-	AREAD_ID_6,
-	AREAD_ID_7,
-	AREAD_ID_8,
-	AREAD_ID_9,
-	AREAD_ID_10,
-	AREAD_ID_11,
-	AREAD_ID_12,
-	AREAD_ID_13,
-	AREAD_ID_14,
-	AREAD_ID_15,
-	AREAD_ID_16,
-	AREAD_ID_17,
-	AREAD_ID_18,
-	AREAD_ID_HEADER_PRICE
-};
-
-extern int StoreLogMsg(const char *fmt, ...);
-extern int8_t clearScreen(int32_t fd, uint8_t isPartial, uint16_t startX, uint16_t startY, uint16_t width, uint16_t height);
-extern int8_t setContrast(int32_t fd, uint8_t startBrightness, uint8_t stopBrightness, uint8_t interval);
-extern int8_t setPower(int32_t fd, uint8_t isOn);
-extern int8_t dispGraphic(int32_t fd, uint8_t isCover, uint16_t startX, uint16_t startY, uint8_t graphicID);
-extern int8_t dispGraphicConfig(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endXX, uint16_t endY);
-extern int8_t dispGraphicArea(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t graphicID);
-extern int8_t dispGraphicPartial(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t bmpX, uint16_t bmpY, uint16_t bmpW, uint16_t bmpH, uint8_t graphicID);
-extern int8_t dispCharacter(int32_t fd, uint16_t startX, uint16_t startY, uint16_t font, uint8_t *data, uint8_t msgLen);
-extern int8_t dispCharacterConfig(int32_t fd, uint8_t areaId, uint8_t isCover, uint16_t startX, uint16_t startY, uint16_t endXX, uint16_t endY);
-extern int8_t dispCharacterArea(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint16_t font, uint8_t *data, uint8_t msgLen);
-extern int8_t dispCharacterScroll(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint16_t font, uint8_t isToRight, uint8_t speed, uint8_t *data, uint8_t msgLen);
-extern int8_t dispCharacterBlink(int32_t fd, uint8_t areaId, uint16_t startX, uint16_t startY, uint16_t font, uint8_t type, uint16_t time, uint8_t *data, uint8_t msgLen);
-extern int8_t checkBusy(int32_t fd);
-extern int8_t drawAll(int32_t fd);
-extern int8_t drawPoint(int32_t fd, uint16_t startX, uint16_t startY);
-extern int8_t drawRect(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t isFill);
-extern int8_t drawRectCorner(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t radius, uint8_t isFill);
-extern int8_t drawRectMesh(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY);
-extern int8_t drawLine(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY);
-extern int8_t drawRfSignal(int32_t fd, uint8_t strength, uint8_t is4G);
-extern int8_t bgConfig(int32_t fd, uint16_t startX, uint16_t startY, uint16_t idxPic);
-extern int8_t bgOperation(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY, uint8_t isRestore);
-extern int8_t picUploadStart(int32_t fd, uint16_t imgIdx, uint16_t width, uint16_t height);
-extern int8_t picUploadData(int32_t fd, uint16_t imgIdx, uint32_t startAddress, uint8_t *data, uint16_t length);
-extern int8_t graphicSave(int32_t fd, uint16_t startX, uint16_t startY, uint16_t endX, uint16_t endY);
-extern int8_t graphicLoad(int32_t fd, uint16_t startX, uint16_t startY);
-extern int8_t qrCodeOperation(int32_t fd, uint16_t startX, uint16_t startY, uint8_t *data, uint16_t msgLen);
-
-typedef struct SYS_FLAG
-{
-	uint8_t isEnable4G:1;
-	uint8_t isEnableWiFi:1;
-}SYS_FLAG;
-
-extern SYS_FLAG sysFlag;
-
-#endif /* LCMCOMM_H_ */

+ 202 - 0
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.c

@@ -0,0 +1,202 @@
+/*
+ * lcmComm_dgus.c
+ *
+ * Created on : 2020-10-20
+ * Update on : XXXX-XX-XX
+ * Author : Folus Wen, Eason Yang
+ * Version : D0.01
+ *
+ */
+
+#include 	"lcmComm_dgus.h"
+
+//#define isDebugPrint
+
+
+//================================
+// Basic routine
+//================================
+void displayMessageDgus(uint8_t *data, uint16_t len, uint8_t isRX)
+{
+	uint8_t output[8192];
+
+	memset(output, 0x00, ARRAY_SIZE(output));
+	sprintf((char*)output, "%s", (isRX?"RX: ":"TX: "));
+	for(uint16_t idx = 0;idx<len;idx++)
+	{
+		sprintf((char*)output, "%s%02x ", output, data[idx]);
+	}
+
+	#ifndef isDebugPrint
+	//DEBUG_INFO("%s\n", output);
+	#endif
+}
+
+//========================================
+// Call function (Transmit message into LCD)
+//========================================
+int transceiverDgus(int32_t fd, uint8_t *tx, uint16_t tx_len, uint8_t *rx, uint16_t rx_len)
+{
+	int result = FAIL;
+	int len;
+
+	tcflush(fd,TCIOFLUSH);
+
+	#ifndef isDebugPrint
+	//displayMessageDgus(tx, tx_len, NO);
+	#endif
+
+	if(write(fd, tx, tx_len) >= ARRAY_SIZE(tx))
+	{
+		if(tx[3] == CMD_REG_WRITE_DATA)
+		{
+			result = PASS;
+		}
+		else if(tx[3] == CMD_REG_READ_DATA)
+		{
+			len = read(fd, rx, rx_len);
+			if(len > 0)
+			{
+				if((rx[0] == CMD_HEADER_1) && (rx[1] == CMD_HEADER_2))
+				{
+					if(rx[3] == CMD_REG_READ_DATA)
+					{
+						#ifndef isDebugPrint
+						//displayMessageDgus(rx, len, YES);
+						#endif
+
+						result = PASS;
+					}
+					else
+					{}
+				}
+				else
+				{}
+			}
+			else
+			{}
+		}
+		else
+		{}
+	}
+	else
+	{}
+
+	return result;
+}
+
+//========================================
+// Call function (Write register value function)
+//========================================
+int8_t lcdRegisterWrite(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen)
+{
+	int8_t result = FAIL;
+	uint8_t tx[(regType == REG_TYPE_CONTROL? 8 : 6) + dataLen];
+	uint8_t rx[128];
+
+	memset(tx, 0x00, sizeof(tx));
+	memset(rx, 0x00, sizeof(rx));
+
+	tx[0] = CMD_HEADER_1;
+	tx[1] = CMD_HEADER_2;
+	tx[2] = (regType == REG_TYPE_CONTROL? 7 : (3 + dataLen));
+	tx[3] = CMD_REG_WRITE_DATA;
+	tx[4] = (address >> 8) & 0xff;
+	tx[5] = (address >> 0) & 0xff;
+
+	if(regType == REG_TYPE_CONTROL)
+	{
+		if(address == REG_ADDRESS_SET_PAGE_ID)
+		{
+			tx[6] = 0x5A;
+			tx[7] = 0x01;
+
+			memcpy(&tx[8], data, dataLen);
+		}
+	}
+	else
+	{
+		memcpy(&tx[6], data, dataLen);
+	}
+
+	if(fd > 0)
+	{
+		if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)))
+		{
+			result = PASS;
+		}
+		else
+		{}
+	}
+	else
+	{}
+
+	return result;
+}
+
+//========================================
+// Call function (Read register value function)
+//========================================
+int8_t lcdRegisterRead(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen)
+{
+	int8_t result = FAIL;
+	uint8_t tx[(regType == REG_TYPE_CONTROL? 7 : 8)];
+	uint8_t rx[(regType == REG_TYPE_CONTROL? (7 + dataLen) : (8 + dataLen*2))];
+
+	memset(tx, 0x00, sizeof(tx));
+	memset(rx, 0x00, sizeof(rx));
+
+	tx[0] = CMD_HEADER_1;
+	tx[1] = CMD_HEADER_2;
+	tx[2] = (regType == REG_TYPE_CONTROL? 4 : 5);
+	tx[3] = CMD_REG_READ_DATA;
+	tx[4] = (address >> 8) & 0xff;
+	tx[5] = (address >> 0) & 0xff;
+
+	if(regType == REG_TYPE_CONTROL)
+	{
+		tx[6] = dataLen;
+	}
+	else if (regType == REG_TYPE_SPECIAL_CONTROL)
+	{
+		tx[6] = (dataLen >> 8) & 0xff;
+		tx[7] = (dataLen >> 0) & 0xff;
+	}
+	else
+	{}
+
+	if(fd > 0)
+	{
+		if(transceiverDgus(fd, tx, ARRAY_SIZE(tx), rx, ARRAY_SIZE(rx)))
+		{
+			if(regType == REG_TYPE_CONTROL)
+			{
+				if((rx[3] == CMD_REG_READ_DATA) && (((rx[4] << 8) | rx[5]) == address))
+				{
+					memcpy(data, rx + 7, dataLen);
+					result = PASS;
+				}
+				else
+				{}
+			}
+			else if(regType == REG_TYPE_SPECIAL_CONTROL)
+			{
+				if((rx[3] == CMD_REG_READ_DATA) && (((rx[4] << 8) | rx[5]) == address))
+				{
+					memcpy(data, rx + 8, dataLen*2);
+					result = PASS;
+				}
+				else
+				{}
+			}
+			else
+			{}
+		}
+		else
+		{}
+	}
+	else
+	{}
+
+	return result;
+}

+ 268 - 0
EVSE/Projects/AW-CCS/Apps/LCM/lcmComm_dgus.h

@@ -0,0 +1,268 @@
+/*
+ * lcmComm_dwin.h
+ *
+ * Created on : 2020-10-20
+ * Update on : XXXX-XX-XX
+ * Author : Folus Wen, Eason Yang
+ * Version : D0.01
+ *
+ */
+
+#ifndef LCMCOMM_DGUS_H_
+#define LCMCOMM_DGUS_H_
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include 	<errno.h>
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__, __FUNCTION__, ##args)
+
+#define ARRAY_SIZE(A)			(sizeof(A) / sizeof(A[0]))
+#define PASS					1
+#define FAIL					-1
+#define YES						1
+#define NO						0
+#define ON						1
+#define OFF						0
+#define PAGE_DISPLAY_PERIOD		3
+
+//=======================================
+// Register Control type
+//=======================================
+#define REG_TYPE_CONTROL					0x00
+#define REG_TYPE_RAM						0x01
+#define REG_TYPE_SPECIAL_CONTROL			0x02
+
+//=======================================
+// Register content (Variable storage)
+//=======================================
+#define REG_ADDRESS_READ_VERSION			0x0F
+#define REG_ADDRESS_READ_RTC				0x10
+#define REG_ADDRESS_READ_PAGE_ID			0x14
+#define REG_ADDRESS_READ_BRIGHTNESS       	0x31
+#define REG_ADDRESS_SET_PAGE_ID				0x84
+#define REG_ADDRESS_SET_RTC					0x9C
+
+//=======================================
+// LCD command constant
+//=======================================
+#define CMD_HEADER_1						0x5A
+#define CMD_HEADER_2						0xA5
+#define CMD_REG_WRITE						0x80
+#define CMD_REG_READ						0x81
+#define CMD_REG_WRITE_DATA					0x82
+#define CMD_REG_READ_DATA					0x83
+
+//=======================================
+// LCD system screen
+//=======================================
+#define SYSTEM_SCREEN_BOOTING				0x00
+#define SYSTEM_SCREEN_IDLE    	  			0x01
+#define SYSTEM_SCREEN_PREPARING				0x02
+#define SYSTEM_SCREEN_PREPARE_FOR_EVSE		0x03
+#define SYSTEM_SCREEN_CHARGING				0x04
+#define SYSTEM_SCREEN_COMPLETE				0x05
+#define SYSTEM_SCREEN_MAINTAIN				0x06
+#define SYSTEM_SCREEN_AUTH_PASS				0x07
+#define SYSTEM_SCREEN_AUTH_FAIL				0x08
+#define SYSTEM_SCREEN_AUTH_UNKNOW			0x09
+#define SYSTEM_SCREEN_TERMINATING			0X0A
+
+//=======================================
+// Parameter to change icon status
+//=======================================
+#define DISAPPEAR							0x00
+#define APPEAR 								0x01
+#define BACKEND_OFFLINE						0x01
+#define BACKEND_ONLINE 						0x02
+#define ETHERENT_OFFLINE					0x03
+#define EHTERNET_ONLINE						0x04
+#define WIFI_OFFLINE						0x05
+#define WIFI_ONLINE							0x06
+#define TELECOM_OFFLINE						0x07
+#define TELECOM_ONLINE						0x08
+#define PRICE_DISAPPEAR						0x00
+#define PRICE_APPEAR						0x01
+#define RFID_DISABLE						0x01
+#define RFID_ENABLE							0x02
+#define VISA_DISABLE						0x03
+#define VISA_ENABLE							0x04
+#define PLUGIN_ARROW_1						0x01
+#define PLUGIN_ARROW_2						0x02
+#define BATTERY_MAP							0x01
+#define BATTERY_CAPACITY_EMPTY				0x02
+#define BATTERY_CAPACITY_20					0x03
+#define BATTERY_CAPACITY_40					0x04
+#define BATTERY_CAPACITY_60					0x05
+#define BATTERY_CAPACITY_80					0x06
+#define BATTERY_CAPACITY_100				0x07
+#define CONNECTION_QUESTION_MARK_1			0x01
+#define CONNECTION_QUESTION_MARK_2			0x02
+#define CONNECTION_ELECTRIC_MARK_1			0x03
+#define CONNECTION_ELECTRIC_MARK_2			0x04
+#define TIMER_DARK							0x01
+#define TIMER_LIGHT							0x02
+#define POWER_DARK							0x01
+#define POWER_LIGHT							0x02
+#define ENERGY_DARK							0x01
+#define ENERGY_LIGHT						0x02
+#define ELECTRICITY_DIRECTION_RIGHT 		0x01
+#define ELECTRICITY_DIRECTION_LEFT 			0x02
+#define WALLET_COMPELTE_DISAPPEAR			0x00
+#define WALLET_COMPLETE_APPEAR				0x01
+#define BATTERY_SOC_EMPTY					0x01
+#define BATTERY_SOC_20						0x02
+#define BATTERY_SOC_40						0x03
+#define BATTERY_SOC_60						0x04
+#define BATTERY_SOC_80						0x05
+#define BATTERY_SOC_100						0x06
+#define CONNECTION_COMPLETE_MARK			0x01
+#define TIMER_COMPLETE_DISAPPEAR			0x00
+#define TIMER_COMPLETE_APPEAR				0x01
+#define COST_COMPLETE_DISAPPER				0x00
+#define COST_COMPLETE_APPEAR				0x01
+#define ENERGY_COMPLETE_DISAPPER			0x00
+#define ENERGY_COMPLETE_APPEAR				0x01
+#define VALID_WALLET_DISAPPER				0x00
+#define VALID_WALLET_APPEAR					0x01
+#define QRCODE_DISABLE						0x01
+#define QRCODE_ENABLE 						0x02
+#define QRCODE_BANDED						0x03
+
+//=======================================
+// Icon variable address start from 1000
+//=======================================
+#define ICON_ALARM_1 						0x1000
+#define ICON_ALARM_2 						0x1001
+#define ICON_ALARM_3 						0x1002
+#define ICON_ALARM_4 						0x1003
+#define ICON_4G_CONNECTION 					0x1004
+#define ICON_WIFI_CONNECTION 				0x1005
+#define ICON_ETHERENT_CONNECTION 			0x1006
+#define ICON_BACKEND_CONNECTION				0x1007
+#define ICON_PRICE							0x1008
+#define ICON_RFID							0x1009
+#define ICON_QRCODE							0x100A
+#define ICON_PLUGIN_ARROW					0x100B
+#define ICON_BATTERY_PRECHARGING			0x100C
+#define ICON_CONNECTION_PRECHARGING 		0x100D
+#define ICON_TIMER_PRECHARGING				0x100E
+#define ICON_POWER_PRECHARGING				0x100F
+#define ICON_ENERGY_PRECHARGING				0x1010
+#define ICON_BATTERY_CHARGING				0x1011
+#define ICON_CONNECTION_CHARGING			0x1012
+#define ICON_ELECTRICITY_DIRECTION			0x1013
+#define ICON_TIMER_CHARGING					0x1014
+#define ICON_POWER_CHARGING					0x1015
+#define ICON_ENERGY_CHARGING				0x1016
+#define ICON_WALLER_COMPLETE				0x1017
+#define ICON_BATTERY_COMPLETE				0x1018
+#define ICON_CONNECTION_COMPLETE			0x1019
+#define ICON_TIMER_COMPLETE					0x101A
+#define ICON_COST_COMPLETE					0X101B
+#define ICON_ENERGY_COMPLETE				0X101C
+#define ICON_BALANCE_WALLET					0x101D
+#define ICON_LOGO							0x1500
+#define ICON_LOGO_CHARGING					0x1501
+
+//=======================================
+// Text content address start from 2000
+//=======================================
+#define TEXT_ALARM_CODE_1					0x2000 // size 6
+#define TEXT_ALARM_CODE_2					0x2006 // size 6
+#define TEXT_ALARM_CODE_3					0x200C // size 6
+#define TEXT_ALARM_CODE_4					0x2012 // size 6
+#define TEXT_PRICE							0x2018 // size 16
+#define TEXT_CURRENCY_UNIT					0x2028 // size 16
+#define TEXT_TIMER_PRECHARGING 				0x2038 // size 16
+#define TEXT_POWER_PRECHARGING 				0x2048 // size 16
+#define TEXT_ENERGY_PRECHARGING 			0x2058 // size 16
+#define TEXT_TIMER_CHARGING					0x2068 // size 16
+#define TEXT_POWER_CHARGING					0x2078 // size 16
+#define TEXT_ENERGY_CHARGING				0x2088 // size 16
+#define TEXT_COST_COMPLETE					0x2098 // size 16
+#define TEXT_ACCOUNT_COMPLETE				0x20A8 // size 16
+#define TEXT_BALANCE						0x20B8 // size 16
+#define TEXT_PERCENTAGE						0x20C8 // size 6
+#define TEXT_RTC							0X2500 // size 32
+
+//=======================================
+// QR Code content address start from 5000
+//=======================================
+#define TEXT_QRCODE_CONTENT					0x3000
+
+//=======================================
+// 4G + WIFI connection flags (Header)
+//=======================================
+#define DISABLE_4G							0x00
+#define ENABLE_4G 							0x01
+#define DISABLE_WIFI						0x00
+#define WIFI_STATION						0x01
+#define WIFI_ACCESS_POINT					0x02
+
+//=======================================
+// Battery level status (Charging)
+//=======================================
+#define BATTERY_LEVEL_0						0x00
+#define BATTERY_LEVEL_1						0x01
+#define BATTERY_LEVEL_2						0x02
+#define BATTERY_LEVEL_3						0x03
+#define BATTERY_LEVEL_4						0x04
+#define BATTERY_LEVEL_5						0x05
+
+//=======================================
+// CConnection level status (Charging)
+//=======================================
+#define CONNECTION_LEVEL_0					0x00
+#define CONNECTION_LEVEL_1					0x01
+
+//=======================================
+// Gun plug-in level status (Preparing)
+//=======================================
+#define GUN_PLUGING_LEVEL_0					0x00
+#define GUN_PLUGING_LEVEL_1					0x01
+
+//=======================================
+// RFID authorization constant
+//=======================================
+#define VALIDATED_RFID						0x00
+#define UNVALIDATED_RFID					0x01
+#define UNKNOW_RFID							0x02
+
+//=======================================
+// Normal mode or CCS mode constant
+//=======================================
+#define BASIC_MODE							0x00
+#define CCS_MODE							0x01
+
+extern int StoreLogMsg(const char *fmt, ...);
+extern int8_t lcdRegisterWrite(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen);
+extern int8_t lcdRegisterRead(int32_t fd, uint8_t regType, uint16_t address, uint8_t *data, uint16_t dataLen);
+
+#endif /* LCMCOMM_DGUS_H_ */

+ 0 - 852
EVSE/Projects/AW-CCS/Apps/LCM/qrcode.c

@@ -1,852 +0,0 @@
-/**
- * The MIT License (MIT)
- *
- * This library is written and maintained by Richard Moore.
- * Major parts were derived from Project Nayuki's library.
- *
- * Copyright (c) 2017 Richard Moore     (https://github.com/ricmoo/QRCode)
- * Copyright (c) 2017 Project Nayuki    (https://www.nayuki.io/page/qr-code-generator-library)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- *  Special thanks to Nayuki (https://www.nayuki.io/) from which this library was
- *  heavily inspired and compared against.
- *
- *  See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
- */
-
-#include "qrcode.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#if LOCK_VERSION == 0
-
-static const uint16_t NUM_ERROR_CORRECTION_CODEWORDS[4][40] = {
-    // 1,  2,  3,  4,  5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40    Error correction level
-    { 10, 16, 26, 36, 48,  64,  72,  88, 110, 130, 150, 176, 198, 216, 240, 280, 308, 338, 364, 416, 442, 476, 504, 560,  588,  644,  700,  728,  784,  812,  868,  924,  980, 1036, 1064, 1120, 1204, 1260, 1316, 1372},  // Medium
-    {  7, 10, 15, 20, 26,  36,  40,  48,  60,  72,  80,  96, 104, 120, 132, 144, 168, 180, 196, 224, 224, 252, 270, 300,  312,  336,  360,  390,  420,  450,  480,  510,  540,  570,  570,  600,  630,  660,  720,  750},  // Low
-    { 17, 28, 44, 64, 88, 112, 130, 156, 192, 224, 264, 308, 352, 384, 432, 480, 532, 588, 650, 700, 750, 816, 900, 960, 1050, 1110, 1200, 1260, 1350, 1440, 1530, 1620, 1710, 1800, 1890, 1980, 2100, 2220, 2310, 2430},  // High
-    { 13, 22, 36, 52, 72,  96, 108, 132, 160, 192, 224, 260, 288, 320, 360, 408, 448, 504, 546, 600, 644, 690, 750, 810,  870,  952, 1020, 1050, 1140, 1200, 1290, 1350, 1440, 1530, 1590, 1680, 1770, 1860, 1950, 2040},  // Quartile
-};
-
-static const uint8_t NUM_ERROR_CORRECTION_BLOCKS[4][40] = {
-    // Version: (note that index 0 is for padding, and is set to an illegal value)
-    // 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level
-    {  1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49},  // Medium
-    {  1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25},  // Low
-    {  1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81},  // High
-    {  1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68},  // Quartile
-};
-
-static const uint16_t NUM_RAW_DATA_MODULES[40] = {
-    //  1,   2,   3,   4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
-      208, 359, 567, 807, 1079, 1383, 1568, 1936, 2336, 2768, 3232, 3728, 4256, 4651, 5243, 5867, 6523,
-    //   18,   19,   20,   21,    22,    23,    24,    25,   26,    27,     28,    29,    30,    31,
-       7211, 7931, 8683, 9252, 10068, 10916, 11796, 12708, 13652, 14628, 15371, 16411, 17483, 18587,
-    //    32,    33,    34,    35,    36,    37,    38,    39,    40
-       19723, 20891, 22091, 23008, 24272, 25568, 26896, 28256, 29648
-};
-
-// @TODO: Put other LOCK_VERSIONS here
-#elif LOCK_VERSION == 3
-
-static const int16_t NUM_ERROR_CORRECTION_CODEWORDS[4] = {
-    26, 15, 44, 36
-};
-
-static const int8_t NUM_ERROR_CORRECTION_BLOCKS[4] = {
-    1, 1, 2, 2
-};
-
-static const uint16_t NUM_RAW_DATA_MODULES = 567;
-
-#else
-
-#error Unsupported LOCK_VERSION (add it...)
-
-#endif
-
-
-static int max(int a, int b) {
-    if (a > b) { return a; }
-    return b;
-}
-
-/*
-static int abs(int value) {
-    if (value < 0) { return -value; }
-    return value;
-}
-*/
-
-
-static int8_t getAlphanumeric(char c) {
-
-    if (c >= '0' && c <= '9') { return (c - '0'); }
-    if (c >= 'A' && c <= 'Z') { return (c - 'A' + 10); }
-
-    switch (c) {
-        case ' ': return 36;
-        case '$': return 37;
-        case '%': return 38;
-        case '*': return 39;
-        case '+': return 40;
-        case '-': return 41;
-        case '.': return 42;
-        case '/': return 43;
-        case ':': return 44;
-    }
-
-    return -1;
-}
-
-static uint8_t isAlphanumeric(const char *text, uint16_t length) {
-    while (length != 0) {
-        if (getAlphanumeric(text[--length]) == -1) { return FALSE; }
-    }
-    return TRUE;
-}
-
-static uint8_t isNumeric(const char *text, uint16_t length) {
-    while (length != 0) {
-        char c = text[--length];
-        if (c < '0' || c > '9') { return FALSE; }
-    }
-    return TRUE;
-}
-
-
-// We store the following tightly packed (less 8) in modeInfo
-//               <=9  <=26  <= 40
-// NUMERIC      ( 10,   12,    14);
-// ALPHANUMERIC (  9,   11,    13);
-// BYTE         (  8,   16,    16);
-static char getModeBits(uint8_t version, uint8_t mode) {
-    // Note: We use 15 instead of 16; since 15 doesn't exist and we cannot store 16 (8 + 8) in 3 bits
-    // hex(int("".join(reversed([('00' + bin(x - 8)[2:])[-3:] for x in [10, 9, 8, 12, 11, 15, 14, 13, 15]])), 2))
-    unsigned int modeInfo = 0x7bbb80a;
-
-#if LOCK_VERSION == 0 || LOCK_VERSION > 9
-    if (version > 9) { modeInfo >>= 9; }
-#endif
-
-#if LOCK_VERSION == 0 || LOCK_VERSION > 26
-    if (version > 26) { modeInfo >>= 9; }
-#endif
-
-    char result = 8 + ((modeInfo >> (3 * mode)) & 0x07);
-    if (result == 15) { result = 16; }
-
-    return result;
-}
-
-
-typedef struct BitBucket {
-    uint32_t bitOffsetOrWidth;
-    uint16_t capacityBytes;
-    uint8_t *data;
-} BitBucket;
-
-/*
-void bb_dump(BitBucket *bitBuffer) {
-    printf("Buffer: ");
-    for (uint32_t i = 0; i < bitBuffer->capacityBytes; i++) {
-        printf("%02x", bitBuffer->data[i]);
-        if ((i % 4) == 3) { printf(" "); }
-    }
-    printf("\n");
-}
-*/
-
-static uint16_t bb_getGridSizeBytes(uint8_t size) {
-    return (((size * size) + 7) / 8);
-}
-
-static uint16_t bb_getBufferSizeBytes(uint32_t bits) {
-    return ((bits + 7) / 8);
-}
-
-static void bb_initBuffer(BitBucket *bitBuffer, uint8_t *data, int32_t capacityBytes) {
-    bitBuffer->bitOffsetOrWidth = 0;
-    bitBuffer->capacityBytes = capacityBytes;
-    bitBuffer->data = data;
-
-    memset(data, 0, bitBuffer->capacityBytes);
-}
-
-static void bb_initGrid(BitBucket *bitGrid, uint8_t *data, uint8_t size) {
-    bitGrid->bitOffsetOrWidth = size;
-    bitGrid->capacityBytes = bb_getGridSizeBytes(size);
-    bitGrid->data = data;
-
-    memset(data, 0, bitGrid->capacityBytes);
-}
-
-static void bb_appendBits(BitBucket *bitBuffer, uint32_t val, uint8_t length) {
-    uint32_t offset = bitBuffer->bitOffsetOrWidth;
-    for (int8_t i = length - 1; i >= 0; i--, offset++) {
-        bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7));
-    }
-    bitBuffer->bitOffsetOrWidth = offset;
-}
-/*
-void bb_setBits(BitBucket *bitBuffer, uint32_t val, int offset, uint8_t length) {
-    for (int8_t i = length - 1; i >= 0; i--, offset++) {
-        bitBuffer->data[offset >> 3] |= ((val >> i) & 1) << (7 - (offset & 7));
-    }
-}
-*/
-static void bb_setBit(BitBucket *bitGrid, uint8_t x, uint8_t y, uint8_t on) {
-    uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
-    uint8_t mask = 1 << (7 - (offset & 0x07));
-    if (on) {
-        bitGrid->data[offset >> 3] |= mask;
-    } else {
-        bitGrid->data[offset >> 3] &= ~mask;
-    }
-}
-
-static void bb_invertBit(BitBucket *bitGrid, uint8_t x, uint8_t y, uint8_t invert) {
-    uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
-    uint8_t mask = 1 << (7 - (offset & 0x07));
-    uint8_t on = ((bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0);
-    if (on ^ invert) {
-        bitGrid->data[offset >> 3] |= mask;
-    } else {
-        bitGrid->data[offset >> 3] &= ~mask;
-    }
-}
-
-static uint8_t bb_getBit(BitBucket *bitGrid, uint8_t x, uint8_t y) {
-    uint32_t offset = y * bitGrid->bitOffsetOrWidth + x;
-    return (bitGrid->data[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0;
-}
-
-
-// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical
-// properties, calling applyMask(m) twice with the same value is equivalent to no change at all.
-// This means it is possible to apply a mask, undo it, and try another mask. Note that a final
-// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.).
-static void applyMask(BitBucket *modules, BitBucket *isFunction, uint8_t mask) {
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    for (uint8_t y = 0; y < size; y++) {
-        for (uint8_t x = 0; x < size; x++) {
-            if (bb_getBit(isFunction, x, y)) { continue; }
-
-            uint8_t invert = 0;
-            switch (mask) {
-                case 0:  invert = (x + y) % 2 == 0;                    break;
-                case 1:  invert = y % 2 == 0;                          break;
-                case 2:  invert = x % 3 == 0;                          break;
-                case 3:  invert = (x + y) % 3 == 0;                    break;
-                case 4:  invert = (x / 3 + y / 2) % 2 == 0;            break;
-                case 5:  invert = x * y % 2 + x * y % 3 == 0;          break;
-                case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;    break;
-                case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;  break;
-            }
-            bb_invertBit(modules, x, y, invert);
-        }
-    }
-}
-
-static void setFunctionModule(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y, uint8_t on) {
-    bb_setBit(modules, x, y, on);
-    bb_setBit(isFunction, x, y, TRUE);
-}
-
-// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y).
-static void drawFinderPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    for (int8_t i = -4; i <= 4; i++) {
-        for (int8_t j = -4; j <= 4; j++) {
-            uint8_t dist = max(abs(i), abs(j));  // Chebyshev/infinity norm
-            int16_t xx = x + j, yy = y + i;
-            if (0 <= xx && xx < size && 0 <= yy && yy < size) {
-                setFunctionModule(modules, isFunction, xx, yy, dist != 2 && dist != 4);
-            }
-        }
-    }
-}
-
-// Draws a 5*5 alignment pattern, with the center module at (x, y).
-static void drawAlignmentPattern(BitBucket *modules, BitBucket *isFunction, uint8_t x, uint8_t y) {
-    for (int8_t i = -2; i <= 2; i++) {
-        for (int8_t j = -2; j <= 2; j++) {
-            setFunctionModule(modules, isFunction, x + j, y + i, max(abs(i), abs(j)) != 1);
-        }
-    }
-}
-
-// Draws two copies of the format bits (with its own error correction code)
-// based on the given mask and this object's error correction level field.
-static void drawFormatBits(BitBucket *modules, BitBucket *isFunction, uint8_t ecc, uint8_t mask) {
-
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    // Calculate error correction code and pack bits
-    uint32_t data = ecc << 3 | mask;  // errCorrLvl is uint2, mask is uint3
-    uint32_t rem = data;
-    for (int i = 0; i < 10; i++) {
-        rem = (rem << 1) ^ ((rem >> 9) * 0x537);
-    }
-
-    data = data << 10 | rem;
-    data ^= 0x5412;  // uint15
-
-    // Draw first copy
-    for (uint8_t i = 0; i <= 5; i++) {
-        setFunctionModule(modules, isFunction, 8, i, ((data >> i) & 1) != 0);
-    }
-
-    setFunctionModule(modules, isFunction, 8, 7, ((data >> 6) & 1) != 0);
-    setFunctionModule(modules, isFunction, 8, 8, ((data >> 7) & 1) != 0);
-    setFunctionModule(modules, isFunction, 7, 8, ((data >> 8) & 1) != 0);
-
-    for (int8_t i = 9; i < 15; i++) {
-        setFunctionModule(modules, isFunction, 14 - i, 8, ((data >> i) & 1) != 0);
-    }
-
-    // Draw second copy
-    for (int8_t i = 0; i <= 7; i++) {
-        setFunctionModule(modules, isFunction, size - 1 - i, 8, ((data >> i) & 1) != 0);
-    }
-
-    for (int8_t i = 8; i < 15; i++) {
-        setFunctionModule(modules, isFunction, 8, size - 15 + i, ((data >> i) & 1) != 0);
-    }
-
-    setFunctionModule(modules, isFunction, 8, size - 8, TRUE);
-}
-
-
-// Draws two copies of the version bits (with its own error correction code),
-// based on this object's version field (which only has an effect for 7 <= version <= 40).
-static void drawVersion(BitBucket *modules, BitBucket *isFunction, uint8_t version) {
-
-    int8_t size = modules->bitOffsetOrWidth;
-
-#if LOCK_VERSION != 0 && LOCK_VERSION < 7
-    return;
-
-#else
-    if (version < 7) { return; }
-
-    // Calculate error correction code and pack bits
-    uint32_t rem = version;  // version is uint6, in the range [7, 40]
-    for (uint8_t i = 0; i < 12; i++) {
-        rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
-    }
-
-    uint32_t data = version << 12 | rem;  // uint18
-
-    // Draw two copies
-    for (uint8_t i = 0; i < 18; i++) {
-        uint8_t bit = ((data >> i) & 1) != 0;
-        uint8_t a = size - 11 + i % 3, b = i / 3;
-        setFunctionModule(modules, isFunction, a, b, bit);
-        setFunctionModule(modules, isFunction, b, a, bit);
-    }
-
-#endif
-}
-
-static void drawFunctionPatterns(BitBucket *modules, BitBucket *isFunction, uint8_t version, uint8_t ecc) {
-
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    // Draw the horizontal and vertical timing patterns
-    for (uint8_t i = 0; i < size; i++) {
-        setFunctionModule(modules, isFunction, 6, i, i % 2 == 0);
-        setFunctionModule(modules, isFunction, i, 6, i % 2 == 0);
-    }
-
-    // Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
-    drawFinderPattern(modules, isFunction, 3, 3);
-    drawFinderPattern(modules, isFunction, size - 4, 3);
-    drawFinderPattern(modules, isFunction, 3, size - 4);
-
-#if LOCK_VERSION == 0 || LOCK_VERSION > 1
-
-    if (version > 1) {
-
-        // Draw the numerous alignment patterns
-
-        uint8_t alignCount = version / 7 + 2;
-        uint8_t step;
-        if (version != 32) {
-            step = (version * 4 + alignCount * 2 + 1) / (2 * alignCount - 2) * 2;  // ceil((size - 13) / (2*numAlign - 2)) * 2
-        } else { // C-C-C-Combo breaker!
-            step = 26;
-        }
-
-        uint8_t alignPositionIndex = alignCount - 1;
-        uint8_t alignPosition[alignCount];
-
-        alignPosition[0] = 6;
-
-        uint8_t size = version * 4 + 17;
-        for (uint8_t i = 0, pos = size - 7; i < alignCount - 1; i++, pos -= step) {
-            alignPosition[alignPositionIndex--] = pos;
-        }
-
-        for (uint8_t i = 0; i < alignCount; i++) {
-            for (uint8_t j = 0; j < alignCount; j++) {
-                if ((i == 0 && j == 0) || (i == 0 && j == alignCount - 1) || (i == alignCount - 1 && j == 0)) {
-                    continue;  // Skip the three finder corners
-                } else {
-                    drawAlignmentPattern(modules, isFunction, alignPosition[i], alignPosition[j]);
-                }
-            }
-        }
-    }
-
-#endif
-
-    // Draw configuration data
-    drawFormatBits(modules, isFunction, ecc, 0);  // Dummy mask value; overwritten later in the constructor
-    drawVersion(modules, isFunction, version);
-}
-
-
-// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
-// data area of this QR Code symbol. Function modules need to be marked off before this is called.
-static void drawCodewords(BitBucket *modules, BitBucket *isFunction, BitBucket *codewords) {
-
-    uint32_t bitLength = codewords->bitOffsetOrWidth;
-    uint8_t *data = codewords->data;
-
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    // Bit index into the data
-    uint32_t i = 0;
-
-    // Do the funny zigzag scan
-    for (int16_t right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair
-        if (right == 6) { right = 5; }
-
-        for (uint8_t vert = 0; vert < size; vert++) {  // Vertical counter
-            for (int j = 0; j < 2; j++) {
-                uint8_t x = right - j;  // Actual x coordinate
-                uint8_t upwards = ((right & 2) == 0) ^ (x < 6);
-                uint8_t y = upwards ? size - 1 - vert : vert;  // Actual y coordinate
-                if (!bb_getBit(isFunction, x, y) && i < bitLength) {
-                    bb_setBit(modules, x, y, ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0);
-                    i++;
-                }
-                // If there are any remainder bits (0 to 7), they are already
-                // set to 0/false/white when the grid of modules was initialized
-            }
-        }
-    }
-}
-
-
-#define PENALTY_N1      3
-#define PENALTY_N2      3
-#define PENALTY_N3     40
-#define PENALTY_N4     10
-
-// Calculates and returns the penalty score based on state of this QR Code's current modules.
-// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
-// @TODO: This can be optimized by working with the bytes instead of bits.
-static uint32_t getPenaltyScore(BitBucket *modules) {
-    uint32_t result = 0;
-
-    uint8_t size = modules->bitOffsetOrWidth;
-
-    // Adjacent modules in row having same color
-    for (uint8_t y = 0; y < size; y++) {
-
-        uint8_t colorX = bb_getBit(modules, 0, y);
-        for (uint8_t x = 1, runX = 1; x < size; x++) {
-        	uint8_t cx = bb_getBit(modules, x, y);
-            if (cx != colorX) {
-                colorX = cx;
-                runX = 1;
-
-            } else {
-                runX++;
-                if (runX == 5) {
-                    result += PENALTY_N1;
-                } else if (runX > 5) {
-                    result++;
-                }
-            }
-        }
-    }
-
-    // Adjacent modules in column having same color
-    for (uint8_t x = 0; x < size; x++) {
-    	uint8_t colorY = bb_getBit(modules, x, 0);
-        for (uint8_t y = 1, runY = 1; y < size; y++) {
-        	uint8_t cy = bb_getBit(modules, x, y);
-            if (cy != colorY) {
-                colorY = cy;
-                runY = 1;
-            } else {
-                runY++;
-                if (runY == 5) {
-                    result += PENALTY_N1;
-                } else if (runY > 5) {
-                    result++;
-                }
-            }
-        }
-    }
-
-    uint16_t black = 0;
-    for (uint8_t y = 0; y < size; y++) {
-        uint16_t bitsRow = 0, bitsCol = 0;
-        for (uint8_t x = 0; x < size; x++) {
-        	uint8_t color = bb_getBit(modules, x, y);
-
-            // 2*2 blocks of modules having same color
-            if (x > 0 && y > 0) {
-            	uint8_t colorUL = bb_getBit(modules, x - 1, y - 1);
-            	uint8_t colorUR = bb_getBit(modules, x, y - 1);
-            	uint8_t colorL = bb_getBit(modules, x - 1, y);
-                if (color == colorUL && color == colorUR && color == colorL) {
-                    result += PENALTY_N2;
-                }
-            }
-
-            // Finder-like pattern in rows and columns
-            bitsRow = ((bitsRow << 1) & 0x7FF) | color;
-            bitsCol = ((bitsCol << 1) & 0x7FF) | bb_getBit(modules, y, x);
-
-            // Needs 11 bits accumulated
-            if (x >= 10) {
-                if (bitsRow == 0x05D || bitsRow == 0x5D0) {
-                    result += PENALTY_N3;
-                }
-                if (bitsCol == 0x05D || bitsCol == 0x5D0) {
-                    result += PENALTY_N3;
-                }
-            }
-
-            // Balance of black and white modules
-            if (color) { black++; }
-        }
-    }
-
-    // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)%
-    uint16_t total = size * size;
-    for (uint16_t k = 0; black * 20 < (9 - k) * total || black * 20 > (11 + k) * total; k++) {
-        result += PENALTY_N4;
-    }
-
-    return result;
-}
-
-static uint8_t rs_multiply(uint8_t x, uint8_t y) {
-    // Russian peasant multiplication
-    // See: https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
-    uint16_t z = 0;
-    for (int8_t i = 7; i >= 0; i--) {
-        z = (z << 1) ^ ((z >> 7) * 0x11D);
-        z ^= ((y >> i) & 1) * x;
-    }
-    return z;
-}
-
-static void rs_init(uint8_t degree, uint8_t *coeff) {
-    memset(coeff, 0, degree);
-    coeff[degree - 1] = 1;
-
-    // Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
-    // drop the highest term, and store the rest of the coefficients in order of descending powers.
-    // Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
-    uint16_t root = 1;
-    for (uint8_t i = 0; i < degree; i++) {
-        // Multiply the current product by (x - r^i)
-        for (uint8_t j = 0; j < degree; j++) {
-            coeff[j] = rs_multiply(coeff[j], root);
-            if (j + 1 < degree) {
-                coeff[j] ^= coeff[j + 1];
-            }
-        }
-        root = (root << 1) ^ ((root >> 7) * 0x11D);  // Multiply by 0x02 mod GF(2^8/0x11D)
-    }
-}
-
-static void rs_getRemainder(uint8_t degree, uint8_t *coeff, uint8_t *data, uint8_t length, uint8_t *result, uint8_t stride) {
-    // Compute the remainder by performing polynomial division
-
-    //for (uint8_t i = 0; i < degree; i++) { result[] = 0; }
-    //memset(result, 0, degree);
-
-    for (uint8_t i = 0; i < length; i++) {
-        uint8_t factor = data[i] ^ result[0];
-        for (uint8_t j = 1; j < degree; j++) {
-            result[(j - 1) * stride] = result[j * stride];
-        }
-        result[(degree - 1) * stride] = 0;
-
-        for (uint8_t j = 0; j < degree; j++) {
-            result[j * stride] ^= rs_multiply(coeff[j], factor);
-        }
-    }
-}
-
-static int8_t encodeDataCodewords(BitBucket *dataCodewords, const uint8_t *text, uint16_t length, uint8_t version) {
-    int8_t mode = MODE_BYTE;
-
-    if (isNumeric((char*)text, length)) {
-        mode = MODE_NUMERIC;
-        bb_appendBits(dataCodewords, 1 << MODE_NUMERIC, 4);
-        bb_appendBits(dataCodewords, length, getModeBits(version, MODE_NUMERIC));
-
-        uint16_t accumData = 0;
-        uint8_t accumCount = 0;
-        for (uint16_t i = 0; i < length; i++) {
-            accumData = accumData * 10 + ((char)(text[i]) - '0');
-            accumCount++;
-            if (accumCount == 3) {
-                bb_appendBits(dataCodewords, accumData, 10);
-                accumData = 0;
-                accumCount = 0;
-            }
-        }
-
-        // 1 or 2 digits remaining
-        if (accumCount > 0) {
-            bb_appendBits(dataCodewords, accumData, accumCount * 3 + 1);
-        }
-
-    } else if (isAlphanumeric((char*)text, length)) {
-        mode = MODE_ALPHANUMERIC;
-        bb_appendBits(dataCodewords, 1 << MODE_ALPHANUMERIC, 4);
-        bb_appendBits(dataCodewords, length, getModeBits(version, MODE_ALPHANUMERIC));
-
-        uint16_t accumData = 0;
-        uint8_t accumCount = 0;
-        for (uint16_t i = 0; i  < length; i++) {
-            accumData = accumData * 45 + getAlphanumeric((char)(text[i]));
-            accumCount++;
-            if (accumCount == 2) {
-                bb_appendBits(dataCodewords, accumData, 11);
-                accumData = 0;
-                accumCount = 0;
-            }
-        }
-
-        // 1 character remaining
-        if (accumCount > 0) {
-            bb_appendBits(dataCodewords, accumData, 6);
-        }
-
-    } else {
-        bb_appendBits(dataCodewords, 1 << MODE_BYTE, 4);
-        bb_appendBits(dataCodewords, length, getModeBits(version, MODE_BYTE));
-        for (uint16_t i = 0; i < length; i++) {
-            bb_appendBits(dataCodewords, (char)(text[i]), 8);
-        }
-    }
-
-    //bb_setBits(dataCodewords, length, 4, getModeBits(version, mode));
-
-    return mode;
-}
-
-static void performErrorCorrection(uint8_t version, uint8_t ecc, BitBucket *data) {
-
-    // See: http://www.thonky.com/qr-code-tutorial/structure-final-message
-
-#if LOCK_VERSION == 0
-    uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc][version - 1];
-    uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc][version - 1];
-    uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1];
-#else
-    uint8_t numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecc];
-    uint16_t totalEcc = NUM_ERROR_CORRECTION_CODEWORDS[ecc];
-    uint16_t moduleCount = NUM_RAW_DATA_MODULES;
-#endif
-
-    uint8_t blockEccLen = totalEcc / numBlocks;
-    uint8_t numShortBlocks = numBlocks - moduleCount / 8 % numBlocks;
-    uint8_t shortBlockLen = moduleCount / 8 / numBlocks;
-
-    uint8_t shortDataBlockLen = shortBlockLen - blockEccLen;
-
-    uint8_t result[data->capacityBytes];
-    memset(result, 0, sizeof(result));
-
-    uint8_t coeff[blockEccLen];
-    rs_init(blockEccLen, coeff);
-
-    uint16_t offset = 0;
-    uint8_t *dataBytes = data->data;
-
-
-    // Interleave all short blocks
-    for (uint8_t i = 0; i < shortDataBlockLen; i++) {
-        uint16_t index = i;
-        uint8_t stride = shortDataBlockLen;
-        for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
-            result[offset++] = dataBytes[index];
-
-#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
-            if (blockNum == numShortBlocks) { stride++; }
-#endif
-            index += stride;
-        }
-    }
-
-    // Version less than 5 only have short blocks
-#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
-    {
-        // Interleave long blocks
-        uint16_t index = shortDataBlockLen * (numShortBlocks + 1);
-        uint8_t stride = shortDataBlockLen;
-        for (uint8_t blockNum = 0; blockNum < numBlocks - numShortBlocks; blockNum++) {
-            result[offset++] = dataBytes[index];
-
-            if (blockNum == 0) { stride++; }
-            index += stride;
-        }
-    }
-#endif
-
-    // Add all ecc blocks, interleaved
-    uint8_t blockSize = shortDataBlockLen;
-    for (uint8_t blockNum = 0; blockNum < numBlocks; blockNum++) {
-
-#if LOCK_VERSION == 0 || LOCK_VERSION >= 5
-        if (blockNum == numShortBlocks) { blockSize++; }
-#endif
-        rs_getRemainder(blockEccLen, coeff, dataBytes, blockSize, &result[offset + blockNum], numBlocks);
-        dataBytes += blockSize;
-    }
-
-    memcpy(data->data, result, data->capacityBytes);
-    data->bitOffsetOrWidth = moduleCount;
-}
-
-// We store the Format bits tightly packed into a single byte (each of the 4 modes is 2 bits)
-// The format bits can be determined by ECC_FORMAT_BITS >> (2 * ecc)
-static const uint8_t ECC_FORMAT_BITS = (0x02 << 6) | (0x03 << 4) | (0x00 << 2) | (0x01 << 0);
-
-uint16_t qrcode_getBufferSize(uint8_t version) {
-    return bb_getGridSizeBytes(4 * version + 17);
-}
-
-// @TODO: Return error if data is too big.
-int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length) {
-    uint8_t size = version * 4 + 17;
-    qrcode->version = version;
-    qrcode->size = size;
-    qrcode->ecc = ecc;
-    qrcode->modules = modules;
-
-    uint8_t eccFormatBits = (ECC_FORMAT_BITS >> (2 * ecc)) & 0x03;
-
-#if LOCK_VERSION == 0
-    uint16_t moduleCount = NUM_RAW_DATA_MODULES[version - 1];
-    uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits][version - 1];
-#else
-    version = LOCK_VERSION;
-    uint16_t moduleCount = NUM_RAW_DATA_MODULES;
-    uint16_t dataCapacity = moduleCount / 8 - NUM_ERROR_CORRECTION_CODEWORDS[eccFormatBits];
-#endif
-
-    struct BitBucket codewords;
-    uint8_t codewordBytes[bb_getBufferSizeBytes(moduleCount)];
-    bb_initBuffer(&codewords, codewordBytes, (int32_t)sizeof(codewordBytes));
-
-    // Place the data code words into the buffer
-    int8_t mode = encodeDataCodewords(&codewords, data, length, version);
-
-    if (mode < 0) { return -1; }
-    qrcode->mode = mode;
-
-    // Add terminator and pad up to a byte if applicable
-    uint32_t padding = (dataCapacity * 8) - codewords.bitOffsetOrWidth;
-    if (padding > 4) { padding = 4; }
-    bb_appendBits(&codewords, 0, padding);
-    bb_appendBits(&codewords, 0, (8 - codewords.bitOffsetOrWidth % 8) % 8);
-
-    // Pad with alternate bytes until data capacity is reached
-    for (uint8_t padByte = 0xEC; codewords.bitOffsetOrWidth < (dataCapacity * 8); padByte ^= 0xEC ^ 0x11) {
-        bb_appendBits(&codewords, padByte, 8);
-    }
-
-    BitBucket modulesGrid;
-    bb_initGrid(&modulesGrid, modules, size);
-
-    BitBucket isFunctionGrid;
-    uint8_t isFunctionGridBytes[bb_getGridSizeBytes(size)];
-    bb_initGrid(&isFunctionGrid, isFunctionGridBytes, size);
-
-    // Draw function patterns, draw all codewords, do masking
-    drawFunctionPatterns(&modulesGrid, &isFunctionGrid, version, eccFormatBits);
-    performErrorCorrection(version, eccFormatBits, &codewords);
-    drawCodewords(&modulesGrid, &isFunctionGrid, &codewords);
-
-    // Find the best (lowest penalty) mask
-    uint8_t mask = 0;
-    int32_t minPenalty = INT32_MAX;
-    for (uint8_t i = 0; i < 8; i++) {
-        drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, i);
-        applyMask(&modulesGrid, &isFunctionGrid, i);
-        int penalty = getPenaltyScore(&modulesGrid);
-        if (penalty < minPenalty) {
-            mask = i;
-            minPenalty = penalty;
-        }
-        applyMask(&modulesGrid, &isFunctionGrid, i);  // Undoes the mask due to XOR
-    }
-
-    qrcode->mask = mask;
-
-    // Overwrite old format bits
-    drawFormatBits(&modulesGrid, &isFunctionGrid, eccFormatBits, mask);
-
-    // Apply the final choice of mask
-    applyMask(&modulesGrid, &isFunctionGrid, mask);
-
-    return 0;
-}
-
-int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data) {
-    return qrcode_initBytes(qrcode, modules, version, ecc, (uint8_t*)data, strlen(data));
-}
-
-uint8_t qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y) {
-    if (x < 0 || x >= qrcode->size || y < 0 || y >= qrcode->size) {
-        return FALSE;
-    }
-
-    uint32_t offset = y * qrcode->size + x;
-    return (qrcode->modules[offset >> 3] & (1 << (7 - (offset & 0x07)))) != 0;
-}
-
-/*
-uint8_t qrcode_getHexLength(QRCode *qrcode) {
-    return ((qrcode->size * qrcode->size) + 7) / 4;
-}
-
-void qrcode_getHex(QRCode *qrcode, char *result) {
-
-}
-*/

+ 0 - 106
EVSE/Projects/AW-CCS/Apps/LCM/qrcode.h

@@ -1,106 +0,0 @@
-/**
- * The MIT License (MIT)
- *
- * This library is written and maintained by Richard Moore.
- * Major parts were derived from Project Nayuki's library.
- *
- * Copyright (c) 2017 Richard Moore     (https://github.com/ricmoo/QRCode)
- * Copyright (c) 2017 Project Nayuki    (https://www.nayuki.io/page/qr-code-generator-library)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-/**
- *  Special thanks to Nayuki (https://www.nayuki.io/) from which this library was
- *  heavily inspired and compared against.
- *
- *  See: https://github.com/nayuki/QR-Code-generator/tree/master/cpp
- */
-
-
-#ifndef __QRCODE_H_
-#define __QRCODE_H_
-
-#include <stdint.h>
-
-#define SIZE_17X17			0
-#define SIZE_21X21			1
-#define SIZE_25X25			2
-#define SIZE_29X29			3
-#define SIZE_33X33			4
-#define SIZE_37X37			5
-#define SIZE_41X41			6
-#define SIZE_45X45			7
-#define SIZE_49X49			8
-#define SIZE_53X53			9
-
-#define	TRUE				1
-#define	FALSE				0
-
-// QR Code Format Encoding
-#define MODE_NUMERIC        0
-#define MODE_ALPHANUMERIC   1
-#define MODE_BYTE           2
-
-
-// Error Correction Code Levels
-#define ECC_LOW            0
-#define ECC_MEDIUM         1
-#define ECC_QUARTILE       2
-#define ECC_HIGH           3
-
-
-// If set to non-zero, this library can ONLY produce QR codes at that version
-// This saves a lot of dynamic memory, as the codeword tables are skipped
-#ifndef LOCK_VERSION
-#define LOCK_VERSION       0
-#endif
-
-
-typedef struct QRCode {
-    uint8_t version;
-    uint8_t size;
-    uint8_t ecc;
-    uint8_t mode;
-    uint8_t mask;
-    uint8_t *modules;
-} QRCode;
-
-
-#ifdef __cplusplus
-extern "C"{
-#endif  /* __cplusplus */
-
-
-
-uint16_t qrcode_getBufferSize(uint8_t version);
-
-int8_t qrcode_initText(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, const char *data);
-int8_t qrcode_initBytes(QRCode *qrcode, uint8_t *modules, uint8_t version, uint8_t ecc, uint8_t *data, uint16_t length);
-
-uint8_t qrcode_getModule(QRCode *qrcode, uint8_t x, uint8_t y);
-
-
-
-#ifdef __cplusplus
-}
-#endif  /* __cplusplus */
-
-
-#endif  /* __QRCODE_H_ */

+ 9 - 2
EVSE/Projects/AW-CCS/Apps/Makefile

@@ -36,7 +36,7 @@ EXI_ENGINE= CCS/v2g/api/api.c \
 	    CCS/Module_CCS.c
 
 all: CopyFile apps
-apps: Module_InternalComm_Task Module_FactoryConfig_Task Module_AlarmDetect_Task Module_CSU_Task Module_Speaker_Task Module_CCS_Task Module_LcmControl_Task Module_ConfigTools_Task Module_Debug_Task
+apps: Module_InternalComm_Task Module_FactoryConfig_Task Module_AlarmDetect_Task Module_CSU_Task Module_Speaker_Task Module_CCS_Task Module_LcmControl_Task Module_ConfigTools_Task Module_Debug_Task Module_PowerSharing_Task
 
 Module_ConfigTools_Task:
 	@echo "===== Module_ConfigTools_Task  ==================================="
@@ -127,10 +127,17 @@ Module_CCS_Task:
 Module_LcmControl_Task:
 	@echo "===== Module_LcmControl_Task ==================================="
 	rm -f Module_LcmControl
-	$(CC) -D $(Project) "-I../../../Modularization/ocppfiles/" "-I./" "-I../../" -O0 -g3 -Wall -fmessage-length=0 LCM/lcmComm.c LCM/Module_LcmControl.c LCM/qrcode.c -o Module_LcmControl
+	$(CC) -D $(Project) "-I../../../Modularization/ocppfiles/" "-I./" "-I../../" -O0 -g3 -Wall -fmessage-length=0 LCM/lcmComm_dgus.c LCM/Module_LcmControl.c -o Module_LcmControl
 	rm -f *.o	
 	mv -f Module_LcmControl ../Images/root
 
+Module_PowerSharing_Task:
+	@echo "===== Module_PowerSharing_Task ==================================="
+	rm -f Module_PowerSharing
+	$(CC) -D $(Project) "-I../../../Modularization/ocppfiles/" "-I./" "-I../../" -O0 -g3 -Wall -fmessage-length=0 Module_PowerSharing.c -o Module_PowerSharing
+	rm -f *.o
+	mv -f Module_PowerSharing ../Images/root
+
 CopyFile: 
 	rm -rfv ../Images/root
 	mkdir -p ../Images/root

+ 115 - 1
EVSE/Projects/AW-CCS/Apps/Module_Debug.c

@@ -40,6 +40,8 @@
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
+struct OCPP16Data				*ShmOCPP16Data;
+struct OCPP20Data				*ShmOCPP20Data;
 struct Charger					*ShmCharger;
 
 int StoreLogMsg(const char *fmt, ...)
@@ -113,6 +115,30 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
+	// Initial ShmOCPP16Data
+	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+
+	// Initial ShmOCPP20Data
+	if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+
 	//Initial ShmCharger
 	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
 	{
@@ -165,6 +191,7 @@ int main(void)
 		memset(cmd, 0x00, ARRAY_SIZE(cmd));
 		printf("\n ============== Debug main menu ==================");
 		printf("\n  info: List charger status info.");
+		printf("\n  test: Charger test command.");
 		printf("\n  exit: Exit Module_Debug_Test.");
 		printf("\n =================================================");
 		printf("\n  Please input debug command: ");
@@ -195,14 +222,33 @@ int main(void)
 
 					gun_index = gun_index<AC_QUANTITY?gun_index:0;
 
+					printf("\n  CSU u-boot version: %s", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev);
+					printf("\n  CSU kernel version: %s", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev);
+					printf("\n  CSU rootfs version: %s", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger connector plug times: %d", ShmCharger->gun_info[gun_index].gunPluginTimes.GunPluginTimes);
+					printf("\n --------------------------------------------------");
 					printf("\n  CP positive voltage: %.2f", ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltagePositive);
 					printf("\n  CP negative voltage: %.2f", ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltageNegative);
+					printf("\n --------------------------------------------------");
 					printf("\n  CSU to MCU legacyRequest: %d", ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest);
 					printf("\n  CSU to MCU relay on request: %d", ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger charging mode BS/HLC: %d", ShmCharger->gun_info[gun_index].chargingMode);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger input voltage L1: %.2f", ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12);
-					printf("\n  CSU output current L1: %.2f", ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]);
+					printf("\n  Charger input voltage L2: %.2f", ShmCharger->gun_info[gun_index].inputVoltage.L2N_L23);
+					printf("\n  Charger input voltage L3: %.2f", ShmCharger->gun_info[gun_index].inputVoltage.L3N_L31);
+					printf("\n --------------------------------------------------");
+					printf("\n  CSU output current L1: %.2f", ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[gun_index]);
+					printf("\n  CSU output current L2: %.2f", ShmCharger->gun_info[gun_index].outputCurrent.L2N_L23[gun_index]);
+					printf("\n  CSU output current L3: %.2f", ShmCharger->gun_info[gun_index].outputCurrent.L3N_L31[gun_index]);
+					printf("\n --------------------------------------------------");
+					printf("\n  CSU power consumption L1: %.2f", (ShmCharger->gun_info[gun_index].powerConsumption[0].power_consumption/100.0));
+					printf("\n  CSU power consumption L2: %.2f", (ShmCharger->gun_info[gun_index].powerConsumption[1].power_consumption/100.0));
+					printf("\n  CSU power consumption L3: %.2f", (ShmCharger->gun_info[gun_index].powerConsumption[2].power_consumption/100.0));
+					printf("\n  CSU power total consumption: %.2f", (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0));
+					printf("\n --------------------------------------------------");
 					printf("\n  CSU temperature: %d", ShmCharger->gun_info[gun_index].temperature.point[0]);
 
 					wait();
@@ -213,7 +259,9 @@ int main(void)
 					scanf("%d", &gun_index);
 					printf("\n  MCU info.\n\n");
 
+					gun_index = gun_index<AC_QUANTITY?gun_index:0;
 
+					printf("\n  Firmware version: %s", ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 					wait();
 				}
@@ -224,6 +272,72 @@ int main(void)
 				}
 			}while(!isExit);
 		}
+		else if(strcmp(cmd, "test") == 0)
+		{
+			int gun_index;
+
+			memset(cmd, 0x00, ARRAY_SIZE(cmd));
+			printf("\n ***************** Info menu *********************");
+			printf("\n  start: start charging session");
+			printf("\n  stop: stop charging session");
+			printf("\n  operative: enable charger gun");
+			printf("\n  inoperative: disable charger gun");
+			printf("\n  exit: exit to previous menu.");
+			printf("\n *************************************************");
+			printf("\n  Please input command: ");
+			scanf("%s", &cmd[0]);
+
+			if(strcmp(cmd, "start") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				ShmCharger->gun_info[gun_index].bleConfigData.isRequestStart = ON;
+			}
+			else if(strcmp(cmd, "stop") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = ON;
+			}
+			else if(strcmp(cmd, "operative") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+				{
+					sprintf((char*)ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Operative");
+					ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+				else
+				{
+					sprintf((char*)(char*)ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Operative");
+					ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+			}
+			else if(strcmp(cmd, "inoperative") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+				{
+					sprintf((char*)ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Inoperative");
+					ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+				else
+				{
+					sprintf((char*)(char*)ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Inoperative");
+					ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+			}
+			else if(strcmp(cmd, "exit") == 0)
+			{
+				printf("\n  Exit to previous.\n\n");
+			}
+		}
 		else if(strcmp(cmd, "exit") == 0)
 		{
 			printf("\n  exit program.\n\n");

+ 2 - 1
EVSE/Projects/AW-CCS/Apps/Module_FactoryConfig.c

@@ -265,6 +265,7 @@ int main(int argc, char *argv[])
 	{
 		memcpy((char*)SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.ModelName, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ModelName));
 		memcpy((char*)SysConfig.SerialNumber, ShmSysConfigAndInfo->SysConfig.SerialNumber, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.SerialNumber));
+		memcpy((char*)SysConfig.CsuBootLoadFwRev, ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.CsuBootLoadFwRev));
 
 		DEBUG_INFO("InitShareMemory OK.\n");
 	}
@@ -311,7 +312,7 @@ int main(int argc, char *argv[])
 	SysConfig.OfflinePolicy = 2;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
 	SysConfig.OfflineMaxChargeEnergy = 0;	// 0: Same as MaxChargeEnergy	Other: 1~65535KWH
 	SysConfig.OfflineMaxChargeDuration = 0; // 0: Same as MaxChargeDuration Other: 1~65535 minutes
-
+	SysConfig.isReqFirstUpgrade = 1;		// 0: Skip first upgrade, 	1: Process first upgrade
 
 	// Customization configuration item
 	if(strstr((char*)&SysConfig.ModelName[12], "P0") != NULL)

+ 6 - 3
EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c

@@ -1966,16 +1966,17 @@ int main(void)
 					ShmCharger->gun_info[gun_index].acCcsInfo.CpNegativeVoltage = ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltageNegative;					
 					ShmCharger->gun_info[gun_index].acCcsInfo.CpPresentPWMDuty = ShmCharger->gun_info[gun_index].primaryMcuState.current_limit;
 					
-					if(ShmCharger->gun_info[gun_index].primaryMcuState.relayState.relay_status[0][0]>0)
+					if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state)
 					{
 						ShmCharger->gun_info[gun_index].acCcsInfo.OutputRelayStatus = ON;
+						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].RelayK1K2Status = ON;
 					}
 					else
 					{
-						ShmCharger->gun_info[gun_index].acCcsInfo.OutputRelayStatus = OFF;	
+						ShmCharger->gun_info[gun_index].acCcsInfo.OutputRelayStatus = OFF;
+						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].RelayK1K2Status = OFF;
 					}					
 
-
 					failCount[gun_index] = 0;
 				}
 				else
@@ -2302,6 +2303,8 @@ int main(void)
 					DEBUG_INFO("MCU-%d get Relay State : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.relay_state);
 					DEBUG_INFO("MCU-%d get Rating Current : %.2f\n", gun_index, (float)ShmCharger->gun_info[gun_index].primaryMcuState.rating_current);
 					DEBUG_INFO("MCU-%d get Rotary switch : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch);
+					DEBUG_INFO("MCU-%d get is on Socket-E mode : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEMode);
+					DEBUG_INFO("MCU-%d get Socket-E detect pin : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn);
 
 					/*
 					DEBUG_INFO("MCU-%d get Locker State : %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuState.locker_state);

BIN
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing


+ 871 - 0
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.c

@@ -0,0 +1,871 @@
+/*
+ * Module_PowerSharing.c
+ *
+ *  Created on: 2020/12/07
+ *      Author: foluswen
+ */
+#include "Module_PowerSharing.h"
+
+struct SysConfigAndInfo		*ShmSysConfigAndInfo;
+struct StatusCodeData 		*ShmStatusCodeData;
+struct OCPP16Data			*ShmOCPP16Data;
+struct Charger				*ShmCharger;
+struct POWER_SHARING		*ShmPowerSharing;
+
+//==========================================
+// Common routine
+//==========================================
+int StoreLogMsg(const char *fmt, ...)
+{
+	char Buf[4096+256];
+	char buffer[4096];
+	time_t CurrentTime;
+	struct tm *tm;
+	struct timeval tv;
+	va_list args;
+
+	va_start(args, fmt);
+	int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
+	va_end(args);
+
+	memset(Buf,0,sizeof(Buf));
+	CurrentTime = time((time_t*)NULL);
+	tm=localtime(&CurrentTime);
+	gettimeofday(&tv, NULL); // get microseconds, 10^-6
+
+
+	sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s\" >> /Storage/SystemLog/[%04d.%02d]Module_PowerSharingLog",
+				tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec,
+				buffer,
+				tm->tm_year+1900,tm->tm_mon+1);
+
+#ifdef SystemLogMessage
+	system(Buf);
+#endif
+
+#ifdef ConsloePrintLog
+	printf("[%04d.%02d.%02d %02d:%02d:%02d.%06ld]%s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,tv.tv_usec, buffer);
+#endif
+
+	return rc;
+}
+
+int DiffTimeb(struct timeb ST, struct timeb ET)
+{
+	//return milli-second
+	unsigned int StartTime,StopTime;
+
+	StartTime=(unsigned int)ST.time;
+	StopTime=(unsigned int)ET.time;
+	return (StopTime-StartTime)*1000+ET.millitm-ST.millitm;
+}
+
+void dM(uint8_t *data, uint16_t len, uint8_t isRX)
+{
+#ifdef DEBUG
+	uint8_t output[8192];
+
+	if(isRX)
+	{
+		DEBUG_INFO("- RX --------------------------------------------\n");
+	}
+	else
+	{
+		DEBUG_INFO("- TX --------------------------------------------\n");
+	}
+
+	memset(output, 0x00, ARRAY_SIZE(output));
+	for(uint16_t idx=0;idx<16;idx++)
+		sprintf((char*)output, "%s %02X", output, idx);
+	DEBUG_INFO("%s\n", output);
+	DEBUG_INFO("-------------------------------------------------\n");
+
+	for(uint16_t idx = 0;idx<len;idx++)
+	{
+		if((idx%16)>0)
+		{
+			sprintf((char*)output, "%s %02X", output, data[idx]);
+		}
+		else
+		{
+			if(idx != 0)
+				DEBUG_INFO("%s\n", output);
+			memset(output, 0x00, ARRAY_SIZE(output));
+			sprintf((char*)output, "%s %02X", output, data[idx]);
+		}
+	}
+	DEBUG_INFO("%s\n", output);
+	DEBUG_INFO("-------------------------------------------------\n");
+#endif
+}
+
+int isValidCheckSum(struct Message *message)
+{
+	uint8_t chksum = 0x00;
+
+	for(int idx=0;idx<(((message->buffer[2]) | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):((message->buffer[2]) | message->buffer[3]<<8));idx++)
+	{
+		chksum ^= message->buffer[4+idx];
+	}
+
+	return ((chksum == message->buffer[4+((message->buffer[2] | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):(message->buffer[2] | message->buffer[3]<<8))]) ? PASS : FAIL);
+}
+
+uint8_t chksumCal(struct Message *message)
+{
+	uint8_t chksum=0;
+
+	for(int idx=0;idx<(((message->buffer[2]) | message->buffer[3]<<8)>ARRAY_SIZE(message->buffer)?ARRAY_SIZE(message->buffer):((message->buffer[2]) | message->buffer[3]<<8));idx++)
+	{
+		chksum ^= message->buffer[4+idx];
+	}
+
+	return chksum & 0xff;
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//Initial ShmSysConfigAndInfo
+	if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo),  0777)) < 0)
+    {
+		DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
+		result = FAIL;
+	}
+    else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
+    	result = FAIL;
+   	 }
+    else
+    {}
+
+   	//Initial ShmStatusCodeData
+   	if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData),  0777)) < 0)
+    {
+   		DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
+   		result = FAIL;
+	}
+    else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+    	DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
+    	result = FAIL;
+   	}
+    else
+    {}
+
+   	//Initial ShmOCPP16Data
+	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data),  0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP16Data NG");
+		result = FAIL;
+	}
+	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP16Data NG");
+		result = FAIL;
+	}
+	else
+	{}
+
+	//Initial ShmCharger
+	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmCharger NG\n");
+		result = FAIL;
+	}
+	else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmCharger NG\n");
+		result = FAIL;
+	}
+
+	//Create ShmPowerSharing
+	if ((MeterSMId = shmget(ShmPowerShargingKey, sizeof(struct POWER_SHARING), IPC_CREAT | 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmPowerShargingKey NG\n");
+
+		result = FAIL;
+	}
+	else if ((ShmPowerSharing = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmPowerShargingKey NG\n");
+
+		result = FAIL;
+	}
+	memset(ShmPowerSharing,0,sizeof(struct POWER_SHARING));
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+		ShmPowerSharing->Connection_Info[idx].socketFd = (idx+1);
+
+    return result;
+}
+
+//==========================================
+// UDP socket server routine
+//==========================================
+int udpSocketServerStart(void)
+{
+	int sockFd;
+	struct sockaddr_in servaddr;
+	struct sockaddr_in peeraddr;
+	socklen_t 			peerlen = sizeof(peeraddr);
+	uint8_t 			inputBuffer[2048] = {};
+	uint8_t 			outBuffer[2048] = {};
+	int16_t				read_size;
+	int16_t				tx_size;
+
+	memset(&servaddr, 0, sizeof(servaddr));
+	servaddr.sin_family = AF_INET;
+	servaddr.sin_port = htons(LISTEN_PORT_UDP);
+	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+	if ((sockFd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
+	{
+		DEBUG_ERROR("UDP server socket create fail.\n");
+		return FAIL;
+	}
+
+	if (bind(sockFd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
+	{
+		DEBUG_ERROR("UDP server socket bind fail.\n");
+	    return FAIL;
+	}
+	else
+		DEBUG_INFO("UDP server initial.\n");
+
+	for(;;)
+	{
+		if((read_size = recvfrom(sockFd, inputBuffer, sizeof(inputBuffer), 0, (struct sockaddr *)&peeraddr, &peerlen)) > 0)
+		{
+			DEBUG_INFO("Revieve from: %s:%d\n", inet_ntoa(peeraddr.sin_addr), htons(peeraddr.sin_port));
+			DEBUG_INFO("read_size: %d\n",read_size);
+			dM(inputBuffer, read_size, YES);
+
+			if(read_size>=6)
+			{
+				/*
+				 *	TODO:
+				 *	1. Protocol validation
+				 *	2. Protocol message parsing
+				 */
+
+				if(TRUE)
+				{
+					DEBUG_INFO("Receive UDP broadcast command.\n");
+					memset(outBuffer, 0x00, ARRAY_SIZE(outBuffer));
+					tx_size = 41;
+
+					outBuffer[0] = 0xff;
+					outBuffer[1] = 0xff;
+					outBuffer[2] = (0x25 << 0x08) & 0xff;
+					outBuffer[3] = 0x25 & 0xff;
+					outBuffer[4] = 0x00;
+
+					dM(outBuffer, tx_size, NO);
+					sendto(sockFd, outBuffer, tx_size, 0, (struct sockaddr *)&peeraddr, peerlen);
+				}
+			}
+		}
+	}
+
+	return FAIL;
+}
+
+//==========================================
+// TCP socket server routine
+//==========================================
+int conn_getDupFd(void)
+{
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(!ShmPowerSharing->Connection_Info[idx].isConnected)
+		{
+			result = ShmPowerSharing->Connection_Info[idx].socketFd;
+			break;
+		}
+	}
+
+	return result;
+}
+
+int conn_register(int socketFd)
+{
+	int result = FAIL;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(!ShmPowerSharing->Connection_Info[idx].isConnected)
+		{
+			DEBUG_INFO("Dupfd-%d register to conn-%d.\n", socketFd, idx);
+			ShmPowerSharing->Connection_Info[idx].isConnected = TRUE;
+			ShmPowerSharing->Connection_Info[idx].socketFd = socketFd;
+			ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL);
+			result = PASS;
+			break;
+		}
+	}
+
+	return result;
+}
+
+int conn_reject(int socketFd)
+{
+	int result = FAIL;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
+		{
+			DEBUG_INFO("Dupfd-%d register from conn_info-%d.\n", socketFd, idx);
+			ShmPowerSharing->Connection_Info[idx].isConnected = FALSE;
+			ShmPowerSharing->Connection_Info[idx].isCharging = FALSE;
+			result = PASS;
+			break;
+		}
+	}
+
+	return result;
+
+}
+
+int conn_getConectedQuantity(void)
+{
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].isConnected)
+		{
+			result += 1;
+		}
+	}
+
+	DEBUG_INFO("Connection quantity: %d\n", result);
+	ShmPowerSharing->connectedQty = result;
+	return result;
+}
+
+int conn_getChargingQuantity(void)
+{
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].isCharging)
+		{
+			result += 1;
+		}
+	}
+
+	//DEBUG_INFO("Charging quantity: %d\n", result);
+	return result;
+}
+
+int conn_getTotalAvailableSharingCurrent(void)
+{
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].isConnected)
+		{
+			result += ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
+		}
+	}
+
+	DEBUG_INFO("Total sharing current: %d\n", result);
+	return result;
+}
+
+int conn_getTotalPresentOutputCurrent(void)
+{
+	int result = 0;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].isConnected && ShmPowerSharing->Connection_Info[idx].isCharging)
+		{
+			result += ShmPowerSharing->Connection_Info[idx].presentOutputCurrent;
+		}
+	}
+
+	DEBUG_INFO("Total actual current: %d\n", result);
+	return result;
+}
+
+uint16_t conn_querySharingCurrent(int socketFd)
+{
+	uint16_t result = 0x00;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
+		{
+			//DEBUG_INFO("Dupfd-%d on conn_info-%d query sharing current(0.1A): %d\n", socketFd, idx, ShmPowerSharing->Connection_Info[idx].sharingCurrent);
+			result = ShmPowerSharing->Connection_Info[idx].availableSharingCurrent;
+			break;
+		}
+	}
+
+	return result;
+}
+
+int conn_updateHeartBeatTime(int socketFd)
+{
+	int result = FAIL;
+
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
+		{
+			//DEBUG_INFO("Dupfd-%d register from conn_info-%d update heart beat time.\n", socketFd, idx);
+			ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime = time((time_t*)NULL);
+			result = PASS;
+			break;
+		}
+	}
+
+	return result;
+}
+
+int conn_updatePresentCurrentOutput(int socketFd, uint8_t isCharging, uint16_t outputCurrent)
+{
+	int result = FAIL;
+	for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+	{
+		if(ShmPowerSharing->Connection_Info[idx].socketFd == socketFd)
+		{
+			//DEBUG_INFO("Dupfd-%d on conn_info-%d update actual output current(0.1A): %d\n", socketFd, idx, outputCurrent);
+			ShmPowerSharing->Connection_Info[idx].isCharging = isCharging;
+			ShmPowerSharing->Connection_Info[idx].presentOutputCurrent = outputCurrent;
+			result = PASS;
+		}
+	}
+
+	return result;
+}
+
+int conn_check_loop(void)
+{
+	for(;;)
+	{
+		// Check conn heart beat
+		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+		{
+			if(ShmPowerSharing->Connection_Info[idx].isConnected &&
+			   (difftime(time((time_t*)NULL), ShmPowerSharing->Connection_Info[idx].lastHeartBeatTime) > 300))
+			{
+				DEBUG_INFO("SocketFd-%d heart beat is over 300 seconds.\n", ShmPowerSharing->Connection_Info[idx].socketFd);
+				ShmPowerSharing->Connection_Info[idx].isCharging = FALSE;
+				ShmPowerSharing->Connection_Info[idx].isConnected = FALSE;
+			}
+		}
+
+		// Check available power
+		for(uint8_t idx=0;idx<CONNECTION_LIMIT;idx++)
+		{
+			if(ShmPowerSharing->Connection_Info[idx].isConnected &&
+			   ShmPowerSharing->Connection_Info[idx].isCharging)
+			{
+				if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent != ((ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity()))
+				{
+					DEBUG_INFO("Dupfd-%d on conn_info-%d update sharing current(0.1A): %d\n", ShmPowerSharing->Connection_Info[idx].socketFd, idx, ((ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity()));
+				}
+				ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = (ShmCharger->gun_info[0].primaryMcuState.rating_current*10) / conn_getChargingQuantity();
+			}
+			else
+			{
+				if(ShmPowerSharing->Connection_Info[idx].availableSharingCurrent != 0)
+				{
+					DEBUG_INFO("Dupfd-%d on conn_info-%d update sharing current(0.1A): 0\n", ShmPowerSharing->Connection_Info[idx].socketFd, idx);
+				}
+				ShmPowerSharing->Connection_Info[idx].availableSharingCurrent = 0;
+			}
+		}
+
+		sleep(1);
+	}
+
+	return FAIL;
+}
+
+int tcpSocketServerStart(void)
+{
+	int 				sockFd = 0;
+	int 				clientSockFd = 0;
+	int					dupFd = 0;
+	struct Message		input;
+	struct Message		output;
+	struct sockaddr_in 	serverInfo, clientInfo;
+	socklen_t 			addrlen = sizeof(clientInfo);
+	uint16_t 			sharingCurrent=0;
+
+	sockFd = socket(AF_INET , SOCK_STREAM , 0);
+	if(sockFd == -1)
+	{
+		DEBUG_ERROR("TCP service socket create fail.\n");
+		sleep(5);
+		return FAIL;
+	}
+
+	bzero(&serverInfo,sizeof(serverInfo));
+	serverInfo.sin_family = PF_INET;
+	serverInfo.sin_addr.s_addr = htonl(INADDR_ANY);
+	serverInfo.sin_port = htons(LISTEN_PORT_TCP);
+
+	if(bind(sockFd, (struct sockaddr *)&serverInfo, sizeof(serverInfo)) < 0)
+		DEBUG_ERROR("TCP server socket bind fail.\n");
+
+	if(listen(sockFd, CONNECTION_LIMIT) < 0)
+		DEBUG_ERROR("TCP server socket listen fail.\n");
+	else
+		DEBUG_INFO("Power sharing TCP server initial listen on port %d.\n", LISTEN_PORT_TCP);
+
+	// Main loop
+	for(;;)
+	{
+		clientSockFd = accept(sockFd, (struct sockaddr*) &clientInfo, &addrlen);
+		fcntl(clientSockFd, F_SETFD, FD_CLOEXEC);
+		DEBUG_INFO("Client connect in.\n");
+		DEBUG_INFO("clientSockFd : %d\n", clientSockFd);
+
+		if(clientSockFd > 0)
+		{
+			if(conn_getConectedQuantity() < CONNECTION_LIMIT)
+			{
+				// Fork a child process to handle the new conn
+				if(fork()==0)
+				{
+					// Assign socket handle as available handle in conn info pool
+					dupFd = dup2(clientSockFd, conn_getDupFd());
+					conn_register(dupFd);
+					while((input.size = recv(dupFd, input.buffer, sizeof(input.buffer), 0)) > 0)
+					{
+						dM(input.buffer, input.size, YES);
+
+						if(isValidCheckSum(&input))
+						{
+							conn_updateHeartBeatTime(dupFd);
+
+							memset(output.buffer, 0x00, ARRAY_SIZE(output.buffer));
+							switch(input.buffer[1])
+							{
+								case SHARING_CMD_QUERY_SHARING:
+									sharingCurrent = conn_querySharingCurrent(dupFd);
+									output.size = 7;
+									output.buffer[0] = 0xaa;
+									output.buffer[1] = SHARING_CMD_QUERY_SHARING;
+									output.buffer[2] = 0x02;
+									output.buffer[3] = 0x00;
+									output.buffer[4] = ((sharingCurrent>>0) & 0xff);
+									output.buffer[5] = ((sharingCurrent>>8) & 0xff);
+									output.buffer[6] = chksumCal(&output);
+									break;
+
+								case SHARING_CMD_SYNC_INFO:
+									conn_updatePresentCurrentOutput(dupFd, input.buffer[4], (input.buffer[5] | (input.buffer[6]<<0x08)));
+									output.size = 6;
+									output.buffer[0] = 0xaa;
+									output.buffer[1] = SHARING_CMD_SYNC_INFO;
+									output.buffer[2] = 0x01;
+									output.buffer[3] = 0x00;
+									output.buffer[4] = 0x01;
+									output.buffer[5] = chksumCal(&output);
+
+									break;
+
+								default:
+									DEBUG_WARN("Receive unknown command.\n");
+									output.size = 5;
+									output.buffer[0] = 0xaa;
+									output.buffer[1] = SHARING_CMD_UNKNOWN;
+									output.buffer[2] = 0x00;
+									output.buffer[3] = 0x00;
+									output.buffer[4] = chksumCal(&output);
+
+									break;
+							}
+						}
+						else
+						{
+							DEBUG_WARN("Receive command check sum error.\n");
+							output.size = 5;
+							output.buffer[0] = 0xaa;
+							output.buffer[1] = SHARING_CMD_CHKSUM_ERROR;
+							output.buffer[2] = 0x00;
+							output.buffer[3] = 0x00;
+							output.buffer[4] = chksumCal(&output);
+						}
+
+						dM(output.buffer, output.size, NO);
+						send(clientSockFd, output.buffer, output.size, 0);
+					}
+
+					if(input.size == 0)
+					{
+						DEBUG_INFO("Client disconnected.\n");
+
+						conn_reject(dupFd);
+						close(dupFd);
+						close(clientSockFd);
+						fflush(stdout);
+					}
+					else if(input.size == -1)
+					{
+						DEBUG_ERROR("Socket recv failed.\n");
+
+						conn_reject(dupFd);
+						close(dupFd);
+						close(clientSockFd);
+						fflush(stdout);
+					}
+
+					conn_getConectedQuantity();
+
+					exit(0);
+				}
+				else
+				{
+					// if parent, close the socket and go back to listening new requests
+					close(clientSockFd);
+				}
+			}
+			else
+			{
+				DEBUG_WARN("Connection is over limit.\n");
+				output.size = 5;
+				output.buffer[0] = 0xaa;
+				output.buffer[1] = SHARING_CMD_CONNECTION_FULL;
+				output.buffer[2] = 0x00;
+				output.buffer[3] = 0x00;
+				output.buffer[4] = chksumCal(&output);
+				send(clientSockFd, output.buffer, output.size, 0);
+				close(clientSockFd);
+			}
+		}
+
+		sleep(1);
+	}
+
+	return FAIL;
+}
+
+//==========================================
+// Client routine
+//==========================================
+void create_cmd_sync(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 8;
+	out->buffer[0] = 0xaa;
+	out->buffer[1] = SHARING_CMD_SYNC_INFO;
+	out->buffer[2] = 0x03;
+	out->buffer[3] = 0x00;
+	out->buffer[4] = (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus == SYS_MODE_CHARGING?YES:NO);
+	out->buffer[5] = (((uint16_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PresentChargingCurrent*10))>>0) & 0xff;
+	out->buffer[6] = (((uint16_t)(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].PresentChargingCurrent*10))>>8) & 0xff;
+	out->buffer[7] = chksumCal(out);
+
+	dM(out->buffer, out->size, FALSE);
+}
+
+void create_cmd_query(struct Message *out)
+{
+	memset(out->buffer, 0, ARRAY_SIZE(out->buffer));
+
+	out->size = 5;
+	out->buffer[0] = 0xaa;
+	out->buffer[1] = SHARING_CMD_QUERY_SHARING;
+	out->buffer[2] = 0x00;
+	out->buffer[3] = 0x00;
+	out->buffer[4] = chksumCal(out);
+	dM(out->buffer, out->size, FALSE);
+}
+
+int tcpSocketClientStart(void)
+{
+	int 				sockfd;
+	struct sockaddr_in 	info;
+	struct hostent 		*ghbn;
+	struct timeval 		tv;
+	uint8_t 			socketEnable;
+
+	struct Message		input;
+	struct Message		output;
+
+	uint8_t				cmdIdx;
+
+	bzero(&info,sizeof(info));
+	ghbn = gethostbyname((char*)"192.168.10.10");
+	info.sin_family = PF_INET;
+	info.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]));
+	info.sin_port = htons(LISTEN_PORT_TCP);
+	ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF;
+	DEBUG_INFO("Connect to %s:%d\n", inet_ntoa(*(struct in_addr *)ghbn->h_addr_list[0]), LISTEN_PORT_TCP);
+
+	sockfd = socket(AF_INET, SOCK_STREAM, 0);
+	if (sockfd == -1)
+	{
+		DEBUG_ERROR("Fail to create a socket.");
+		return 0;
+	}
+
+	if(connect(sockfd, (struct sockaddr *)&info,sizeof(info)) ==-1)
+	{
+		DEBUG_ERROR("Connection error.\n");
+		ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF;
+		socketEnable = OFF;
+	}
+	else
+	{
+		DEBUG_INFO("Connect success.\n");
+		tv.tv_sec = 0;
+		tv.tv_usec = 500000;
+		setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
+		socketEnable = ON;
+	}
+
+	while(socketEnable)
+	{
+		memset(input.buffer, 0, ARRAY_SIZE(input.buffer));
+		if((input.size = recv(sockfd, input.buffer, ARRAY_SIZE(input.buffer), 0)) > 0)
+		{
+			//DEBUG_INFO("Receive size: %d.\n", input.size);
+			dM(input.buffer, input.size, TRUE);
+
+			if(isValidCheckSum(&input))
+			{
+				switch(input.buffer[1])
+				{
+					case SHARING_CMD_QUERY_SHARING:
+						if(ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent != ((input.buffer[4] | (input.buffer[5] << 8))/10))
+						{
+							ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent = ((input.buffer[4] | (input.buffer[5] << 8))/10);
+							DEBUG_INFO("Update available sharing current(A): %d\n", ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent);
+						}
+						ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = ON;
+
+						break;
+
+					case SHARING_CMD_SYNC_INFO:
+						if(!input.buffer[4])
+							DEBUG_INFO("Charger status sync reject.\n");
+
+						break;
+
+					default:
+						DEBUG_WARN("Receive unknown command.\n");
+						break;
+				}
+			}
+			else
+			{
+				DEBUG_WARN("Receive command check sum error.\n");
+			}
+		}
+		else if(input.size == 0)
+		{
+			DEBUG_INFO("Disconnected.\n");
+			fflush(stdout);
+
+			socketEnable = OFF;
+			ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer = OFF;
+		}
+		else if(input.size == -1)
+		{
+			switch(cmdIdx)
+			{
+				case 0:
+					create_cmd_sync(&output);
+					cmdIdx += 1;
+					break;
+				default:
+					create_cmd_query(&output);
+					cmdIdx = 0;
+					break;
+			}
+			send(sockfd, output.buffer, output.size, 0);
+		}
+		usleep(1000000);
+	}
+	close(sockfd);
+
+	return FAIL;
+}
+
+//==========================================
+// Main process
+//==========================================
+int main(void)
+{
+	signal(SIGCHLD,SIG_IGN);
+
+	// Initial share memory
+	if(InitShareMemory() == FAIL)
+	{
+		DEBUG_ERROR("InitShareMemory NG\n");
+
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=ON;
+		}
+		sleep(5);
+		return 0;
+	}
+
+	// Enable server if rotary switch not slave mode
+	if((ShmCharger->gun_info[0].primaryMcuState.rotatory_switch != SWITCH_F_SLAVE) &&
+	   (AC_QUANTITY==1?TRUE:(ShmCharger->gun_info[1].primaryMcuState.rotatory_switch != SWITCH_F_SLAVE)))
+	{
+		// UDP socket server start
+		/*
+		if(fork() == 0)
+		{
+			if(udpSocketServerStart() == FAIL)
+			{
+				DEBUG_ERROR("UDP socket server down.\n");
+				return 0;
+			}
+		}*/
+
+		// TCP socket server start
+		if(fork() == 0)
+		{
+			if(tcpSocketServerStart() == FAIL)
+			{
+				DEBUG_ERROR("TCP socket server down.\n");
+				return 0;
+			}
+		}
+
+		// Connection check loop
+		if(fork() == 0)
+		{
+			if(conn_check_loop() == FAIL)
+			{
+				DEBUG_ERROR("Connection check loop fail.\n");
+				return 0;
+			}
+		}
+	}
+
+	sleep(10);
+	for(;;)
+	{
+		// Slave logic
+		tcpSocketClientStart();
+
+		usleep(100000);
+	}
+
+	return FAIL;
+}

+ 119 - 0
EVSE/Projects/AW-CCS/Apps/Module_PowerSharing.h

@@ -0,0 +1,119 @@
+/*
+ * Module_PowerSharing.h
+ *
+ *  Created on: 2020/12/07
+ *      Author: foluswen
+ */
+
+#ifndef MODULE_POWERSHARING_H_
+#define MODULE_POWERSHARING_H_
+
+#include 	<sys/time.h>
+#include 	<sys/timeb.h>
+#include    <sys/types.h>
+#include    <sys/stat.h>
+#include 	<sys/types.h>
+#include 	<sys/ioctl.h>
+#include 	<sys/socket.h>
+#include 	<sys/ipc.h>
+#include 	<sys/shm.h>
+#include 	<sys/shm.h>
+#include 	<sys/mman.h>
+#include 	<linux/wireless.h>
+#include 	<arpa/inet.h>
+#include 	<netinet/in.h>
+
+#include 	<unistd.h>
+#include 	<stdarg.h>
+#include    <stdio.h>
+#include    <stdlib.h>
+#include    <unistd.h>
+#include    <fcntl.h>
+#include    <termios.h>
+#include    <errno.h>
+#include 	<errno.h>
+#include 	<string.h>
+#include	<time.h>
+#include	<ctype.h>
+#include 	<ifaddrs.h>
+#include 	<sys/types.h>
+#include 	<sys/socket.h>
+#include 	<netinet/in.h>
+#include 	<netdb.h>
+#include 	<error.h>
+#include 	<signal.h>
+#include	"define.h"
+#include 	"main.h"
+
+//#define DEBUG
+#define is_error(ptr) 				((unsigned long)ptr > (unsigned long)-4000L)
+#define ARRAY_SIZE(A)				(sizeof(A) / sizeof(A[0]))
+#define PASS						1
+#define FAIL			   			-1
+#define ON							1
+#define OFF							0
+#define YES							1
+#define NO							0
+#define true			    		1
+#define false						0
+
+#define LISTEN_PORT_UDP				8421
+#define LISTEN_PORT_TCP				8422
+#define	CONNECTION_LIMIT			8
+
+#define ShmPowerShargingKey			LISTEN_PORT_TCP
+
+enum ROTARY_SWITCH_LIMIT
+{
+	SWITCH_0_DEBUG=0,
+	SWITCH_1_12A,
+	SWITCH_2_16A,
+	SWITCH_3_20A,
+	SWITCH_4_24A,
+	SWITCH_5_28A,
+	SWITCH_6_32A,
+	SWITCH_7_36A,
+	SWITCH_8_40A,
+	SWITCH_9_48A,
+	SWITCH_A_56A,
+	SWITCH_B_64A,
+	SWITCH_C_72A,
+	SWITCH_D_80A,
+	SWITCH_E_RESERVE,
+	SWITCH_F_SLAVE
+};
+
+enum SHARING_COMMAND
+{
+	SHARING_CMD_QUERY_SHARING=0x01,
+	SHARING_CMD_SYNC_INFO=0x81,
+	SHARING_CMD_CONNECTION_FULL=0xfd,
+	SHARING_CMD_CHKSUM_ERROR=0xfe,
+	SHARING_CMD_UNKNOWN=0xff
+};
+
+struct Message
+{
+	int			size;
+	uint8_t		buffer[2048];
+};
+
+struct CONNECTION_INFO
+{
+	int 		socketFd;					// Socket file description
+	uint16_t	availableSharingCurrent;	// Each connection available sharing current, resolution: 0.1A
+	uint16_t	presentOutputCurrent;		// Each connection preset output current, resolution: 0.1A
+	uint16_t	SOC;						// Each connection preset SOC, resolution: 0.1%
+	uint16_t	remindTime;					// Each connection remind charging time, resolution: 1min
+	time_t		lastHeartBeatTime;			// Each connection latest get heart beat start time
+	uint8_t		isConnected:1;				// Each connection connected flag
+	uint8_t 	isCharging:1;				// Each connection charging state flag
+};
+
+struct POWER_SHARING
+{
+	uint8_t					connectedQty;
+	struct CONNECTION_INFO	Connection_Info[CONNECTION_LIMIT];
+};
+
+#endif /* MODULE_POWERSHARING_H_ */

+ 228 - 145
EVSE/Projects/AW-CCS/Apps/main.c

@@ -256,6 +256,38 @@ unsigned int isKernelSupportNAT()
 
 	return result;
 }
+
+int getEth0MacAddress()
+{
+	int result = PASS;
+	FILE *fp;
+	char cmd[256];
+	char buf[512];
+	char tmp[512];
+
+	strcpy(cmd, "ifconfig eth0");
+	fp = popen(cmd, "r");
+	if(fp != NULL)
+	{
+		while(fgets(buf, sizeof(buf), fp) != NULL)
+		{
+			if(strstr(buf, "eth0") > 0)
+			{
+				result = PASS;
+			}
+
+			if(strstr(buf, "eth0      Link encap:Ethernet  HWaddr") > 0)
+			{
+				sscanf(buf, "%*s%*s%*s%*s%s", tmp);
+				strcpy((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, tmp);
+			}
+		}
+	}
+	pclose(fp);
+
+	return result;
+}
+
 //======================================================
 // OCPP routine
 //======================================================
@@ -345,11 +377,26 @@ void ocpp_boot_info_sync()
 		memcpy((char*)ShmOCPP16Data->ChargeBoxId, (char*)ShmSysConfigAndInfo->SysConfig.ChargeBoxId, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.ChargeBoxId));
 		sprintf((char*)ShmOCPP16Data->BootNotification.CpFwVersion, (char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
 		sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterSerialNumber, "N/A");
-		sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "AC");
 
-		DEBUG_INFO("CpFwVersion: %s\n",ShmOCPP16Data->BootNotification.CpFwVersion);
-		DEBUG_INFO("CpMeterSerialNumber: %s\n",ShmOCPP16Data->BootNotification.CpMeterSerialNumber);
-		DEBUG_INFO("CpMeterType: %s\n",ShmOCPP16Data->BootNotification.CpMeterType);
+		switch(ShmSysConfigAndInfo->SysConfig.ModelName[3])
+		{
+			case 'M':
+			case 'Z':
+				sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "MID");
+				break;
+			case 'P':
+				sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "PTB");
+				break;
+			case 'I':
+				sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "TIC");
+				break;
+			case 'U':
+				sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "UL");
+				break;
+			default:
+				sprintf((char*)ShmOCPP16Data->BootNotification.CpMeterType, "N/A");
+				break;
+		}
 	}
 	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
 	{
@@ -431,8 +478,10 @@ uint8_t ocpp_get_remotestop(uint8_t gun_index)
 	return result;
 }
 
-void ocpp_set_auth_req(uint8_t status)
+void ocpp_set_auth_req(uint8_t status, ...)
 {
+	va_list args;
+
 	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
 	{
 		if(ShmOCPP16Data->SpMsg.bits.AuthorizeReq != status)
@@ -448,7 +497,12 @@ void ocpp_set_auth_req(uint8_t status)
 		if(ShmOCPP20Data->SpMsg.bits.AuthorizeReq != status)
 		{
 			if(status == ON)
+			{
 				memset(&ShmOCPP20Data->Authorize.Response_idTokenInfo, 0x00, sizeof(struct IdTokenInfoType));
+				va_start(args, status);
+				sprintf((char*)ShmOCPP20Data->Authorize.idToken.type, "%s", va_arg(args, char*));
+				va_end(args);
+			}
 
 			ShmOCPP20Data->SpMsg.bits.AuthorizeReq = status;
 		}
@@ -621,6 +675,33 @@ void ocpp_copy_userid_to_starttransaction(uint8_t gun_index)
 	}
 }
 
+uint8_t ocpp_get_starttransaction_result(uint8_t gun_index)
+{
+	uint8_t result = PASS;
+
+	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+	{
+		if((strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Blocked")==0) ||
+		   (strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Expired")==0) ||
+		   (strcmp((char*)ShmOCPP16Data->StartTransaction[gun_index].ResponseIdTagInfo.Status, "Invalid")==0))
+			result = NO;
+	}
+	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+	{
+		if((strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Blocked")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Expired")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Invalid")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NoCredit")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAllowedTypeEVSE")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisLocation")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "NotAtThisTime")==0) ||
+		   (strcmp((char*)ShmOCPP20Data->TransactionEvent[gun_index].Response_idTokenInfo.status, "Unknown")==0))
+			result = NO;
+	}
+
+	return result;
+}
+
 uint8_t ocpp_get_smartcharging_profileId(uint8_t gun_index)
 {
 	uint8_t result = 0;
@@ -1049,7 +1130,8 @@ int DB_Open(sqlite3 *db)
 						  "socStart text, "
 						  "socStop text, "
 						  "chargeEnergy text, "
-						  "stopReason text"
+						  "stopReason text, "
+						  "finalCost text"
 						  ");";
 
 	char* createCfgSql="CREATE TABLE IF NOT EXISTS `config` ( "
@@ -1101,18 +1183,38 @@ int DB_Insert_Record(sqlite3 *db, int gun_index)
 	char* errMsg = NULL;
 	char sqlStr[1024];
 
-	sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason) "
-					   "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s');",
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
-					   ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
-					   ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
-					   ShmOCPP16Data->StopTransaction[gun_index].StopReason);
+	if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+	{
+		sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) "
+ 					    "values('%d', '%d', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%s');",
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
+					    ShmOCPP16Data->StartTransaction[gun_index].ResponseTransactionId,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
+					    ShmOCPP16Data->StopTransaction[gun_index].StopReason,
+					    ShmOCPP16Data->Cost.FinalCost[gun_index].description);
+	}
+	else if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_20)
+	{
+		sprintf(sqlStr, "insert into charging_record(reservationId, transactionId, startMethod, userId, dateTimeStart, dateTimeStop, socStart, socStop, chargeEnergy, stopReason, finalCost) "
+ 					    "values('%d', '%s', '%d', '%s', '%s', '%s', '%d', '%d', '%f', '%s', '%f');",
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].ReservationId,
+					    ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.transactionId,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartMethod,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartUserId,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StartDateTime,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].StopDateTime,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].EvBatterySoc,
+					    ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy,
+					    ShmOCPP20Data->TransactionEvent[gun_index].transactionInfo.stoppedReason,
+					    ShmOCPP20Data->CostUpdated.totalCost);
+	}
 
 	if(sqlite3_open(DB_FILE, &db))
 	{
@@ -1583,7 +1685,7 @@ void InitEthernet()
 	system(tmpbuf);
 	system("ifconfig lo up &");
 	system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &");
-	system("/sbin/ethtool -s eth0 speed 10 duplex full autoneg off");
+	//system("/sbin/ethtool -s eth0 speed 10 duplex full autoneg off");
 
     //Run DHCP client if enabled
 	system("killall udhcpc");
@@ -1601,6 +1703,9 @@ void InitEthernet()
 	sprintf(tmpbuf, "echo %s > /etc/hostname", ShmSysConfigAndInfo->SysConfig.SystemId);
 	system(tmpbuf);
 
+	// Ethernet MAC address
+	getEth0MacAddress();
+
 	//check internet status
 	pid = fork();
 
@@ -1620,18 +1725,18 @@ void InitEthernet()
 					system(tmpbuf);
 				}
 				else
-                                {
-                                        system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
-                                        memset(tmpbuf,0,256);
-                                        sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up &",
-                                                ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,
-                                                ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress);
-                                        system(tmpbuf);
-                                        memset(tmpbuf,0,256);
-                                        sprintf(tmpbuf,"route add default gw %s eth0 &",
-                                        ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);
-                                        system(tmpbuf);
-                                }
+				{
+					system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
+					memset(tmpbuf,0,256);
+					sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up &",
+							ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,
+							ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress);
+					system(tmpbuf);
+					memset(tmpbuf,0,256);
+					sprintf(tmpbuf,"route add default gw %s eth0 &",
+					ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);
+					system(tmpbuf);
+				}
 			}
 
 			if(isReachableInternet() == PASS)
@@ -1760,15 +1865,8 @@ void InitEthernet()
 
 int SpawnTask()
 {
-	system ("pkill Module_4g");
-	system ("pkill Module_Wifi");
-	system ("pkill Module_EventLogging");
+	system ("pkill Module_");
 	system ("pkill OcppBackend");
-	system ("pkill Module_AlarmDetect");
-	system ("pkill Module_InternalComm");
-	system ("pkill Module_Speaker");
-	system ("pkill Module_ProduceUtils");
-	system ("pkill Module_LcmControl");
 
 	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D'))
 	{
@@ -1780,6 +1878,7 @@ int SpawnTask()
 	}
 
 	system("/root/Module_EventLogging &");
+
 	if(strcmp((char *)&ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0)
 	{
 		ocpp_process_start();
@@ -2023,7 +2122,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.45.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.47.00.0000.00");
 
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
@@ -2843,40 +2942,6 @@ int isValidLocalWhiteCard()
 	return result;
 }
 
-//==========================================
-// Get Ethernet MAC address
-//==========================================
-int getEth0MacAddress()
-{
-	int result = PASS;
-	FILE *fp;
-	char cmd[256];
-	char buf[512];
-	char tmp[512];
-
-	strcpy(cmd, "ifconfig eth0");
-	fp = popen(cmd, "r");
-	if(fp != NULL)
-	{
-		while(fgets(buf, sizeof(buf), fp) != NULL)
-		{
-			if(strstr(buf, "eth0") > 0)
-			{
-				result = PASS;
-			}
-
-			if(strstr(buf, "eth0      Link encap:Ethernet  HWaddr") > 0)
-			{
-				sscanf(buf, "%*s%*s%*s%*s%s", tmp);
-				strcpy((char*)ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthMacAddress, tmp);
-			}
-		}
-	}
-	pclose(fp);
-
-	return result;
-}
-
 //==========================================
 // Check routine
 //==========================================
@@ -2955,6 +3020,19 @@ void checkTask()
 		DEBUG_INFO("Module_LcmControl not running, restart it.\n");
 		system ("/root/Module_LcmControl &");
 	}
+
+	if(system("pidof -s Module_PowerSharing > /dev/null") != 0)
+	{
+		DEBUG_INFO("Module_PowerSharing not running, restart it.\n");
+		system ("/root/Module_PowerSharing &");
+	}
+
+	if((system("pidof -s Module_InitUpgrade > /dev/null") != 0) &&
+		ShmSysConfigAndInfo->SysConfig.isReqFirstUpgrade)
+	{
+		DEBUG_INFO("Module_InitUpgrade not running, restart it.\n");
+		system ("/root/Module_InitUpgrade &");
+	}
 }
 
 void checkConnectionTimeout()
@@ -2994,6 +3072,7 @@ void checkReset()
 				sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted");
 				ShmOCPP16Data->MsMsg.bits.ResetConf = ON;
 
+				DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP16Data->Reset.Type);
 				if(strcmp((char*)ShmOCPP16Data->Reset.Type, "Hard") == 0)
 				{
 					system("sync");
@@ -3019,11 +3098,13 @@ void checkReset()
 			   (AC_QUANTITY>1?(!isMode(1, SYS_MODE_CHARGING) && !isMode(1, SYS_MODE_TERMINATING)  && !isMode(0, SYS_MODE_COMPLETE)):TRUE))
 			{
 				ShmOCPP20Data->MsMsg.bits.ResetReq = OFF;
-				sprintf((char*)ShmOCPP16Data->Reset.ResponseStatus, "Accepted");
+				sprintf((char*)ShmOCPP20Data->Reset.Response_status, "Accepted");
 				ShmOCPP20Data->MsMsg.bits.ResetConf = ON;
 
+				DEBUG_INFO("%s reset request by OCPP.\n", ShmOCPP20Data->Reset.type);
 				if(strcmp((char*)ShmOCPP20Data->Reset.type, "Immediate") == 0)
 				{
+
 					system("sync");
 					sleep(5);
 					system("reboot -f");
@@ -3178,7 +3259,7 @@ void checkChargingProfileLimit(uint8_t gun_index)
 						   ((idx_period == 0) || (ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].StartPeriod > 0))
 						  )
 						{
-							ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/220:ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
+							ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingRateUnit,"W")==PASS?ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit/(220*ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].NumberPhases):ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod[idx_period].Limit);
 							DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
 						}
 						else
@@ -3221,13 +3302,13 @@ void checkChargingProfileLimit(uint8_t gun_index)
 					(mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingProfilePurpose, "TxProfile") == FAIL))
 				{
 					// Checking limitation
-					for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP16Data->SmartChargingProfile[gun_index].ChargingSchedule.ChargingSchedulePeriod);idx_period++)
+					for(uint8_t idx_period=0;idx_period<ARRAY_SIZE(ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod);idx_period++)
 					{
 						if((getScheduleStart(gun_index) > ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod) &&
 						   ((idx_period == 0) || (ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].startPeriod > 0))
 						  )
 						{
-							ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/220:ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit);
+							ShmCharger->gun_info[gun_index].targetCurrent = (mystrcmp((char*)ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingRateUnit,"W")==PASS?ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit/(220*ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].numberPhases):ShmOCPP20Data->SmartChargingProfile[gun_index].chargingSchedule[0].chargingSchedulePeriod[idx_period].limit);
 							DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent on period[%d]: %d\n", gun_index, idx_period, ShmCharger->gun_info[gun_index].targetCurrent);
 						}
 						else
@@ -3395,12 +3476,14 @@ void checkRemoteUpgradeStatus()
 	}
 }
 
-//===============================================
+//======================================================
 // Main process
-//===============================================
+//======================================================
 int main(void)
 {
-	//Create all share memory
+	//==================================================
+	// Create all share memory
+	//==================================================
 	if(CreatShareMemory()==0)
 	{
 		DEBUG_ERROR("CreatShareMemory NG\n");
@@ -3423,44 +3506,38 @@ int main(void)
 		ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PreviousSystemStatus = 0xff;
 		ShmCharger->gun_info[gun_index].primaryMcuState.rotatory_switch = 0xff;
 		ShmCharger->gun_info[gun_index].mcuResetRequest.isMcuResetRequest = ON;
-		ShmCharger->gun_info[gun_index].isInitialPass = NO;
 		ShmCharger->gun_info[gun_index].isSetBreatheLedTiming = OFF;
 		ShmCharger->gun_info[gun_index].isSetLedBrightness = OFF;
 	}
 
+	//==================================================
 	// Main loop
+	//==================================================
 	for(;;)
 	{
-		//==========================================
+		//==============================================
 		// Synchronize share memory from OCPP struct
-		//==========================================
+		//==============================================
 		ShmSysConfigAndInfo->SysInfo.OcppConnStatus = ocpp_get_connection_status();
 
-		//==========================================
-		// Ethernet MAC address
-		//==========================================
-		getEth0MacAddress();
-
-		//==========================================
+		//==============================================
 		// Check task processing
-		//==========================================
+		//==============================================
 		if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
 			checkTask();
 
-		//==========================================
+		//==============================================
 		// Check connection timeout specification
-		//==========================================
+		//==============================================
 		checkConnectionTimeout();
 
-		//==========================================
+		//==============================================
 		// Something need run in Idle mode
-		//==========================================
+		//==============================================
 		if(((ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus==SYS_MODE_ALARM)) &&
 		   (AC_QUANTITY>1?((ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_IDLE) || (ShmSysConfigAndInfo->SysInfo.AcChargingData[1].SystemStatus==SYS_MODE_ALARM)):true))
 		{
-			//======================================
 			// Check restore factory setting request
-			//======================================
 			if(ShmSysConfigAndInfo->SysInfo.FactoryConfiguration)
 			{
 				// Set led to initial
@@ -3478,9 +3555,7 @@ int main(void)
 				system("reboot -f");
 			}
 
-			//======================================
 			// Check upgrade firmware request
-			//======================================
 			if(ShmSysConfigAndInfo->SysInfo.FirmwareUpdate ||
 			   ocpp_get_update_firmware_req())
 			{
@@ -3500,14 +3575,14 @@ int main(void)
 			}
 		}
 
-		//==========================================
+		//==============================================
 		// Check remote reset request
-		//==========================================
+		//==============================================
 		checkReset();
 
-		//==========================================
+		//==============================================
 		// Check RFID
-		//==========================================
+		//==============================================
 		if(!ShmCharger->gun_info[ShmCharger->gun_selectd].rfidReq)
 		{
 			if(GetCardSerialNumber()!= FAIL)
@@ -3516,9 +3591,9 @@ int main(void)
 			}
 		}
 
-		//==========================================
+		//==============================================
 		// Connector loop
-		//==========================================
+		//==============================================
 		for(int gun_index = 0;gun_index<AC_QUANTITY;gun_index++)
 		{
 			//==========================================
@@ -3573,55 +3648,50 @@ int main(void)
 				}
 			}
 
+			//==========================================
 			// Synchronize current rating value from MCU
+			//==========================================
 			ShmSysConfigAndInfo->SysConfig.RatingCurrent = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 
+			//==========================================
 			// Assign connector location index for OCPP
+			//==========================================
 			ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].Index = gun_index;
 
+			//==========================================
 			// Synchronize present charging power
+			//==========================================
 			if(ShmCharger->gun_info[gun_index].primaryMcuState.relay_state == ON)
 				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = (ShmSysConfigAndInfo->SysInfo.InputVoltageR* ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingCurrent)/1000;
 			else
 				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargingPower = 0;
 
-			// The system switch to Booting mode
-			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == 0XFF)
-			{
-				setChargerMode(gun_index, SYS_MODE_BOOTING);
-			}
-
+			//==========================================
 			// Check initialization "PASS" or "FAIL"
-			if(ShmCharger->gun_info[gun_index].isInitialPass == YES)
+			//==========================================
+			if(ShmSysConfigAndInfo->SysInfo.AcChargingData[0].SystemStatus != SYS_MODE_BOOTING)
 			{
 				// Alarm event check
 				if((ShmCharger->gun_info[gun_index].primaryMcuAlarm.InputAlarmCode>0))
 				{
 					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_ALARM)
 					{
-						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_UPDATE)
-						{
-
-						}
-						else
+						if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus != SYS_MODE_UPDATE)
 						{
 							setChargerMode(gun_index, SYS_MODE_ALARM);
 						}
 					}
 				}
-				else
-				{
-					if(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus == SYS_MODE_ALARM)
-					{
-
-					}
-				}
 			}
 
+			//==========================================
 			// Reservation request check
+			//==========================================
 			checkReservation(gun_index);
 
+			//==========================================
 			// Change availability check
+			//==========================================
 			checkAvailability(gun_index);
 
 			if(ShmCharger->gun_info[gun_index].isOperactive)
@@ -3639,10 +3709,14 @@ int main(void)
 				}
 			}
 
+			//==========================================
 			// Unlock Connector signal check
+			//==========================================
 			checkUnlocker(gun_index);
 
+			//==========================================
 			// Connector process
+			//==========================================
 			switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].SystemStatus)
 			{
 				case SYS_MODE_BOOTING:
@@ -3688,9 +3762,6 @@ int main(void)
 						DEBUG_INFO("Wifi password: %s\n",  ShmSysConfigAndInfo->SysConfig.AthInterface.WifiPassword);
 						DEBUG_INFO("==========================================\n");
 
-						// Flag for initialization system success
-						ShmCharger->gun_info[gun_index].isInitialPass = YES;
-
 						// Set max current to rating current
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = ShmCharger->gun_info[gun_index].primaryMcuState.rating_current;
 						
@@ -3731,6 +3802,7 @@ int main(void)
 						ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop = OFF;
 						ocpp_set_remotestart(gun_index, OFF);
 						ocpp_set_remotestop(gun_index, OFF);
+						ocpp_set_auth_conf(OFF);
 
 						ShmCharger->gun_info[gun_index].systemAlarmCode.SystemAlarmCode = 0x00;
 						ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration = 0;
@@ -3850,7 +3922,7 @@ int main(void)
 									if(ocpp_get_connection_status())
 									{
 										// On line
-										ocpp_set_auth_req(ON);
+										ocpp_set_auth_req(ON, "ISO14443");
 										setLedMotion(gun_index,LED_ACTION_AUTHED);
 									}
 									else
@@ -3859,7 +3931,7 @@ int main(void)
 										switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy)
 										{
 											case OFF_POLICY_LOCALLIST:
-												ocpp_set_auth_req(ON);
+												ocpp_set_auth_req(ON, "ISO14443");
 												break;
 											case OFF_POLICY_PH_RFID:
 												break;
@@ -4320,7 +4392,8 @@ int main(void)
 
 					if((ShmCharger->gun_info[gun_index].rfidReq == ON) ||
 					   (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) ||
-					   ocpp_get_remotestop(gun_index)||
+					   ocpp_get_remotestop(gun_index) ||
+					   (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) ||
 					   ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState != CP_STATE_C) ||
 					   ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && !ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) ||
 					   ocpp_get_reset_req() ||
@@ -4393,7 +4466,7 @@ int main(void)
 												if(ocpp_get_connection_status())
 												{
 													// On line
-													ocpp_set_auth_req(ON);
+													ocpp_set_auth_req(ON, "ISO14443");
 												}
 												else
 												{
@@ -4401,7 +4474,7 @@ int main(void)
 													switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy)
 													{
 														case OFF_POLICY_LOCALLIST:
-															ocpp_set_auth_req(ON);
+															ocpp_set_auth_req(ON, "ISO14443");
 															break;
 														case OFF_POLICY_PH_RFID:
 															break;
@@ -4469,6 +4542,7 @@ int main(void)
 					}
 					else
 					{
+						// Charging session info calculation
 						setLedMotion(gun_index,LED_ACTION_CHARGING);
 						if(ShmSysConfigAndInfo->SysConfig.AcPhaseCount==1)
 							ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PowerConsumption = (ShmCharger->gun_info[gun_index].powerConsumptionTotal.power_consumption/100.0);
@@ -4510,6 +4584,12 @@ int main(void)
 						// Checking profile id > 0 and current time is between charging profile validFrom & validTo
 						checkChargingProfileLimit(gun_index);
 
+						// Charging session target current check if OCPP disconnect and power sharing server connected
+						if(!ocpp_get_connection_status() && ShmSysConfigAndInfo->SysInfo.localSharingInfo.isConnectedSharingServer)
+						{
+							ShmCharger->gun_info[gun_index].targetCurrent = ShmSysConfigAndInfo->SysInfo.localSharingInfo.AvailableShargingCurrent;
+						}
+
 						// Determine max charging current to MCU
 						if(ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent == 0)
 						{
@@ -4561,17 +4641,7 @@ int main(void)
 							}
 						}
 
-						// Debug information
-						if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT)
-						{
-							DEBUG_INFO("===============================================================\n");
-							DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent: %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
-							DEBUG_INFO("ShmCharger->gun_info[%d].primaryMcuCp_Pwn_Duty.max_current: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current);
-							DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent);
-							DEBUG_INFO("===============================================================\n");
-							ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]);
-						}
-
+						// Charging session local limit condition check
 						if(ocpp_get_connection_status())
 						{
 							// On-line max condition check
@@ -4685,6 +4755,17 @@ int main(void)
 								DEBUG_INFO("Connector-%d can not charging in off line\n", gun_index);
 							}
 						}
+
+						// Debug information
+						if(DiffTimebWithNow(startTime[gun_index][TMR_IDX_LOGPPRINTOUT]) > TIMEOUT_SPEC_LOGPPRINTOUT)
+						{
+							DEBUG_INFO("===============================================================\n");
+							DEBUG_INFO("ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent: %d \n", ShmSysConfigAndInfo->SysConfig.MaxChargingCurrent);
+							DEBUG_INFO("ShmCharger->gun_info[%d].primaryMcuCp_Pwn_Duty.max_current: %d\n", gun_index, ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current);
+							DEBUG_INFO("ShmCharger->gun_info[%d].targetCurrent: %d\n", gun_index, ShmCharger->gun_info[gun_index].targetCurrent);
+							DEBUG_INFO("===============================================================\n");
+							ftime(&startTime[gun_index][TMR_IDX_LOGPPRINTOUT]);
+						}
 					}
 
 					break;
@@ -4711,6 +4792,7 @@ int main(void)
 					   (ShmCharger->gun_info[gun_index].isAuthPassEnd) ||
 					   (ShmCharger->gun_info[gun_index].bleConfigData.isRequestStop == ON) ||
 					   ocpp_get_remotestop(gun_index) ||
+					   (ocpp_get_connection_status() && !ocpp_get_starttransaction_result(gun_index)) ||
 					   ((ShmCharger->gun_info[gun_index].chargingMode != CHARGING_MODE_SOCKETE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_A) && ocpp_get_StopTransactionOnEVSideDisconnect()) ||
 					   ((ShmCharger->gun_info[gun_index].chargingMode == CHARGING_MODE_SOCKETE) && !ShmCharger->gun_info[gun_index].primaryMcuState.socket_e.isSocketEPinOn) ||
 					   ocpp_get_reset_req() ||
@@ -4829,7 +4911,7 @@ int main(void)
 												if(ocpp_get_connection_status())
 												{
 													// On line
-													ocpp_set_auth_req(ON);
+													ocpp_set_auth_req(ON, "ISO14443");
 												}
 												else
 												{
@@ -4837,7 +4919,7 @@ int main(void)
 													switch(ShmSysConfigAndInfo->SysConfig.OfflinePolicy)
 													{
 														case OFF_POLICY_LOCALLIST:
-															ocpp_set_auth_req(ON);
+															ocpp_set_auth_req(ON, "ISO14443");
 															break;
 														case OFF_POLICY_PH_RFID:
 															break;
@@ -4897,6 +4979,7 @@ int main(void)
 						   !ocpp_get_remotestop(gun_index) &&
 						   (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop != ON) &&
 						   !ocpp_get_reset_req() &&
+						   ocpp_get_starttransaction_result(gun_index) &&
 						   !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60))) &&
 						   !(ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedEnergy >= ((float)ShmSysConfigAndInfo->SysConfig.MaxChargingEnergy))) &&
 						   !(!ocpp_get_connection_status() && (ShmSysConfigAndInfo->SysConfig.OfflinePolicy != OFF_POLICY_NOCHARGE) && ((ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration > 0) ? (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.OfflineMaxChargeDuration*60)) : (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration > 0) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PresentChargedDuration >= (ShmSysConfigAndInfo->SysConfig.MaxChargingDuration*60)))) &&

+ 71 - 73
EVSE/Projects/AW-CCS/Apps/main.h

@@ -42,49 +42,6 @@
 #include	<sqlite3.h>
 
 
-//===================================
-//	Define CP State constant
-//===================================
-#define CP_STATE_UNKNOWN			0
-#define CP_STATE_A					1
-#define CP_STATE_B					2
-#define CP_STATE_C					3
-#define CP_STATE_D					4
-#define CP_STATE_E					5
-#define CP_STATE_F					6
-
-//===================================
-//	Define CCS CP State constant
-//===================================
-#define CCS_CP_STATE_UNKNOWN			0
-#define CCS_CP_STATE_A					1	//A (12V, no PWM)
-#define CCS_CP_STATE_B1					2	//B1 (9V, no PWM)
-#define CCS_CP_STATE_B2					3	//B2 (9V, with PWM)
-#define CCS_CP_STATE_C					4	//C (6V, with PWM)
-#define CCS_CP_STATE_D					5	//D (3V, with PWM)
-#define CCS_CP_STATE_E					6	//E (0V, no PWM)
-#define CCS_CP_STATE_F					7	//F (-12V, no PWM)
-#define CCS_CP_STATE_G					8	//G (>12V)
-#define CCS_CP_STATE_H					9	//H  (<12V)
-
-//===================================
-// Define start mode constant
-//===================================
-#define START_METHOD_FREE	 		0
-#define START_METHOD_RFID	 		1
-#define START_METHOD_BACKEND 		2
-#define START_METHOD_BLE	 		3
-
-//===================================
-// Define Speaker type constant
-//===================================
-#define SPEAKER_STOP				0
-#define SPEAKER_ALWAYS_ON			1
-#define SPEAKER_SHORT				2
-#define SPEAKER_LONG				3
-#define SPEAKER_INTERVAL_SHORT		4
-#define SPEAKER_INTERVAL_LONG		5
-#define SPEAKER_INTERVAL_3COUNT		6
 
 //===================================
 // Define Alarm code constant
@@ -120,41 +77,82 @@
 #define ALARM_L3_OVER_CURRENT					0x02000000
 #define ALARM_L2_CIRCUIT_SHORT                  0x04000000 
 #define ALARM_L3_CIRCUIT_SHORT                  0x08000000
-
 #define ALARM_METER_TIMEOUT						0x10000000
 
-
-//===================================
-// Define Led constant
-//===================================
-#define LED_ACTION_INIT             	0
-#define LED_ACTION_IDLE             	1
-#define LED_ACTION_AUTHED           	2
-#define LED_ACTION_CONNECTED        	3
-#define LED_ACTION_CHARGING         	4
-#define LED_ACTION_STOP             	5
-#define LED_ACTION_ALARM            	6
-#define LED_ACTION_MAINTAIN         	7
-#define LED_ACTION_RFID_PASS        	8
-#define LED_ACTION_RFID_FAIL        	9
-#define LED_ACTION_BLE_CONNECT      	10
-#define LED_ACTION_BLE_DISABLE      	11
-#define LED_ACTION_DEBUG            	12
-#define LED_ACTION_ALL_OFF          	13
-#define LED_RELAY_ON               	 	14
-#define LED_RELAY_OFF               	15
-#define LED_ACTION_HANDSHAKE_FAIL   	16
-#define LED_ACTION_INTERNET_DISCONNECT	17
-
 //=================================
 //CCS related define
 //=================================
-//#define CCS_SIMULATION_DATA
+#define CCS_PWM_DUTY_CP_STATE_F					0
+#define CCS_PWM_DUTY_CP_STATE_E					1
+#define CCS_PWM_DUTY_5							5
+#define CCS_PWM_DUTY_100						100
+
+
+enum CP_STATE
+{
+	CP_STATE_UNKNOWN=0,
+	CP_STATE_A,
+	CP_STATE_B,
+	CP_STATE_C,
+	CP_STATE_D,
+	CP_STATE_E,
+	CP_STATE_F
+};
+
+enum CCS_CP_STATE
+{
+	CCS_CP_STATE_UNKNOWN=0,
+	CCS_CP_STATE_A,				//A (12V, no PWM)
+	CCS_CP_STATE_B1,			//B1 (9V, no PWM)
+	CCS_CP_STATE_B2,			//B2 (9V, with PWM)
+	CCS_CP_STATE_C,				//C (6V, with PWM)
+	CCS_CP_STATE_D,				//D (3V, with PWM)
+	CCS_CP_STATE_E,				//E (0V, no PWM)
+	CCS_CP_STATE_F,				//F (-12V, no PWM)
+	CCS_CP_STATE_G,				//G (>12V)
+	CCS_CP_STATE_H				//H  (<12V)
+};
 
-#define CCS_PWM_DUTY_CP_STATE_F			0	
-#define CCS_PWM_DUTY_CP_STATE_E			1		
-#define CCS_PWM_DUTY_5					5
-#define CCS_PWM_DUTY_100				100
+enum SPEAKER_ACTION
+{
+	SPEAKER_STOP=0,
+	SPEAKER_ALWAYS_ON,
+	SPEAKER_SHORT,
+	SPEAKER_LONG,
+	SPEAKER_INTERVAL_SHORT,
+	SPEAKER_INTERVAL_LONG,
+	SPEAKER_INTERVAL_3COUNT
+};
+
+enum LED_ACTION
+{
+	LED_ACTION_INIT=0,
+	LED_ACTION_IDLE,
+	LED_ACTION_AUTHED,
+	LED_ACTION_CONNECTED,
+	LED_ACTION_CHARGING,
+	LED_ACTION_STOP,
+	LED_ACTION_ALARM,
+	LED_ACTION_MAINTAIN,
+	LED_ACTION_RFID_PASS,
+	LED_ACTION_RFID_FAIL,
+	LED_ACTION_BLE_CONNECT,
+	LED_ACTION_BLE_DISABLE,
+	LED_ACTION_DEBUG,
+	LED_ACTION_ALL_OFF,
+	LED_RELAY_ON,
+	LED_RELAY_OFF,
+	LED_ACTION_HANDSHAKE_FAIL,
+	LED_ACTION_INTERNET_DISCONNECT
+};
+
+enum START_METHOD
+{
+	START_METHOD_FREE=0,
+	START_METHOD_RFID,
+	START_METHOD_BACKEND,
+	START_METHOD_BLE
+};
 
 enum HANDSHAKE_STATE
 {
@@ -686,7 +684,6 @@ typedef struct GUN_INFO
 	uint16_t										isAuthPassEnd:1;
 	uint16_t										rfidReq:1;
 	uint16_t										isGunPlugged:1;
-	uint16_t										isInitialPass:1;
 	uint16_t										isSetBreatheLedTiming:1;
 	uint16_t										isSetLedBrightness:1;
 	uint16_t										isUnlockerConnetor:1;
@@ -697,6 +694,7 @@ typedef struct GUN_INFO
 	uint16_t										isDoEvReadyOnce:1;
 	uint16_t										isChargerStopByCondition:1;
 	uint16_t										isMeterOn:1;
+	uint16_t										:3;
 }Gun_Info;
 
 struct Charger

+ 107 - 0
EVSE/Projects/AW-Regular/Apps/Module_Debug.c

@@ -40,6 +40,8 @@
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
+struct OCPP16Data				*ShmOCPP16Data;
+struct OCPP20Data				*ShmOCPP20Data;
 struct Charger					*ShmCharger;
 
 int StoreLogMsg(const char *fmt, ...)
@@ -113,6 +115,30 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
+	// Initial ShmOCPP16Data
+	if ((MeterSMId = shmget(ShmOcppModuleKey, sizeof(struct OCPP16Data), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP16Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP16Data NG\n");
+		result = FAIL;
+	}
+
+	// Initial ShmOCPP20Data
+	if ((MeterSMId = shmget(ShmOcpp20ModuleKey, sizeof(struct OCPP20Data), 0777)) < 0)
+	{
+		DEBUG_ERROR("shmget ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+	else if ((ShmOCPP20Data = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		DEBUG_ERROR("shmat ShmOCPP20Data NG\n");
+		result = FAIL;
+	}
+
 	//Initial ShmCharger
 	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
 	{
@@ -165,6 +191,7 @@ int main(void)
 		memset(cmd, 0x00, ARRAY_SIZE(cmd));
 		printf("\n ============== Debug main menu ==================");
 		printf("\n  info: List charger status info.");
+		printf("\n  test: Charger test command.");
 		printf("\n  exit: Exit Module_Debug_Test.");
 		printf("\n =================================================");
 		printf("\n  Please input debug command: ");
@@ -195,14 +222,26 @@ int main(void)
 
 					gun_index = gun_index<AC_QUANTITY?gun_index:0;
 
+					printf("\n  CSU u-boot version: %s", ShmSysConfigAndInfo->SysInfo.CsuBootLoadFwRev);
+					printf("\n  CSU kernel version: %s", ShmSysConfigAndInfo->SysInfo.CsuKernelFwRev);
+					printf("\n  CSU rootfs version: %s", ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger connector plug times: %d", ShmCharger->gun_info[gun_index].gunPluginTimes.GunPluginTimes);
+					printf("\n --------------------------------------------------");
 					printf("\n  CP positive voltage: %.2f", ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltagePositive);
 					printf("\n  CP negative voltage: %.2f", ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltageNegative);
+					printf("\n --------------------------------------------------");
 					printf("\n  CSU to MCU legacyRequest: %d", ShmCharger->gun_info[gun_index].legacyRequest.isLegacyRequest);
 					printf("\n  CSU to MCU relay on request: %d", ShmCharger->gun_info[gun_index].legacyRequest.isRelayOn);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger charging mode BS/HLC: %d", ShmCharger->gun_info[gun_index].chargingMode);
+					printf("\n --------------------------------------------------");
 					printf("\n  Charger input voltage L1: %.2f", ShmCharger->gun_info[gun_index].inputVoltage.L1N_L12);
+					printf("\n --------------------------------------------------");
 					printf("\n  CSU output current L1: %.2f", ShmCharger->gun_info[gun_index].outputCurrent.L1N_L12[0]);
+					printf("\n --------------------------------------------------");
+					printf("\n  CSU power total consumption: %.2f", (ShmCharger->gun_info[gun_index].powerConsumption.power_consumption/100.0));
+					printf("\n --------------------------------------------------");
 					printf("\n  CSU temperature: %d", ShmCharger->gun_info[gun_index].temperature.point[0]);
 
 					wait();
@@ -213,7 +252,9 @@ int main(void)
 					scanf("%d", &gun_index);
 					printf("\n  MCU info.\n\n");
 
+					gun_index = gun_index<AC_QUANTITY?gun_index:0;
 
+					printf("\n  Firmware version: %s", ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 					wait();
 				}
@@ -224,6 +265,72 @@ int main(void)
 				}
 			}while(!isExit);
 		}
+		else if(strcmp(cmd, "test") == 0)
+		{
+			int gun_index;
+
+			memset(cmd, 0x00, ARRAY_SIZE(cmd));
+			printf("\n ***************** Info menu *********************");
+			printf("\n  start: start charging session");
+			printf("\n  stop: stop charging session");
+			printf("\n  operative: enable charger gun");
+			printf("\n  inoperative: disable charger gun");
+			printf("\n  exit: exit to previous menu.");
+			printf("\n *************************************************");
+			printf("\n  Please input command: ");
+			scanf("%s", &cmd[0]);
+
+			if(strcmp(cmd, "start") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStart = ON;
+			}
+			else if(strcmp(cmd, "stop") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].schedule.isTriggerStop = ON;
+			}
+			else if(strcmp(cmd, "operative") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+				{
+					sprintf((char*)ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Operative");
+					ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+				else
+				{
+					sprintf((char*)(char*)ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Operative");
+					ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+			}
+			else if(strcmp(cmd, "inoperative") == 0)
+			{
+				printf("\n  Please input gun index: ");
+				scanf("%d", &gun_index);
+
+				if(ShmSysConfigAndInfo->SysInfo.OcppRunningVer == OCPP_RUNNING_VERSION_16)
+				{
+					sprintf((char*)ShmOCPP16Data->ChangeAvailability[gun_index].Type, "Inoperative");
+					ShmOCPP16Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+				else
+				{
+					sprintf((char*)(char*)ShmOCPP20Data->ChangeAvailability[gun_index].operationalStatus, "Inoperative");
+					ShmOCPP20Data->CsMsg.bits[gun_index].ChangeAvailabilityReq = ON;
+				}
+			}
+			else if(strcmp(cmd, "exit") == 0)
+			{
+				printf("\n  Exit to previous.\n\n");
+			}
+		}
 		else if(strcmp(cmd, "exit") == 0)
 		{
 			printf("\n  exit program.\n\n");

+ 1 - 1
EVSE/Projects/AW-Regular/Apps/Module_FactoryConfig.c

@@ -323,7 +323,7 @@ int main(int argc, char *argv[])
 	SysConfig.OfflinePolicy = 2;			// 0: local list, 1: Phihong RFID tag, 2: free charging, 3: no charging
 	SysConfig.OfflineMaxChargeEnergy = 0;	// 0: Same as MaxChargeEnergy	Other: 1~65535KWH
 	SysConfig.OfflineMaxChargeDuration = 0; // 0: Same as MaxChargeDuration Other: 1~65535 minutes
-
+	//SysConfig.isReqFirstUpgrade = 1;		// 0: Skip first upgrade, 	1: Process first upgrade
 
 	// Customization configuration item
 	if(strstr((char*)&SysConfig.ModelName[12], "P0") != NULL)

+ 8 - 6
EVSE/Projects/AW-Regular/Apps/Module_InternalComm.c

@@ -15,12 +15,12 @@
 
 #include 	<unistd.h>
 #include 	<stdarg.h>
-#include  	<stdio.h>      /*標準輸入輸出定義*/
-#include  	<stdlib.h>     /*標準函數庫定義*/
-#include  	<unistd.h>     /*Unix 標準函數定義*/
-#include  	<fcntl.h>      /*檔控制定義*/
-#include  	<termios.h>    /*PPSIX 終端控制定義*/
-#include 	<errno.h>      /*錯誤號定義*/
+#include  	<stdio.h>
+#include  	<stdlib.h>
+#include  	<unistd.h>
+#include  	<fcntl.h>
+#include  	<termios.h>
+#include 	<errno.h>
 #include 	<errno.h>
 #include 	<string.h>
 #include	<time.h>
@@ -1824,6 +1824,8 @@ int main(void)
 					ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltagePositive = ShmCharger->gun_info[gun_index].primaryMcuState.cp_voltage_positive;
 					ShmCharger->gun_info[gun_index].PilotVoltage.PilotVoltageNegative = ShmCharger->gun_info[gun_index].primaryMcuState.cp_voltage_negtive;
 
+					ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].RelayK1K2Status = ShmCharger->gun_info[gun_index].primaryMcuState.relay_state;
+
 					failCount[gun_index] = 0;
 				}
 				else

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 871 - 57
EVSE/Projects/AW-Regular/Apps/main.c


+ 56 - 25
EVSE/Projects/DO360/Apps/Config.h

@@ -45,6 +45,8 @@ typedef unsigned char			byte;
 #define BOOTTING			0
 #define BOOT_COMPLETE		1
 
+#define SM_ChargerInfoKey           3000
+
 enum _SYSTEM_STATUS
 {
 	S_BOOTING = 						0,
@@ -95,21 +97,6 @@ enum _GUN_TYPE
 	_Type_Unknown = 0xFF
 };
 
-//enum _LCM_INDEX
-//{
-//	_LCM_INIT = 			0x00,
-//	_LCM_IDLE = 			0x01,
-//	_LCM_AUTHORIZING = 		0x04,
-//	_LCM_AUTHORIZ_COMP = 	0x05,
-//	_LCM_AUTHORIZ_FAIL = 	0x06,
-//	_LCM_WAIT_FOR_PLUG = 	0x07,
-//	_LCM_PRE_CHARGE = 		0x08,
-//	_LCM_CHARGING = 		0x09,
-//	_LCM_COMPLETE = 		0x0A,
-//	_LCM_FIX = 				0x0B,
-//	_LCM_NONE = 			0xFF,
-//};
-
 enum _LCM_INDEX
 {
 	_LCM_INIT = 			0x00,
@@ -130,19 +117,22 @@ enum _DispenserAuthorizeStatus
     _AuthorizeStatus_Idle   = 0x00,
     _AuthorizeStatus_Wait   = 0x01,
     _AuthorizeStatus_Busy   = 0x02,
-    _AuthorizeStatus_Pass   = 0x03,
-    _AuthorizeStatus_Fail   = 0x04,
+    _AuthorizeStatus_Done   = 0x03,
+    _AuthorizeStatus_End    = 0x04,
 };
 
-#define AUTHORIZE_SRC_NONE_DEV      "None  Src"
-#define AUTHORIZE_SRC_LOCAL_DEV     "Connector"
-#define AUTHORIZE_SRC_REMOTE_DEV    "Connector"
+enum _ConnectorAuthorizeResult
+{
+    _AuthResult_None    = 0x00,
+    _AuthResult_Valid   = 0x01,
+    _AuthResult_Invalid = 0x02,
+};
 
-enum _AuthorizeSource
+enum _AuthorizedType
 {
-    _AuthorizeSrc_None      = 0x00,
-    _AuthorizeSrc_Local     = 0x01,
-    _AuthorizeSrc_Remote    = 0x02,
+    _AuthType_None          = 0x00,
+    _AuthType_RFID          = 0x01,
+    _AuthType_RemoteStart   = 0x02,
 };
 
 enum _SELF_TEST_SEQ
@@ -203,7 +193,8 @@ enum _EXTRA_ERR_PROCESS
 {
 	_EXTRA_ERR_PROCESS_NONE = 0,
 	_EXTRA_ERR_PROCESS_INUVP = 1,
-	_EXTRA_ERR_PROCESS_INOVP = 2
+	_EXTRA_ERR_PROCESS_INOVP = 2,
+	_EXTRA_ERR_PROCESS_PRIMARY = 3,
 };
 
 enum _CHARGER_TYPE
@@ -241,4 +232,44 @@ enum _ETHERNET_USAGE
 	_ETHERNET_USAGE_3G_4g
 };
 
+enum _CONN_STATUS
+{
+    _Connnection_Disable = 0,
+    _Connnection_Connected = 1,
+    _Connnection_Disconnected = 2,
+};
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int AcContactor:1;                 // 0: ac contactor off,         1: ac contactor on
+        unsigned int AcContactorForceOff:1;         // 0: no effect,                1: ac contactor off
+        unsigned int StandbyCountdown:1;            // 0: charger is using,         1: start countdown
+        unsigned int res:29;
+    }bits;
+}RelayControl;
+
+typedef union
+{
+    unsigned int CtrlValue;
+    struct
+    {
+        unsigned int FailureResume:1;               // 0: no error,                 1: psu failure, need resume
+        unsigned int res:31;
+    }bits;
+}PsuControl;
+
+typedef struct
+{
+    RelayControl    RelayCtrl;
+    PsuControl      PsuCtrl;
+}SysControl;
+
+typedef struct
+{
+    SysControl Control;
+}ChargerInfoData;
+
 #endif /* CONFIG_H_ */

+ 142 - 50
EVSE/Projects/DO360/Apps/Module_EvComm.c

@@ -934,9 +934,10 @@ void ConnectorIDResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
-void PowerCabinetStatusResponse(int socket, struct PACKET_STRUCTURE *packet)
+void PowerCabinetStatusResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
 	struct PACKET_STRUCTURE sendBuffer;
+	unsigned char MiscEventCode[7];
 
 	memset(&sendBuffer, 0x00, sizeof(sendBuffer));
 	sendBuffer.Header.se = packet->Header.se;
@@ -959,6 +960,14 @@ void PowerCabinetStatusResponse(int socket, struct PACKET_STRUCTURE *packet)
 		}
 	}
 
+    if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.MiscNeedAnnouncement)
+    {
+        sendBuffer.Header.len += 6;
+        memset(MiscEventCode, 0, sizeof(MiscEventCode));
+        memcpy(MiscEventCode, "B40001", sizeof(MiscEventCode) - 1);
+        memcpy(&sendBuffer.Payload.data[1 + (ShmSysConfigAndInfo->SysWarningInfo.WarningCount * 6)], &MiscEventCode[0], 6);
+    }
+
 	send(socket, &sendBuffer, sendBuffer.Header.len + 4, 0);
 }
 
@@ -1290,6 +1299,46 @@ void MiscControlResponse(int socket, struct PACKET_STRUCTURE *packet, unsigned c
                 AddMiscCommand(&sendBuffer, &misc);
             }
 
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.BackendStatusRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.BackendStatusRequest = false;
+                misc.Command = _MiscCmd_BackendStatus;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.CabinetMicsStatus.BackendStatus;
+
+                PRINTF_FUNC("Announce Connector %d BackendStatus: %d", packet->Header.id, (misc.Value));
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.EthernetStatusRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.EthernetStatusRequest = false;
+                misc.Command = _MiscCmd_EthernetStatus;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.CabinetMicsStatus.EthernetStatus;
+
+                PRINTF_FUNC("Announce Connector %d EthernetStatus: %d", packet->Header.id, (misc.Value));
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.WiFiStatusRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.WiFiStatusRequest = false;
+                misc.Command = _MiscCmd_WiFiStatus;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.CabinetMicsStatus.WiFiStatus;
+
+                PRINTF_FUNC("Announce Connector %d WiFiStatus: %d", packet->Header.id, (misc.Value));
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
+            if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.TelcomModemStatusRequest)
+            {
+                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.TelcomModemStatusRequest = false;
+                misc.Command = _MiscCmd_4GStatus;
+                misc.Value = ShmSysConfigAndInfo->SysInfo.CabinetMicsStatus.TelcomModemStatus;
+
+                PRINTF_FUNC("Announce Connector %d TelcomModemStatus: %d", packet->Header.id, (misc.Value));
+                AddMiscCommand(&sendBuffer, &misc);
+            }
+
             if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.HardwareRebootRequest)
             {
                 ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.HardwareRebootRequest = false;
@@ -1486,27 +1535,20 @@ void ConnectorTypeBindingHandler(unsigned char dispenserIndex, unsigned char *ty
 
 BOOL IsAvailableDispenserIndexSequence(unsigned char index)
 {
-	if((ShmSysConfigAndInfo->SysInfo.DispenserInfo.CheckInLog.Status & (1 << index)) > 0)
-	{
-		// dispenser ever checkin
-		return true;
-	}
-	else
-	{
-		for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
-		{
-			if(i == index)
-			{
-				return true;
-			}
+    for(int i = 0; i < GENERAL_GUN_QUANTITY; i++)
+    {
+        if(i == index)
+        {
+            return true;
+        }
+
+        if((ShmSysConfigAndInfo->SysInfo.DispenserInfo.CheckInLog.Status & (1 << i)) == 0)
+        {
+            // i is not check in yet before index
+            return false;
+        }
+    }
 
-			if((ShmSysConfigAndInfo->SysInfo.DispenserInfo.CheckInLog.Status & (1 << index)) == 0)
-			{
-				// i is not check in yet before index
-				return false;
-			}
-		}
-	}
 	return false;
 }
 
@@ -1830,21 +1872,54 @@ BOOL ConnectorPlugInHandler(struct PACKET_STRUCTURE *packet, unsigned char dispe
 BOOL ConnectorStateHandler(struct PACKET_STRUCTURE *packet, unsigned char dispenserIndex)
 {
 	BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
+	unsigned char ConnectionState;
+	unsigned char *AlarmCode;
 
-	if(find)
+	if(find && packet->Header.len <= 8)
 	{
-		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus != packet->Payload.data[0])
+	    ConnectionState = packet->Payload.data[0];
+	    AlarmCode = &packet->Payload.data[1];
+
+		if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus != ConnectionState)
 		{
-			PRINTF_FUNC("Connector %d Remote Status: %d", packet->Header.id, packet->Payload.data[0]);
+			PRINTF_FUNC("Connector %d Remote Status: %d", packet->Header.id, ConnectionState);
 
-			if((packet->Payload.data[0] == _CRS_Idle && ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus != _CRS_Terminating) ||
-				packet->Payload.data[0] == _CRS_Terminating)
+			switch(ConnectionState)
 			{
-			    PRINTF_FUNC("*********** Connector id %d Set Stop Flag ***********\n", packet->Header.id);
-				ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].GeneralChargingData.ChargingStopFlag.bits.NormalStop = true;
+                case _CRS_Idle:
+                case _CRS_Terminating:
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing ||
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Charging)
+                    {
+                        PRINTF_FUNC("*********** Connector id %d Set Normal Stop Flag ***********\n", packet->Header.id);
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.NormalStopRequest = true;
+                    }
+                    break;
+
+                case _CRS_Alarm:
+                    memcpy(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemotenAlarmCode, AlarmCode, 6);
+
+                    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Idle)
+                    {
+                        PRINTF_FUNC("*********** Connector id %d Set Fault Status [%s] ***********", packet->Header.id,
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemotenAlarmCode);
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.FaultStatusRequest = true;
+                    }
+                    else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Preparing ||
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus == _CRS_Charging)
+                    {
+
+                        PRINTF_FUNC("*********** Connector id %d Set Alarm Stop Flag [%s] ***********", packet->Header.id,
+                            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemotenAlarmCode);
+                        ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AlarmStopRequest = true;
+                    }
+                    break;
+
+                default:
+                    break;
 			}
 		}
-		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus = packet->Payload.data[0];
+		ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].RemoteStatus = ConnectionState;
 	}
 	else
 	{
@@ -1858,33 +1933,45 @@ unsigned char UserIDHandler(struct PACKET_STRUCTURE *packet, unsigned char dispe
 {
     BOOL find = FindConnectorID(dispenserIndex, packet->Header.id);
 	DispenserAck_Status authorize = _DAS_Wait;
+	unsigned char CardNumber[32];
+	unsigned char *result;
+	int length = 0;
 
-	if(find)
+	if(find || packet->Header.id == 0xFF)
 	{
-	    if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AuthorizeStatus == _AuthorizeStatus_Idle)
+	    length = packet->Header.len - 1;
+	    memset(CardNumber, 0x00, sizeof(CardNumber));
+	    memcpy(CardNumber, packet->Payload.data, length);
+
+	    if(packet->Header.id != 0xFF)
 	    {
-	        if(!ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AuthorizeRequest &&
-                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].AuthorizeStatus == _AuthorizeStatus_Idle)
-	        {
-                memset(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId, 0x00, 32);
-                memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId, packet->Payload.data, packet->Header.len - 1);
-
-                PRINTF_FUNC("Dispenser %d connector %d user id %s need authorize", dispenserIndex + 1, packet->Header.id, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId);
-	            ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].Parameter.bits.AuthorizeRequest = true;
-	            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.AuthorizeTargetID = packet->Header.id;
-	        }
-	        authorize = _DAS_Wait;
+	        result = &ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AuthorizingResult;
 	    }
-	    else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AuthorizeStatus == _AuthorizeStatus_Fail)
+	    else
 	    {
-            PRINTF_FUNC("Dispenser %d connector %d user id %s authorizing fail", dispenserIndex + 1, packet->Header.id, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId);
-            authorize = _DAS_NotAllowed;
+	        result = &ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].AuthResult;
 	    }
-	    else if(ShmSysConfigAndInfo->SysInfo.ConnectorInfo[packet->Header.id - 1].AuthorizeStatus == _AuthorizeStatus_Pass)
+
+	    if(*result == _AuthResult_Valid)
 	    {
-            PRINTF_FUNC("Dispenser %d connector %d user id %s authorizing ok", dispenserIndex + 1, packet->Header.id, ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId);
+            PRINTF_FUNC("Dispenser %d Target %d user id %s authorizing ok", dispenserIndex + 1, packet->Header.id, CardNumber);
             authorize = _DAS_Allowed;
 	    }
+	    else if(*result == _AuthResult_Invalid)
+	    {
+            PRINTF_FUNC("Dispenser %d Target %d user id %s authorizing fail", dispenserIndex + 1, packet->Header.id, CardNumber);
+            authorize = _DAS_NotAllowed;
+	    }
+	    else if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].AuthStatus == _AuthorizeStatus_Idle &&
+            ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.AuthorizeRequest == false)
+	    {
+	        memcpy(ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].UserId, CardNumber, sizeof(CardNumber));
+	        ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].AuthTarget = packet->Header.id;
+	        ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.AuthorizeRequest = true;
+
+	        PRINTF_FUNC("Dispenser %d connector %d user id %s need authorize", dispenserIndex + 1, packet->Header.id, CardNumber);
+	        authorize = _DAS_Wait;
+	    }
 	    else
 	    {
 	        authorize = _DAS_Wait;
@@ -2247,7 +2334,7 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 			if(rxLen == (receiveBuffer.Header.len + PACKET_HEADER_LENGTH))
 			{
 				ackResult = _R_NG;
-				//ShowSocketData(&receiveBuffer);
+                //ShowSocketData(&receiveBuffer);
 
 				if(ShmSysConfigAndInfo->SysInfo.DispenserInfo.ConnectionInfo[index].Status == _CNS_WaitModelName)
 				{
@@ -2326,6 +2413,10 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
                                 ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.ConnectorTimeoutConfigRequest = 1;
                                 ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.DefaultPriceConfigRequest = 1;
                                 ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.CurrencyConfigRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.BackendStatusRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.EthernetStatusRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.WiFiStatusRequest = 1;
+                                ShmSysConfigAndInfo->SysInfo.DispenserInfo.Dispenser[dispenserIndex].Setting.bits.TelcomModemStatusRequest = 1;
                             }
 						}
 					}
@@ -2333,7 +2424,7 @@ void DispenserSocketProcess(int socketFd, struct sockaddr_in clientInfo, unsigne
 					// Reg: 0x03, Power cabinet status
 					if(receiveBuffer.Header.op == _Header_Read && receiveBuffer.Payload.reg == _Reg_Power_Cabinet_Status)
 					{
-						PowerCabinetStatusResponse(socketFd, &receiveBuffer);
+						PowerCabinetStatusResponse(socketFd, &receiveBuffer, dispenserIndex);
 					}
 
 					// Reg: 0x04, Dispenser status
@@ -2569,7 +2660,8 @@ void InitDispenserInfo(void)
 	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].ReadyToCharge = 0;
 	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].ParentDispensetIndex = 0;
 	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].Parameter.Value = 0;
-	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AuthorizeStatus = 0;
+	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AuthorizingType = 0;
+	    ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].AuthorizingResult = 0;
 	    memset(&ShmSysConfigAndInfo->SysInfo.ConnectorInfo[i].WarningInfo, 0x00, sizeof(struct WARNING_CODE_INFO));
 
 	    //memset(&LastWarningInfo[i], 0x00, sizeof(struct WARNING_CODE_INFO));

+ 8 - 0
EVSE/Projects/DO360/Apps/Module_EvComm.h

@@ -29,6 +29,7 @@
 #define CCS_MAX_PHYSICAL_VOLTAGE        9500
 #define CCS_NATURAL_MAX_CURRENT         2000
 #define CCS_LIQUID_MAX_CURRENT          5000
+#define CCS_NATURAL_REMA_MAX_CURRENT    3000
 
 #define CHA_MAX_PHYSICAL_VOLTAGE        5000
 #define CHA_NATURAL_MAX_CURRENT         2000
@@ -36,6 +37,8 @@
 #define GBT_MAX_PHYSICAL_VOLTAGE        7500
 #define GBT_NATURAL_MAX_CURRENT         2500
 
+#define AUTO_GUN_SELECTION              0xFF
+
 struct Message
 {
 	int				size;
@@ -94,6 +97,7 @@ enum Connector_Remote_Status
 	_CRS_Preparing		= 0x01,
 	_CRS_Charging		= 0x02,
 	_CRS_Terminating	= 0x03,
+	_CRS_Alarm          = 0x04,
 };
 
 typedef enum
@@ -166,6 +170,10 @@ enum MiscCommand
     _MiscCmd_DefaultPrice       = 0x0003,
     _MiscCmd_Currency           = 0x0004,
     _MiscCmd_AccountBalance     = 0x0005,
+    _MiscCmd_BackendStatus      = 0x0006,
+    _MiscCmd_EthernetStatus     = 0x0007,
+    _MiscCmd_WiFiStatus         = 0x0008,
+    _MiscCmd_4GStatus           = 0x0009,
     _MiscCmd_HardwareReboot     = 0x0101,
     _MiscCmd_SoftwareRestart    = 0x0102,
     _MiscCmd_RemoteStart        = 0x0103,

+ 19 - 41
EVSE/Projects/DO360/Apps/Module_EventLogging.c

@@ -209,9 +209,6 @@ void RemoveFaultCodeToBuf(unsigned char *Code)
 	}
 }
 
-unsigned char MiscRequirement = 0;
-unsigned char VersionInfoRequirement = 0;
-
 int main(void)
 {
 	int ByteCount,BitCount;
@@ -231,6 +228,8 @@ int main(void)
 	}
 
 	memset((char *)&StatusCodeDisableMask, 0x00, sizeof(struct StatusCodeData));
+
+	// AlarmCode disable mask
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
@@ -256,44 +255,17 @@ int main(void)
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
 	StatusCodeDisableMask.AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
 
+	// InfoEvents disable mask
+	StatusCodeDisableMask.InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet = YES;
+	StatusCodeDisableMask.InfoCode.InfoEvents.bits.InternetDisconnectViaWiFi = YES;
+	StatusCodeDisableMask.InfoCode.InfoEvents.bits.InternetDisconnectVia4Gi = YES;
+    StatusCodeDisableMask.InfoCode.InfoEvents.bits.WiFiDisable = YES;
+    StatusCodeDisableMask.InfoCode.InfoEvents.bits.Telocom4GModuleDisable = YES;
+	StatusCodeDisableMask.InfoCode.InfoEvents.bits.BackendDisconnectedViaEthernet = YES;
+	StatusCodeDisableMask.InfoCode.InfoEvents.bits.BackendDisconnectedViaEthernet = YES;
+
 	for(;;)
 	{
-	    if(MiscRequirement != ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement)
-	    {
-	        memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
-            memcpy(EventCodeTmp, "B40001", sizeof(EventCodeTmp) - 1);
-
-	        if(ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement)
-	        {
-	            DEBUG_INFO("********** Misc Command Need Announcement **********\n");
-	            AddFaultCodeToBuf(EventCodeTmp);
-	        }
-	        else
-	        {
-	            DEBUG_INFO("********** Misc Command Announced **********\n");
-	            RemoveFaultCodeToBuf(EventCodeTmp);
-	        }
-	        MiscRequirement = ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.MiscNeedAnnouncement;
-	    }
-
-	    if(VersionInfoRequirement != ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo)
-	    {
-            memset(EventCodeTmp, 0, sizeof(EventCodeTmp));
-            memcpy(EventCodeTmp, "B40999", sizeof(EventCodeTmp) - 1);
-
-	        if(ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo)
-	        {
-                DEBUG_INFO("********** Need Update Dispenser Version Info **********\n");
-                AddFaultCodeToBuf(EventCodeTmp);
-	        }
-	        else
-	        {
-	            DEBUG_INFO("********** Dispenser Version Info Updated **********\n");
-	            RemoveFaultCodeToBuf(EventCodeTmp);
-	        }
-	        VersionInfoRequirement = ShmSysConfigAndInfo->SysInfo.CabinetSetting.bits.NeedDispenserVerInfo;
-	    }
-
 		//check Fault Status
 		for(ByteCount=0;ByteCount<4;ByteCount++)
 		{
@@ -377,13 +349,19 @@ int main(void)
 							//EventCodeTmp[0]=1;
 							DEBUG_INFO("Recovery Info Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] &= ~(1<<BitCount);
-							RemoveFaultCodeToBuf(EventCodeTmp);
+							if(!(StatusCodeDisableMask.InfoCode.InfoEvents.InfoVal[ByteCount] & (1<<BitCount)))
+							{
+							    RemoveFaultCodeToBuf(EventCodeTmp);
+							}
 						}
 						else
 						{
 							DEBUG_INFO("Info Code = %s\n", EventCodeTmp);
 							ShmStatusCodeData->InfoCode.PreviousInfoVal[ByteCount] |= (1<<BitCount);
-							AddFaultCodeToBuf(EventCodeTmp);
+							if(!(StatusCodeDisableMask.InfoCode.InfoEvents.InfoVal[ByteCount] & (1<<BitCount)))
+							{
+							    AddFaultCodeToBuf(EventCodeTmp);
+							}
 						}
 					}
 				}

+ 21 - 75
EVSE/Projects/DO360/Apps/Module_InternalComm.c

@@ -30,6 +30,7 @@
 #include	"../../define.h"
 #include	"internalComm.h"
 #include 	<stdbool.h>
+#include    "Config.h"
 
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
@@ -58,6 +59,7 @@ struct RelayModuleData			*ShmRelayModuleData[2];
 struct LedModuleData			*ShmLedModuleData;
 struct PsuData 					*ShmPsuData;
 struct OCPP16Data				*ShmOCPP16Data;
+ChargerInfoData                 *ShmChargerInfo;
 
 #define VIN_MAX_VOLTAGE_IEC         285	// 大於該值 : OVP
 #define VIN_MAX_REV_VOLTAGE_IEC     275 // 小於賦歸 OVP
@@ -126,7 +128,6 @@ int Uart5Fd;
 char *relayRs485PortName = "/dev/ttyS5";
 unsigned short fanSpeedSmoothValue = 500;
 
-bool isStopChargingCount = false;
 struct timeval _close_ac_contactor;
 
 struct timeval _priority_time;
@@ -1129,54 +1130,6 @@ void SetK1K2RelayStatus(byte index)
 	}
 }
 
-void CheckAcInputOvpStatus(byte index)
-{
-	if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputOVP == YES ||
-			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputOVP == YES ||
-			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputOVP == YES)
-	{
-//		if ((_chargingData[index]->SystemStatus >= S_PREPARNING && _chargingData[index]->SystemStatus <= S_CHARGING) ||
-//				(_chargingData[index]->SystemStatus >= S_CCS_PRECHARGE_ST0 && _chargingData[index]->SystemStatus <= S_CCS_PRECHARGE_ST1))
-//		{
-//			if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_IEC)
-//			{
-//				if (_psuInputVolR > VIN_MAX_VOLTAGE_IEC ||
-//						_psuInputVolS > VIN_MAX_VOLTAGE_IEC ||
-//						_psuInputVolT > VIN_MAX_VOLTAGE_IEC)
-//				{
-//					PRINTF_FUNC("IEC _psuInputVolR = %f, _psuInputVolS = %f, _psuInputVolT = %f \n",
-//							_psuInputVolR, _psuInputVolS, _psuInputVolT);
-//					_chargingData[index]->StopChargeFlag = YES;
-//				}
-//
-//			}
-//			else if (ShmSysConfigAndInfo->SysInfo.ChargerType == _CHARGER_TYPE_UL)
-//			{
-//				if (_psuInputVolR > VIN_MAX_VOLTAGE_UL ||
-//						_psuInputVolS > VIN_MAX_VOLTAGE_UL ||
-//						_psuInputVolT > VIN_MAX_VOLTAGE_UL)
-//				{
-//					PRINTF_FUNC("UL _psuInputVolR = %f, _psuInputVolS = %f, _psuInputVolT = %f \n",
-//							_psuInputVolR, _psuInputVolS, _psuInputVolT);
-//					_chargingData[index]->StopChargeFlag = YES;
-//				}
-//			}
-//		}
-//		else
-			_chargingData[index]->StopChargeFlag = YES;
-	}
-}
-
-void CheckPhaseLossStatus(byte index)
-{
-	if (ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL1InputUVP == YES ||
-			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL2InputUVP == YES ||
-			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.SystemL3InputUVP == YES)
-	{
-		_chargingData[index]->StopChargeFlag = YES;
-	}
-}
-
 void SetParalleRelayStatus()
 {
 	// 之後雙槍單模機種,橋接都會上
@@ -1586,6 +1539,21 @@ int InitShareMemory()
 		result = FAIL;
 	}
 
+    if ((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData), 0777)) < 0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ChargerInfoData NG \n");
+        #endif
+        result = FAIL;
+    }
+    else if ((ShmChargerInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ChargerInfoData NG \n");
+        #endif
+        result = FAIL;
+    }
+
 	return result;
 }
 
@@ -2497,7 +2465,6 @@ int main(void)
 	{
 	    if(!ShmSysConfigAndInfo->SysInfo.FirmwareUpdate)
 	    {
-            bool isCharging = false;
             // 程序開始之前~ 必須先確定 FW 版本與硬體版本,確認後!!~ 該模組才算是真正的 Initial Comp.
             if (ShmRelayModuleData[0]->SelfTest_Comp == NO)
             {
@@ -2580,11 +2547,6 @@ int main(void)
                     // 依據當前各槍的狀態選擇 搭上/放開 Relay
                     SetK1K2RelayStatus(i);
 
-                    if (ShmSysConfigAndInfo->SysConfig.PhaseLossPolicy == YES)
-                        CheckPhaseLossStatus(i);
-
-                    CheckAcInputOvpStatus(i);
-
                     if (_chargingData[i]->SystemStatus == S_IDLE)
                     {
                         _chargingData[i]->RelayWeldingCheck = NO;
@@ -2598,7 +2560,6 @@ int main(void)
                         (ShmSysConfigAndInfo->SysInfo.PageIndex >= _LCM_AUTHORIZING && ShmSysConfigAndInfo->SysInfo.PageIndex <= _LCM_WAIT_FOR_PLUG))
                     {
                         _chargingData[i]->IsReadyToCharging = YES;
-                        isCharging = true;
 
                         // 限定只有在槍類別為 GBT 的時候才做 relay welding 的判斷
 //                        if (_chargingData[i]->Type == _Type_GB)
@@ -2626,31 +2587,16 @@ int main(void)
                 // 橋接 relay
                 SetParalleRelayStatus();
 
-                if (isCharging ||
-                    (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE))
+                if(ShmChargerInfo->Control.RelayCtrl.bits.AcContactor == YES &&
+                        ShmChargerInfo->Control.RelayCtrl.bits.AcContactorForceOff == NO)
                 {
-                    isStopChargingCount = false;
                     outputRelay[0].relay_event.bits.AC_Contactor = YES;
                     outputRelay[1].relay_event.bits.AC_Contactor = YES;
                 }
                 else
                 {
-                    if (!isStopChargingCount)
-                    {
-                        gettimeofday(&_close_ac_contactor, NULL);
-                        isStopChargingCount = true;
-                    }
-                    else
-                    {
-                        if (((outputRelay[0].relay_event.bits.AC_Contactor == YES || outputRelay[1].relay_event.bits.AC_Contactor == YES)&&
-                                GetTimeoutValue(_close_ac_contactor) / 1000 >= (TEN_MINUTES * 1000)) ||
-                                ShmSysConfigAndInfo->SysInfo.ForceAcContactorOff == YES)
-                        {
-                            outputRelay[0].relay_event.bits.AC_Contactor = NO;
-                            outputRelay[1].relay_event.bits.AC_Contactor = NO;
-                            ShmSysConfigAndInfo->SysInfo.ForceAcContactorOff = NO;
-                        }
-                    }
+                    outputRelay[0].relay_event.bits.AC_Contactor = NO;
+                    outputRelay[1].relay_event.bits.AC_Contactor = NO;
                 }
 
                 if (ShmPsuData->Work_Step >= _TEST_MODE && ShmPsuData->Work_Step <= _TEST_MODE)

+ 18 - 2
EVSE/Projects/DO360/Apps/Module_PrimaryComm.c

@@ -37,6 +37,8 @@
 #define YES					1
 #define NO					0
 
+#define COMM_FAIL_COUNT     10
+
 typedef unsigned char 		byte;
 
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
@@ -59,6 +61,7 @@ byte _OutputDrv = 0;
 
 byte _acStatus = 0;
 byte _acChkCount = 0;
+int _CommFailCount = 0;
 
 void PRINTF_FUNC(char *string, ...);
 
@@ -259,9 +262,15 @@ void GetFwAndHwVersion()
 		strcpy((char *)ShmPrimaryMcuData->version, ver.Version_FW);
 		strcpy((char *) ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ver.Version_FW);
 	}
+	else
+	{
+	    _CommFailCount++;
+	}
 
 	if (Query_HW_Ver(Uart1Fd, Addr.IoExtend, &ver) == PASS)
+	{
 		PRINTF_FUNC("s2 = %s \n", ver.Version_HW);
+	}
 }
 
 void GetInputGpioStatus()
@@ -286,6 +295,7 @@ void GetInputGpioStatus()
 					ShmSysConfigAndInfo->SysInfo.AcContactorStatus = 1;
 					ShmPrimaryMcuData->InputDet.bits.AcContactorDetec = 1;
 				}
+				PRINTF_FUNC("Ac Contactor Status %s", ShmPrimaryMcuData->InputDet.bits.AcContactorDetec > 0 ? "On" : "Off");
 			}
 			else
 				_acChkCount++;
@@ -309,8 +319,8 @@ void GetInputGpioStatus()
 		//PRINTF_FUNC("left = %d \n", ShmPrimaryMcuData->InputDet.bits.Button1);
 		//PRINTF_FUNC("right = %d \n", ShmPrimaryMcuData->InputDet.bits.Button2);
 		//PRINTF_FUNC("ShmSysConfigAndInfo->SysInfo.AcContactorStatus = %d \n", ShmSysConfigAndInfo->SysInfo.AcContactorStatus);
-		if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == YES)
-			DEBUG_ERROR("AC Mainbreaker occur. \n");
+		//if (ShmPrimaryMcuData->InputDet.bits.AcMainBreakerDetec == YES)
+		//	DEBUG_ERROR("AC Mainbreaker occur. \n");
 	}
 }
 
@@ -477,6 +487,12 @@ int main(void)
                 {
                     ShmPrimaryMcuData->SelfTest_Comp = YES;
                 }
+
+                if(_CommFailCount >= COMM_FAIL_COUNT)
+                {
+                    PRINTF_FUNC("Primary MCU Communication Fail: %d", _CommFailCount);
+                    _CommFailCount = 0;
+                }
             }
             else
             {

+ 68 - 35
EVSE/Projects/DO360/Apps/Module_PsuComm.c

@@ -1,5 +1,6 @@
 
 #include 	"Module_PsuComm.h"
+#include    "Config.h"
 
 #define ARRAY_SIZE(A)		(sizeof(A) / sizeof(A[0]))
 #define PASS				1
@@ -26,6 +27,7 @@
 struct SysConfigAndInfo			*ShmSysConfigAndInfo;
 struct StatusCodeData 			*ShmStatusCodeData;
 struct PsuData 					*ShmPsuData;
+ChargerInfoData                 *ShmChargerInfo;
 
 bool libInitialize = false;
 byte getAvailableCapOffset = 5;
@@ -487,11 +489,14 @@ void GetModuleCountCallback(byte group, byte count)
 		ShmPsuData->SystemPresentPsuQuantity = count;
 	else
 	{
-		ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity = count;
+	    if(group < GENERAL_GUN_QUANTITY)
+	    {
+	        ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity = count;
+	    }
 	}
 }
 
-void GetMaxPowerAndCur(unsigned char mode, int ratingCur, int *pow, int *cur)
+void GetMaxPowerAndCur(unsigned char mode, byte group, int ratingCur, int *pow, int *cur)
 {
 	if (ShmPsuData->Work_Step < GET_SYS_CAP)
 		return;
@@ -501,8 +506,20 @@ void GetMaxPowerAndCur(unsigned char mode, int ratingCur, int *pow, int *cur)
 
 	if (mode == _MAIN_CHARGING_MODE_AVER)
 	{
-		maxCurrent /= 2;
-		maxPower /= 2;
+		//maxCurrent /= 2;
+		//maxPower /= 2;
+		if(ShmPsuData->SystemPresentPsuQuantity != 0)
+		{
+		    maxCurrent *= ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
+		    maxCurrent /= ShmPsuData->SystemPresentPsuQuantity;
+		    maxPower *= ShmPsuData->PsuGroup[group].GroupPresentPsuQuantity;
+		    maxPower /= ShmPsuData->SystemPresentPsuQuantity;
+		}
+		else
+		{
+		    maxCurrent = 0;
+		    maxPower = 0;
+		}
 	}
 
 	if (maxPower != 0 && maxPower <= *pow)
@@ -638,7 +655,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 			}
 		}
 
-		GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, ratingCur, &halfPow, &halfCur);
+		GetMaxPowerAndCur(_MAIN_CHARGING_MODE_AVER, group, ratingCur, &halfPow, &halfCur);
 
 //		if ((ShmSysConfigAndInfo->SysInfo.ReAssignedFlag >= _REASSIGNED_GET_NEW_CAP &&
 //				 ShmSysConfigAndInfo->SysInfo.ReAssignedFlag <= _REASSIGNED_RELAY_M_TO_A))
@@ -674,7 +691,7 @@ void GetAvailableCapCallback(byte address, short maxVol, short minVol, short max
 	else if (ShmSysConfigAndInfo->SysInfo.MainChargingMode == _MAIN_CHARGING_MODE_MAX)
 	{
 		//PRINTF_FUNC("group = %d, Final = %d \n", group, _current);
-		GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, _ratingcurrent, &_power, &_current);
+		GetMaxPowerAndCur(_MAIN_CHARGING_MODE_MAX, group, _ratingcurrent, &_power, &_current);
 
 		if (ShmSysConfigAndInfo->SysInfo.IsAlternatvieConf == YES)
 		{
@@ -1285,6 +1302,21 @@ int InitShareMemory()
 		result = FAIL;
 	 }
 
+    if ((MeterSMId = shmget(SM_ChargerInfoKey, sizeof(ChargerInfoData), 0777)) < 0)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ChargerInfoData NG");
+        #endif
+        result = FAIL;
+    }
+    else if ((ShmChargerInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+    {
+        #ifdef SystemLogMessage
+        DEBUG_ERROR("shmat ChargerInfoData NG");
+        #endif
+        result = FAIL;
+    }
+
     return result;
 }
 
@@ -1305,30 +1337,30 @@ void InitialPsuData()
 		ShmPsuData->PsuGroup[_groupCount].GroupErrorFlag.PsuGroupErrorValue = 0;
 	}
 
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFuseBurnOut = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcAndDcdcCommFault = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageUnbalance = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusOverVoltage = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusVoltageAbnormal = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputOVP = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDuplicateID = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuBusUnderVoltage = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputPhaseLoss = NO;
     ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuInputUVP = NO;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = YES;
-    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = YES;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCommunicationFail = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuSevereUnevenCurrent = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFfcSideShutDown = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFullSpeed = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcSideShutDown = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPowerLimitedState = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuTemperaturePowerLimit = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuAcPowerLimit = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcEepromFault = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuFanFailureAlarm = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuOutputShortCircuit = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuPfcEepromFault = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuCriticalPointOTP = NO;
+    ShmStatusCodeData->AlarmCode.AlarmEvents.bits.PsuDcdcOverVoltage = NO;
 }
 
 void Initialization()
@@ -1511,7 +1543,7 @@ void PsuReceiveRecoveryCheck(void)
             psuTaskCount++;
         }
 
-        ptrToken = strtok_r(NULL, ";", &ptrSave);
+        ptrToken = strtok_r(NULL, " ", &ptrSave);
     }
     close(fd);
 
@@ -1574,7 +1606,8 @@ int main(void)
 	while (libInitialize)
 	{
 		// 斷電狀態
-		if (ShmSysConfigAndInfo->SysInfo.AcContactorStatus == NO)
+		if (ShmChargerInfo->Control.RelayCtrl.bits.AcContactor == NO ||
+            ShmChargerInfo->Control.RelayCtrl.bits.AcContactorForceOff == YES)
 		{
 			//一但 AC Off PSU 斷電全部的 PSU Group ID 會全部清 0
 			if (!isInitialComp)
@@ -1648,15 +1681,15 @@ int main(void)
 						PRINTF_FUNC("Psu Count = %d", moduleCount);
 						if (ShmSysConfigAndInfo->SysInfo.BootingStatus == BOOTTING || psuReceiveRecovery)
 						{
-							// 電樁在 Booting 的狀態 - 自檢
-							PRINTF_FUNC("== PSU == GET_SYS_CAP");
-							ShmPsuData->Work_Step = GET_SYS_CAP;
+                            // 電樁在 Booting 的狀態 - 自檢
+                            PRINTF_FUNC("== PSU == GET_SYS_CAP");
+                            ShmPsuData->Work_Step = GET_SYS_CAP;
+                            psuReceiveRecovery = false;
 						}
 						else
 						{
 							PRINTF_FUNC("== PSU == _WORK_CHARGING");
 							ShmPsuData->Work_Step = _WORK_CHARGING;
-
 							gettimeofday(&_test_time, NULL);
 						}
 					}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 592 - 337
EVSE/Projects/DO360/Apps/main.c


BIN
EVSE/Projects/DO360/Images/ramdisk.gz


+ 16 - 3
EVSE/Projects/Noodoe/Apps/main.c

@@ -28,7 +28,7 @@
 #define TMR_IDX_9 						9
 
 #define TIMEOUT_SPEC_HANDSHAKING		180000
-#define TIMEOUT_SPEC_AUTH				15000
+#define TIMEOUT_SPEC_AUTH				60000
 #define TIMEOUT_SPEC_HANDSHAKING_LED	185000
 #define TIMEOUT_SPEC_LOGPPRINTOUT		30000
 #define TIMEOUT_SPEC_PROFILE_PREPARE	5000
@@ -998,6 +998,19 @@ void InitEthernet()
 					sprintf(tmpbuf, "/sbin/udhcpc -i eth0 -x hostname:CSU3_%s -s /root/dhcp_script/eth0.script > /dev/null &", ShmSysConfigAndInfo->SysConfig.SystemId);
 					system(tmpbuf);
 				}
+				else
+				{
+					system("pgrep -f \"udhcpc -i eth0\" | xargs kill");
+					memset(tmpbuf,0,256);
+				        sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up &",
+					        ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthIpAddress,
+					        ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthSubmaskAddress);
+					system(tmpbuf);
+					memset(tmpbuf,0,256);
+					sprintf(tmpbuf,"route add default gw %s eth0 &",
+					ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);
+					system(tmpbuf);
+				}
 			}
 
 			if(isReachableInternet() == PASS)
@@ -1275,7 +1288,7 @@ void get_firmware_version(unsigned char gun_index)
 	strcpy((char*)ShmSysConfigAndInfo->SysInfo.CsuPrimFwRev, ShmCharger->gun_info[gun_index].ver.Version_FW);
 
 	// Get CSU root file system version
-	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.49.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "V0.50.00.0000.00");
 
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
@@ -1760,7 +1773,7 @@ int isReachableInternet()
 	}
 	pclose(fp);
 	memset(buf, 0x00, sizeof(buf));
-	
+
 	// Get gateway
 	fp = popen("ip route", "r");
 	if(fp == NULL)

BIN
EVSE/Projects/Noodoe/Images/ramdisk.gz


+ 76 - 40
EVSE/Projects/define.h

@@ -114,7 +114,7 @@ Storage							0x0A200000-0x7FFFFFFF		1886 MB
     #define CCS_QUANTITY            2
     #define GB_QUANTITY             2
     #define AC_QUANTITY             0
-    #define GENERAL_GUN_QUANTITY	0
+    #define GENERAL_GUN_QUANTITY    0
     #define PSU_QUANTITY            2
     #define ONE_CONNECTOR_USE       0
 #elif DO360
@@ -386,6 +386,12 @@ struct Schedule
 	unsigned char   isTriggerStop;    					// 0: disable; 1: enable
 };
 
+struct LocalSharingInfo
+{
+    unsigned short      AvailableShargingCurrent;       // 0 ~ rating value amp,  Synchronize from local sharing server
+    unsigned char       isConnectedSharingServer:1;     // 0: Disconnected, 1: Connected
+};
+
 typedef union
 {
     unsigned int ChargingStopValue;
@@ -456,6 +462,7 @@ struct SysConfigData
 	unsigned int 			Checksum;					//4 bytes checksum
 	struct LED				LedInfo;					// LED configuration info
 	unsigned char			ShowInformation;
+	unsigned char           isReqFirstUpgrade;          //EVSE is request first upgrade from PH server
 };
 
 struct ChargingInfoData
@@ -550,6 +557,9 @@ typedef union
     struct
     {
         unsigned int DispenserConfigSync:1;             // 0: not synced,   1: synced
+        unsigned int MiscNeedAnnouncement:1;            // 0: no need,      1: need send misc command
+        unsigned int NeedDispenserVerInfo:1;            // 0: no need,      1: need dispenser to report it's version info
+        unsigned int EnableAutoGunSelection:1;          // 0: disable,      1: enable auto gun selection
         unsigned int AuthorizeRequest:1;                // 0: idle,         1: requesting                           ( dispenser -> cabinet)
         unsigned int ConnectorTimeoutConfigRequest:1;   // 0: no request,   1: connector timeout setting            (    ocpp   -> cabinet -> dispenser)
         unsigned int DefaultPriceConfigRequest:1;       // 0: no request,   1: default price setting                (    ocpp   -> cabinet -> dispenser)
@@ -558,11 +568,14 @@ typedef union
         unsigned int HardwareRebootConfirm:1;           // 0: no effect,    1: dispenser confirmed
         unsigned int SoftwareResetRequest:1;            // 0: no request,   1: software reset request               (    ocpp   -> cabinet -> dispenser)
         unsigned int SoftwareResetConfirm:1;            // 0: no effect,    1: dispenser confirmed
-        unsigned int AuthorizeTargetID:8;               // authorize target connector id
         unsigned int FirmwareUpdateRequest:1;           // firmware update request
         unsigned int FirmwareUpdateConfirm:1;           // firmware update start
         unsigned int FirmwareUpdateCompleted:1;         // firmware update completed
-        unsigned int res:12;
+        unsigned int BackendStatusRequest:1;            // 0: no request,   1: backend connection status has changed            ( cabinet -> dispenser)
+        unsigned int EthernetStatusRequest:1;           // 0: no request,   1: ethernet connection status has changed           ( cabinet -> dispenser)
+        unsigned int WiFiStatusRequest:1;               // 0: no request,   1: wifi connection status has changed               ( cabinet -> dispenser)
+        unsigned int TelcomModemStatusRequest:1;        // 0: no request,   1: 4g connection status has changed                 ( cabinet -> dispenser)
+        unsigned int res:13;
     }bits;
 }DispenserSettingFlag;
 
@@ -600,7 +613,10 @@ struct DispenserModule
     struct   LED    LedInfo;                    // LED configuration info
 
                                                 // 0: Authorize idle, 1: Authorize wait,   2: Authorizing
-    unsigned char           AuthorizeStatus;    // 3: Authorize ok,   4: Authorizing fail
+    unsigned char           AuthStatus;         // 3: Authorize done, 4: Authorize end
+    unsigned char           AuthTarget;         // Authorize Target Connector ID: 1 ~ 4, AutoSelection: 0xFF
+    unsigned char           AuthType;           // 0: _AuthType_None, 1: _AuthType_RFID, 2: _AuthType_RemoteStart
+    unsigned char           AuthResult;         // 0: _AuthResult_None, 1: _AuthResult_Valid,   2: _AuthResult_Invalid
     DispenserSettingFlag    Setting;
     char                    FwFileName[128];
 };
@@ -655,7 +671,6 @@ typedef union
     unsigned int Value;
     struct
     {
-        unsigned int  AuthorizeRequestType:4;           // 0: not authorize, 1: local authorized, 2: remote start authorized
         unsigned int  PermissionRequest:1;              // 0: no request,    1: dispenser request to charging                   ( dispenser -> cabinet)
         unsigned int  RemoteStartRequest:1;             // 0: no request,    1: remote start                                    (    ocpp   -> cabinet -> dispenser)
         unsigned int  RemoteStartConfirm:1;
@@ -670,26 +685,30 @@ typedef union
         unsigned int  AnnounceBalance:1;                //
         unsigned int  StartWaitPlug:1;                  //
         unsigned int  NeedCleanAuthorizeInfo:1;         //
-        unsigned int  AuthorizeRequest:1;               // 0: idle,         1: requesting                                       ( dispenser -> cabinet)
         unsigned int  SwipeRfidConfirm:1;
         unsigned int  OutputLimitEnable:1;              // 0: disable,      1: enable
         unsigned int  ChargingPermission:2;             // 0: not allowed,  1: allowed,         2: wait
-        unsigned int  res:9;
+        unsigned int  NormalStopRequest:1;              // 0: no effect,    1: connector normal stop request                    ( dispenser -> cabinet)
+        unsigned int  AlarmStopRequest:1;               // 0: no effect,    1: connector alarm stop request                     ( dispenser -> cabinet)
+        unsigned int  FaultStatusRequest:1;
+        unsigned int  res:11;
     }bits;
 }ConnectorParameter;
 
 struct ConnectorInfoData
 {
-    unsigned char RemoteStatus;                         // 0: Idle, 1: Preparing, 2: Charging, 3: Terminating
+    unsigned char RemoteStatus;                         // 0: Idle, 1: Preparing, 2: Charging, 3: Terminating, 4: Alarm
     unsigned char Enable;                               // 0: Disable, 1: Enable
     unsigned char ReadyToCharge;                        // 0: Not Ready, 1: Ready to Charge (no use)
     unsigned char ParentDispensetIndex;                 // Parent Dispenser Index: 0 ~ 3
     ConnectorParameter       Parameter;
-                                                        // 0: Authorize idle, 1: Authorize wait,   2: Authorizing
-    unsigned char            AuthorizeStatus;           // 3: Authorize ok,   4: Authorizing fail
+
+    unsigned char            AuthorizingType;
+    unsigned char            AuthorizingResult;         // 0: _AuthResult_None, 1: _AuthResult_Valid,   2: _AuthResult_Invalid
     struct ChargingInfoData  GeneralChargingData;
     struct WARNING_CODE_INFO WarningInfo;
 
+    unsigned char           RemotenAlarmCode[7];
     unsigned short          RemoteChargingVoltage;          // charging voltage from connector, unit: 0.1V
     unsigned short          RemoteChargingCurrent;          // charging current from connector, unit: 0.1A
     unsigned int            RemoteRemainChargingDuration;   // remain charging duration from connector, unit: 1s
@@ -719,16 +738,25 @@ typedef union
     {
         unsigned int StartAuthorize:1;          // 0: idle,    1: authorizing
         unsigned int AuthorizingCompleted:1;    // 0: not yet, 1: authorizing completed
-        unsigned int AuthorizeTargetIndex:4;    // dispenser or connector index from 0 ~ 3
-        unsigned int AuthorizeSrc:4;            // 0: not authorize, 1: local authorize, 2: remote authorize
-        unsigned int MiscNeedAnnouncement:1;    // 0: no requirement, 1: need to announce something to dispenser
-        unsigned int NeedDispenserVerInfo:1;    // 0: no requirement, 1: need dispenser to report it's version info
         unsigned int DispenserDisconnection:1;  // 0: no connection,  1: dispenser connected
         unsigned int BackendAuthorized:1;       // 0: local authorized, 1: backend authorized
-        unsigned int res:18;
+        unsigned int res:28;
     }bits;
 }CabinetSettingFlag;
 
+typedef struct
+{
+    unsigned int ConnectionTimeout;             // unit: 1s
+    unsigned int DefaultPrice;                  // unit: 0.01dollar
+    unsigned int Currency;                      // currency index
+    unsigned int BackendStatus;                 // 0: disable, 1: connected, 2: disconnected
+    unsigned int EthernetStatus;                // 0: disable, 1: connected, 2: disconnected
+    unsigned int WiFiStatus;                    // 0: disable, 1: connected, 2: disconnected
+    unsigned int TelcomModemStatus;             // 0: disable, 1: connected, 2: disconnected
+    unsigned int HardwareReboot;                // 1: HardwareReboot, Other value: no effect
+    unsigned int SoftwareRestart;               // 1: SoftwareRestart, Other value: no effect
+}CabinetMiscCommand;
+
 struct SysInfoData
 {
 	/**************System***************/
@@ -812,8 +840,14 @@ struct SysInfoData
     unsigned char Relay2ModuleFwRev[32];	//Relay control  module firmware version
     struct DispenserInfoData DispenserInfo;
     struct ConnectorInfoData ConnectorInfo[GENERAL_GUN_QUANTITY];
-    CabinetSettingFlag       CabinetSetting;
-    unsigned char       ForceAcContactorOff;            // 0: no effect,    1: ac contactor off
+
+    unsigned char           AuthorizedDispenser;        // record authorized dispenser index
+    unsigned char           AuthorizedTarget;           // record authorized target: 1 ~ 4, 0xFF
+    unsigned char           AuthorizedType;             // record authorized type
+    unsigned char           AuthorizedStatus;           // cabinet authorized status
+    CabinetSettingFlag      CabinetSetting;
+    CabinetMiscCommand      CabinetMicsStatus;
+    struct LocalSharingInfo localSharingInfo;           // Local power sharing info structure
 };
 
 struct SysConfigAndInfo
@@ -4635,7 +4669,7 @@ struct ChargingProfileType
 	unsigned char recurrencyKind[8];								// Optional. Indicates the start point of a recurrence.
 	unsigned char validFrom[28];									// Optional. Point in time at which the profile starts to be valid. If absent, the profile is valid as soon as it is received by the Charging Station.
 	unsigned char validTo[28];										// Optional. Point in time at which the profile stops to be valid. If absent, the profile is valid until it is replaced by another profile.
-	unsigned char transactionId[36];								// Optional. SHALL only be included if ChargingProfilePurpose is set to TxProfile. The transactionId is used to match the profile to a specific transaction.
+	unsigned char transactionId[37];								// Optional. SHALL only be included if ChargingProfilePurpose is set to TxProfile. The transactionId is used to match the profile to a specific transaction.
 	struct ChargingScheduleType chargingSchedule[3];				// Required. Schedule that contains limits for the available power or current over time. In order to support ISO 15118 schedule negotiation, it supports at most three schedules with associated tariff to choose from.
 };
 
@@ -4727,7 +4761,7 @@ struct EventDataType
 	unsigned char techcode[50];										// Optional. Technical (error) code as reported by component.
 	unsigned char techInfo[500];									// Optional. Technical detail information as reported by component.
 	unsigned char cleared;											// Optional. Cleared is set to true to report the clearing of a monitored situation, i.e. a 'return to normal'.
-	unsigned char transactionId[36];								// Optional. If an event notification is linked to a specific transaction, this field can be used to specify its transactionId.
+	unsigned char transactionId[37];								// Optional. If an event notification is linked to a specific transaction, this field can be used to specify its transactionId.
 	unsigned int variableMonitoringId;								// Optional. Identifies the VariableMonitoring which triggered the event.
 	unsigned char eventNotificationType[32];						// Required. Specifies the event notification type of the message.
 	struct ComponentType component;									// Required. Component for which event is notified.
@@ -4773,7 +4807,7 @@ struct MessageInfoType
 	unsigned char state[16];										// Optional. During what state should this message be shown. When omitted this message should be shown in any state of the Charging Station.
 	unsigned char startDateTime[28];								// Optional. From what date-time should this message be shown. If omitted: directly.
 	unsigned char endDateTime[28];									// Optional. Until what date-time should this message be shown, after this date/time this message SHALL be removed.
-	unsigned char transactionId[36];								// Optional. During which transaction shall this message be shown. Message SHALL be removed by the Charging Station after transaction has ended.
+	unsigned char transactionId[37];								// Optional. During which transaction shall this message be shown. Message SHALL be removed by the Charging Station after transaction has ended.
 	struct MessageContentType message;								// Required. Contains message details for the message to be displayed on a Charging Station.
 	struct ComponentType display;									// Optional. When a Charging Station has multiple Displays, this field can be used to define to which Display this message belongs.
 };
@@ -4892,7 +4926,7 @@ struct SetVariableResultType
 
 struct TransactionType
 {
-	unsigned char transactionId[36];								// Required. This contains the Id of the transaction.
+	unsigned char transactionId[37];								// Required. This contains the Id of the transaction.
 	unsigned char chargingState[16];								// Optional. Current charging state, is required when state has changed. Omitted when there is no communication between EVSE and EV, because no cable is plugged in.
 	unsigned int timeSpentCharging;									// Optional. Contains the total time that energy flowed from EVSE to EV during the transaction (in seconds). Note that timeSpentCharging is smaller or equal to the duration of the transaction.
 	unsigned char stoppedReason[20];								// Optional. This contains the reason why the transaction was stopped. MAY only be omitted when Reason is "Local".
@@ -4979,7 +5013,7 @@ struct ClearVariableMonitoring_20
 struct CostUpdated_20
 {
 	float totalCost;												// Required. Current total cost, based on the information known by the CSMS, of the transaction including taxes. In the currency configured with the configuration Variable: [Currency]
-	unsigned char transactionId[36];								// Required. Transaction Id of the transaction the current cost are asked for.
+	unsigned char transactionId[37];								// Required. Transaction Id of the transaction the current cost are asked for.
 	unsigned char guid[37];											// Save guid from server request
 };
 
@@ -5117,7 +5151,7 @@ struct GetReport_20
 
 struct GetTransactionStatus_20
 {
-	unsigned char transactionId[36];								// Optional. The Id of the transaction for which the status is requested.
+	unsigned char transactionId[37];								// Optional. The Id of the transaction for which the status is requested.
 	unsigned char Response_ongoingIndicator;						// Optional. Whether the transaction is still ongoing.
 	unsigned char Response_messagesInQueue;							// Required. Whether there are still message to be delivered.
 	unsigned char guid[37];											// Save guid from server request
@@ -5255,13 +5289,13 @@ struct RequestStartTransaction_20
 	struct ChargingProfileType chargingProfile;						// Optional. Charging Profile to be used by the Charging Station for the requested transaction.
 	struct IdTokenType groupIdToken;								// Optional. The group identifier that the Charging Station must use to start a transaction.
 	unsigned char Response_status[16];								// Required. Status indicating whether the Charging Station accepts the request to start a transaction.
-	unsigned char Response_transactionId[36];						// Optional. When the transaction was already started by the Charging Station before the RequestStartTransactionRequest was received, for example: cable plugged in first. This contains the transactionId of the already started transaction.
+	unsigned char Response_transactionId[37];						// Optional. When the transaction was already started by the Charging Station before the RequestStartTransactionRequest was received, for example: cable plugged in first. This contains the transactionId of the already started transaction.
 	unsigned char guid[37];											// Save guid from server request
 };
 
 struct RequestStopTransaction_20
 {
-	unsigned char transactionId[36];								// Required. The identifier of the transaction which the Charging Station is requested to stop.
+	unsigned char transactionId[37];								// Required. The identifier of the transaction which the Charging Station is requested to stop.
 	unsigned char Response_status[16];								// Required. Status indicating whether Charging Station accepts the request to stop a transaction.
 	unsigned char guid[37];											// Save guid from server request
 };
@@ -5484,23 +5518,22 @@ struct OCPP20Data
 			unsigned char NotifyDisplayMessagesReq :1;
 			unsigned char NotifyDisplayMessagesConf :1;
 
-			unsigned char NotifyEVChargingNeedsReq :1;
-			unsigned char NotifyEVChargingNeedsConf :1;
 			unsigned char NotifyEVChargingScheduleReq :1;
 			unsigned char NotifyEVChargingScheduleConf :1;
 			unsigned char NotifyEventReq :1;
 			unsigned char NotifyEventConf :1;
 			unsigned char NotifyMonitoringReportReq :1;
 			unsigned char NotifyMonitoringReportConf :1;
-
 			unsigned char NotifyReportReq :1;
 			unsigned char NotifyReportConf :1;
+
 			unsigned char ReportChargingProfilesReq :1;
 			unsigned char ReportChargingProfilesConf :1;
 			unsigned char SecurityEventNotificationReq :1;
 			unsigned char SecurityEventNotificationConf :1;
 			unsigned char SignCertificateReq :1;
 			unsigned char SignCertificateConf :1;
+			unsigned char :2;
 
 		} bits;
 	} SpMsg;
@@ -5551,71 +5584,70 @@ struct OCPP20Data
 			unsigned char ClearCacheConf :1;	//bit 3,
 			unsigned char ClearDisplayMessageReq :1;
 			unsigned char ClearDisplayMessageConf :1;
-			unsigned char ClearedChargingLimitReq :1;
-			unsigned char ClearedChargingLimitConf :1;
-
 			unsigned char ClearVariableMonitoringReq :1;
 			unsigned char ClearVariableMonitoringConf :1;
+
 			unsigned char CostUpdatedReq :1;
 			unsigned char CostUpdatedConf :1;
 			unsigned char CustomerInformationReq :1;
 			unsigned char CustomerInformationConf :1;
 			unsigned char DeleteCertificateReq :1;
 			unsigned char DeleteCertificateConf :1;
-
 			unsigned char GetBaseReportReq :1;
 			unsigned char GetBaseReportConf :1;
+
 			unsigned char GetChargingProfilesReq :1;
 			unsigned char GetChargingProfilesConf :1;
 			unsigned char GetCompositeScheduleReq :1;	//bit 4,
 			unsigned char GetCompositeScheduleConf :1;	//bit 5,
 			unsigned char GetDisplayMessagesReq :1;
 			unsigned char GetDisplayMessagesConf :1;
-
 			unsigned char GetInstalledCertificateIdsReq :1;
 			unsigned char GetInstalledCertificateIdsConf :1;
+
 			unsigned char GetLocalListVersionReq :1; //bit 2,
 			unsigned char GetLocalListVersionConf :1;	//bit 3,
 			unsigned char GetLogReq :1;
 			unsigned char GetLogConf :1;
 			unsigned char GetMonitoringReportReq :1;
 			unsigned char GetMonitoringReportConf :1;
-
 			unsigned char GetReportReq :1;
 			unsigned char GetReportConf :1;
+
 			unsigned char GetTransactionStatusReq :1;
 			unsigned char GetTransactionStatusConf :1;
 			unsigned char GetVariablesReq :1;
 			unsigned char GetVariablesConf :1;
 			unsigned char InstallCertificateReq :1;
 			unsigned char InstallCertificateConf :1;
-
 			unsigned char PublishFirmwareReq :1;
 			unsigned char PublishFirmwareConf :1;
+
 			unsigned char ResetReq :1; //bit 4,
 			unsigned char ResetConf :1;	//bit 5,
 			unsigned char SendLocalListReq :1;	//bit 6,
 			unsigned char SendLocalListConf :1;	//bit 7,
 			unsigned char SetChargingProfileReq :1;	//bit 6,
 			unsigned char SetChargingProfileConf :1;	//bit 7,
-
 			unsigned char SetDisplayMessageReq :1;
 			unsigned char SetDisplayMessageConf :1;
+
 			unsigned char SetMonitoringBaseReq :1;
 			unsigned char SetMonitoringBaseConf :1;
 			unsigned char SetMonitoringLevelReq :1;
 			unsigned char SetMonitoringLevelConf :1;
 			unsigned char SetNetworkProfileReq :1;
 			unsigned char SetNetworkProfileConf :1;
-
 			unsigned char SetVariableMonitoringReq :1;
 			unsigned char SetVariableMonitoringConf :1;
+
 			unsigned char SetVariablesReq :1;
 			unsigned char SetVariablesConf :1;
 			unsigned char UnpublishFirmwareReq :1;
 			unsigned char UnpublishFirmwareConf :1;
-			unsigned char UpdateFirmwareReq :1;	//bit 6,
-			unsigned char UpdateFirmwareConf :1;	//bit 7,
+			unsigned char UpdateFirmwareReq :1;
+			unsigned char UpdateFirmwareConf :1;
+			unsigned char :2;
 		} bits;
 	} MsMsg;
 
@@ -5628,7 +5660,11 @@ struct OCPP20Data
 			//CSUMsgValue[0]
 			unsigned char ChargingProfileReq:1;	//bit 0,
 			unsigned char ChargingProfileConf:1;	//bit 0,
-			unsigned char :6;	//bit 1,2,3,4,5,6,7 , reserved
+            unsigned char ClearedChargingLimitReq :1;
+            unsigned char ClearedChargingLimitConf :1;
+            unsigned char NotifyEVChargingNeedsReq :1;
+            unsigned char NotifyEVChargingNeedsConf :1;
+            unsigned char :2;   //bit 1,2,3,4,5,6,7 , reserved
 		} bits[CONNECTOR_QUANTITY];
 	}CSUMsg;
 

+ 1 - 1
EVSE/rootfs/etc/logrotate.d/evse

@@ -1,7 +1,7 @@
 /Storage/**/*Log /Storage/**/*.log{
 	weekly
         rotate 24
-	size 50M
+	size 10M
         missingok
         compress
         notifempty

+ 1 - 0
EVSE/rootfs/root/.gitignore

@@ -7,3 +7,4 @@ OcppBackend20
 Module_ProduceUtils
 Module_EventLogging
 Module_PhBackend
+Module_InitUpgrade

BIN
EVSE/rootfs/root/OcppBackend20


+ 13 - 13
Makefile

@@ -305,7 +305,7 @@ DM30-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DM30 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DM30 all
 	@cd EVSE/Projects/DM30/Apps;make Project=DM30 Project_Debug_Option=0 all
 	@rm -f EVSE/Projects/DM30/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -333,7 +333,7 @@ DM30-DEBUG-rootfs:
 	@echo =================================
 	@echo     Building DM30 debug rootfs
 	@echo =================================
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DM30 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DM30 all
 	@cd EVSE/Projects/DM30/Apps;make Project=DM30 Project_Debug_Option=1 all
 	@rm -f EVSE/Projects/DM30/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -400,7 +400,7 @@ DW30-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DW30 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DW30 all
 	@cd EVSE/Projects/DW30/Apps;make Project=DW30 Project_Debug_Option=0 all
 	@rm -f EVSE/Projects/DW30/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -428,7 +428,7 @@ DW30-DEBUG-rootfs:
 	@echo =================================
 	@echo     Building DW30 debug rootfs
 	@echo =================================
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DW30 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DW30 all
 	@cd EVSE/Projects/DW30/Apps;make Project=DW30 Project_Debug_Option=1 all
 	@rm -f EVSE/Projects/DW30/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -499,7 +499,7 @@ DS60-120-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DS60120 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DS60120 all
 	@cd EVSE/Projects/DS60-120/Apps;make Project=DS60120 all
 	@rm -f EVSE/Projects/DS60-120/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -570,7 +570,7 @@ AW-Regular-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=AWRegular all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=AWRegular all
 	@cd EVSE/Projects/AW-Regular/Apps;make Project=AWRegular all
 	@rm -f EVSE/Projects/AW-Regular/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -641,7 +641,7 @@ BYTON-GB-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=BYTONGB all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=BYTONGB all
 	@cd EVSE/Projects/BYTON-GB/Apps;make Project=BYTONGB all
 	@rm -f EVSE/Projects/BYTON-GB/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1138,7 +1138,7 @@ PlugIt360-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=PlugIt360 all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=PlugIt360 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=PlugIt360 all
 	@cd EVSE/Projects/PlugIt360/Apps;make Project=PlugIt360 all
 	@rm -f EVSE/Projects/PlugIt360/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1211,7 +1211,7 @@ AW-CCS-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=AWCCS all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=AWCCS all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=AWCCS all
 	@cd EVSE/Projects/AW-CCS/Apps;make Project=AWCCS all
 	@rm -f EVSE/Projects/AW-CCS/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1283,7 +1283,7 @@ DO360-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=DO360 all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=DO360 all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=DO360 all
 	@cd EVSE/Projects/DO360/Apps;make Project=DO360 all
 	@rm -f EVSE/Projects/DO360/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1356,7 +1356,7 @@ ATE-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=ATE all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=ATE all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=ATE all
 	@cd EVSE/Projects/ATE/Apps;make Project=ATE all
 	@rm -f EVSE/Projects/ATE/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1429,7 +1429,7 @@ Zanobe-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=Zanobe all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=Zanobe all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=Zanobe all
 	@cd EVSE/Projects/Zanobe/Apps;make Project=Zanobe all
 	@rm -f EVSE/Projects/Zanobe/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072
@@ -1502,7 +1502,7 @@ e4you-rootfs:
 	@echo     Building User rootfs
 	@echo =================================
 #	@cd EVSE/GPL;make Project=e4you all
-	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_PASS_CERT_EXPIRED Project=e4you all
+	@cd EVSE/Modularization;make TLS_EXPIRED=TLS_VALID_CERT_EXPIRED Project=e4you all
 	@cd EVSE/Projects/e4you/Apps;make Project=e4you all
 	@rm -f EVSE/Projects/e4you/Images/ramdisk.gz
 	@dd if=/dev/zero of=/dev/ram0 bs=1k count=131072

+ 1 - 1
board-support/u-boot-2017.01+gitAUTOINC+340fb36f04-g340fb36f04/.config

@@ -379,7 +379,7 @@ CONFIG_CMD_ENV_EXISTS=y
 CONFIG_CMD_MEMORY=y
 CONFIG_CMD_CRC32=y
 # CONFIG_LOOPW is not set
-# CONFIG_CMD_MEMTEST is not set
+CONFIG_CMD_MEMTEST=y
 # CONFIG_CMD_MX_CYCLIC is not set
 # CONFIG_CMD_MEMINFO is not set
 

+ 2 - 0
board-support/u-boot-2017.01+gitAUTOINC+340fb36f04-g340fb36f04/include/configs/am335x_evm.h

@@ -18,6 +18,8 @@
 
 #include <configs/ti_am335x_common.h>
 
+#define CONFIG_SYS_MEMTEST_START	0x80000000
+#define CONFIG_SYS_MEMTEST_END		0x9fffffff
 
 #ifndef CONFIG_SPL_BUILD
 # define CONFIG_TIMESTAMP

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно