Browse Source

[New feature][AW-CCS][Module_LcmControl]

2020.09.18 / Folus Wen

Actions:
1. EVSE/Projects/AW-CCS/Apps/LCM/ add LCM control task.
2. EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.c add usleep(100000) to while loop for reduce CPU utilization.
3. EVSE/Projects/AW-CCS/Apps/main.c Implement model name 'D' rule and modify call Module_CSS timing.

Files:
1. As follow commit history

Image version: D0.35.XX.XXXX.XX
Image checksum: XXXXXXXX

Hardware PWB P/N : XXXXXXX
Hardware Version : XXXXXXX
FolusWen 4 năm trước cách đây
mục cha
commit
cf41073a5e

+ 4 - 1
EVSE/Projects/AW-CCS/Apps/CCS/Module_CCS.c

@@ -1655,6 +1655,7 @@ void CP_Detection()
 
         //ftime(&EndTime);
         //DEBUG_PRINTF_EVCOMM_DETAIL("duration:%.02lf\n", DiffTimeb(StartTime, EndTime));
+        usleep(100000);
     }//while
 }
 
@@ -1723,6 +1724,7 @@ void PP_Detection()
         sleep(5);
         printf("V_pp = %.02f\n", TotalTmpVolt);
         #endif
+        usleep(100000);
     }//while
 }
 
@@ -2029,7 +2031,7 @@ void Error_Monitor()
             Update_V2G_Flow_Status(Other_Fault);
             End_Process();
         }
-
+        usleep(100000);
     }//while
 }
 
@@ -16391,5 +16393,6 @@ int main(int argc, char *argv[])
                 //null
             }
         }
+        usleep(100000);
     } //while
 }//main while

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

@@ -0,0 +1,615 @@
+/*
+ * 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_ */

+ 1188 - 0
EVSE/Projects/AW-CCS/Apps/LCM/Module_LcmControl.c

@@ -0,0 +1,1188 @@
+#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	"define.h"
+#include	"main.h"
+#include	"lcmComm.h"
+#include	"Image.h"
+#include	"qrcode.h"
+
+#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
+
+struct SysConfigAndInfo			*ShmSysConfigAndInfo;
+struct StatusCodeData 			*ShmStatusCodeData;
+struct Charger					*ShmCharger;
+
+void trim(char *s);
+int mystrcmp(char *p1,char *p2);
+void substr(char *dest, const char* src, unsigned int start, unsigned int cnt);
+void split(char **arr, char *str, const char *del);
+
+int Uart1Fd;
+QRCode qrcode;
+
+
+//=================================
+// 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(NULL);
+	tm=localtime(&CurrentTime);
+	gettimeofday(&tv, NULL); // get microseconds, 10^-6
+
+	if((ShmSysConfigAndInfo->SysConfig.ModelName != NULL) && (ShmSysConfigAndInfo->SysConfig.SerialNumber != NULL) && (strlen((char*)ShmSysConfigAndInfo->SysConfig.ModelName) >= 14))
+	{
+		sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld] - %s\" >> /Storage/SystemLog/[%04d.%02d]%s_%s_LcmSystemLog",
+					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,
+					ShmSysConfigAndInfo->SysConfig.ModelName,
+					ShmSysConfigAndInfo->SysConfig.SerialNumber);
+	}
+	else
+	{
+		sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d.%06ld] - %s\" >> /Storage/SystemLog/[%04d.%02d]LcmSystemLog",
+					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 trim(char *s)
+{
+    int i=0, j, k, l=0;
+
+    while((s[i]==' ')||(s[i]=='\t')||(s[i]=='\n'))
+        i++;
+
+    j = strlen(s)-1;
+    while((s[j]==' ')||(s[j]=='\t')||(s[j]=='\n'))
+        j--;
+
+    if(i==0 && j==strlen(s)-1) { }
+    else if(i==0) s[j+1] = '\0';
+    else {
+        for(k=i; k<=j; k++) s[l++] = s[k];
+        s[l] = '\0';
+    }
+}
+
+int mystrcmp(char *p1,char *p2)
+{
+    while(*p1==*p2)
+    {
+        if(*p1=='\0' || *p2=='\0')
+            break;
+        p1++;
+        p2++;
+    }
+    if(*p1=='\0' && *p2=='\0')
+        return(PASS);
+    else
+        return(FAIL);
+}
+
+void substr(char *dest, const char* src, unsigned int start, unsigned int cnt)
+{
+	strncpy(dest, src + start, cnt);
+	dest[cnt] = 0;
+}
+
+void split(char **arr, char *str, const char *del)
+{
+	char *s = strtok(str, del);
+
+	while(s != NULL)
+	{
+		*arr++ = s;
+		s = strtok(NULL, del);
+	}
+}
+
+//==========================================
+// Page routine
+//==========================================
+void page_booting()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_INIT);
+			break;
+	}
+}
+
+void page_idle()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 4, 8, 64, 64, IMG_ADDR_QRCODE);
+			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 70, 18, 70+48, 18+38, IMG_ADDR_TAP_RFID);
+
+			break;
+	}
+}
+
+void page_authorizing()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_VERIFY);
+			break;
+	}
+}
+
+void page_preparing()
+{
+	static uint8_t idxPage = 0;
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 15, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 10, 128, 54, IMG_ADDR_HANDSHAKE_1+idxPage);
+			break;
+	}
+
+	idxPage ^= 1;
+}
+
+void page_charging()
+{
+	uint8_t buf[128];
+	static uint8_t idxBatt = 0;
+	static uint8_t idxPage = 0;
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 19, 48, 36, IMG_ADDR_ICON_B0+idxBatt);
+			//dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);
+
+			switch(idxPage/PAGE_DISPLAY_PERIOD)
+			{
+				case 0:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
+					sprintf((char*)buf, " 000.0000");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
+					sprintf((char*)buf, " 000:00");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+				case 1:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
+					sprintf((char*)buf, "     0.45");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
+					sprintf((char*)buf, " 123.88");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+				default:
+					idxPage = 0;
+					break;
+			}
+
+			break;
+	}
+
+	if(idxBatt<5)
+		idxBatt++;
+	else
+		idxBatt =0;
+}
+
+void page_complete()
+{
+	uint8_t buf[128];
+	static uint8_t idxPage = 0;
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 20, 48, 36, IMG_ADDR_ICON_B100);
+			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);
+
+			switch(idxPage/PAGE_DISPLAY_PERIOD)
+			{
+				case 0:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
+					sprintf((char*)buf, " 000.0000");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
+					sprintf((char*)buf, " 000:00");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+				case 1:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
+					sprintf((char*)buf, "     0.45");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
+					sprintf((char*)buf, " 123.88");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+			}
+
+			break;
+	}
+}
+
+void page_terminating()
+{
+	uint8_t buf[128];
+	static uint8_t idxPage = 0;
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 0, 20, 48, 36, IMG_ADDR_ICON_B100);
+			dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 0, 40, 48, 64, IMG_ADDR_ICON_COMPLETE);
+
+			switch(idxPage/PAGE_DISPLAY_PERIOD)
+			{
+				case 0:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_ENERGY);
+					sprintf((char*)buf, " 000.0000");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_TIME);
+					sprintf((char*)buf, " 000:00");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+				case 1:
+					dispGraphicArea(Uart1Fd, AREAD_ID_1, YES, 48, 14, 70, 38, IMG_ADDR_ICON_COST);
+					sprintf((char*)buf, "     0.45");
+					dispCharacterArea(Uart1Fd, AREAD_ID_2, 72, 22, 128, 40, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					dispGraphicArea(Uart1Fd, AREAD_ID_3, YES, 48, 40, 81, 64, IMG_ADDR_ICON_PRICE);
+					sprintf((char*)buf, " 123.88");
+					dispCharacterArea(Uart1Fd, AREAD_ID_4, 84, 48, 128, 64, FONT_ASCII_6X8, buf, strlen((char*)buf));
+
+					idxPage++;
+					break;
+			}
+
+			break;
+	}
+}
+
+void page_alarm()
+{
+	uint8_t buf[128];
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 32, 24, 48, 40, IMG_ADDR_ICON_ALERT);
+			sprintf((char*)buf, "012336");
+			dispCharacterArea(Uart1Fd, AREAD_ID_1, 50, 26, 128, 40, FONT_ASCII_8X12, buf, strlen((char*)buf));
+			break;
+	}
+}
+
+void page_fault()
+{
+	uint8_t buf[128];
+
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicArea(Uart1Fd, AREAD_ID_0, YES, 32, 24, 48, 40, IMG_ADDR_ICON_ALERT);
+			sprintf((char*)buf, "012336");
+			dispCharacterArea(Uart1Fd, AREAD_ID_1, 50, 26, 128, 40, FONT_ASCII_8X12, buf, strlen((char*)buf));
+			break;
+	}
+}
+
+void page_maintain()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
+			break;
+	}
+}
+
+void page_update()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
+			break;
+	}
+}
+
+void page_reservation()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			break;
+	}
+}
+
+void page_booking()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			break;
+	}
+}
+
+void page_debug()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
+			break;
+	}
+}
+
+void page_unknown()
+{
+	switch(ShmSysConfigAndInfo->SysConfig.DefaultLanguage)
+	{
+		case LCD_LANG_CHT:
+		case LCD_LANG_CHS:
+		case LCD_LANG_JAPANESE:
+		case LCD_LANG_FRENCH:
+		case LCD_LANG_ITALIAN:
+		case LCD_LANG_SPANISH:
+		case LCD_LANG_GERMAN:
+		case LCD_LANG_DUTCH:
+		case LCD_LANG_NORWEGIAN:
+		case LCD_LANG_FINNISH:
+		case LCD_LANG_SWEDISH:
+		case LCD_LANG_SLOVENIAN:
+		case LCD_LANG_THAI:
+		case LCD_LANG_ENGLISH:
+		default:
+			dispGraphicConfig(Uart1Fd, AREAD_ID_0, YES, 0, 8, 128, 64);
+			dispGraphicPartial(Uart1Fd, AREAD_ID_0, YES, 0, 0, 0, 8, 128, 64, IMG_ADDR_MAINTIAN);
+			break;
+	}
+}
+
+void page_header()
+{
+	uint8_t buf[128];
+
+	if(sysFlag.isEnable4G)
+	{
+		// Drawing 4G signal strength
+		if((ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi == 0) || (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi == 99))
+		{
+			drawRfSignal(Uart1Fd, 0, YES);
+		}
+		else if((1 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 9))		// -95dBm ~ -111dBm
+		{
+			drawRfSignal(Uart1Fd, 1, YES);
+		}
+		else if((9 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 14))		// -85dBm ~ -95dBm
+		{
+			drawRfSignal(Uart1Fd, 2, YES);
+		}
+		else if((14 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 19))	// -75dBm ~ -85dBm
+		{
+			drawRfSignal(Uart1Fd, 3, YES);
+		}
+		else if((19 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi) && (ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi < 27))	// -60dBm ~ -75dBm
+		{
+			drawRfSignal(Uart1Fd, 4, YES);
+		}
+		else if((27 <= ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomRssi))	//  60dBm ~
+		{
+			drawRfSignal(Uart1Fd, 5, YES);
+		}
+		else
+		{
+			drawRfSignal(Uart1Fd, 0, YES);
+		}
+
+	}
+
+	if(sysFlag.isEnableWiFi)
+	{
+		// Drawing WIFI signal strength
+		if(ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi == 0)
+		{
+			drawRfSignal(Uart1Fd, 0, NO);
+		}
+		else if((-100 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -80))
+		{
+			drawRfSignal(Uart1Fd, 1, NO);
+		}
+		else if((-80 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -70))
+		{
+			drawRfSignal(Uart1Fd, 2, NO);
+		}
+		else if((-70 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -50))
+		{
+			drawRfSignal(Uart1Fd, 3, NO);
+		}
+		else if((-50 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi) && (ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi < -30))
+		{
+			drawRfSignal(Uart1Fd, 4, NO);
+		}
+		else if((-30 <= ShmSysConfigAndInfo->SysConfig.AthInterface.WifiRssi))
+		{
+			drawRfSignal(Uart1Fd, 5, NO);
+		}
+		else
+		{
+			drawRfSignal(Uart1Fd, 0, NO);
+		}
+
+	}
+
+	// Drawing ethernet status
+	dispGraphic(Uart1Fd, YES, 121-(sysFlag.isEnableWiFi?26:0)+(sysFlag.isEnable4G?26:0), 0, (ShmStatusCodeData->InfoCode.InfoEvents.bits.InternetDisconnectViaEthernet?IMG_ADDR_ICON_LAN_OFF:IMG_ADDR_ICON_LAN_ON));
+
+	// Unit price display
+	if(ShmSysConfigAndInfo->SysConfig.BillingData.isBilling)
+	{
+		sprintf((char*)buf, "%.2f %s/KWH", ShmSysConfigAndInfo->SysConfig.BillingData.Cur_fee, Currency[ShmSysConfigAndInfo->SysConfig.BillingData.Currency]);
+		dispCharacterArea(Uart1Fd, AREAD_ID_HEADER_PRICE, 0, 0, 30, 7, FONT_ASCII_4X6, buf, strlen((char*)buf));
+	}
+	else
+	{
+		dispCharacterArea(Uart1Fd, AREAD_ID_HEADER_PRICE, 0, 0, 30, 7, FONT_ASCII_4X6, (uint8_t*)"", strlen(""));
+	}
+
+	//dispCharacterConfig(Uart1Fd, AREAD_ID_HEADER, YES, 0, 0, 30, 7);
+	//dispCharacterScroll(Uart1Fd, AREAD_ID_HEADER, 0, 0, 40, 7, FONT_ASCII_4X6, NO, 25, (uint8_t*)"012334", strlen("012334"));
+	//dispCharacterBlink(Uart1Fd, AREAD_ID_HEADER, 0, 0, FONT_ASCII_4X6, 1, 100, (uint8_t*)"ABCDEFG", strlen("ABCDEFG"));
+}
+
+//==========================================
+// Init all share memory
+//==========================================
+int InitShareMemory()
+{
+	int result = PASS;
+	int MeterSMId;
+
+	//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
+    {}
+
+   	//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
+    {}
+
+   	//Initial ShmCharger
+	if ((MeterSMId = shmget(ShmChargerKey, sizeof(struct Charger), 0777)) < 0)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmget ShmChargerKey NG\r\n");
+		#endif
+		result = FAIL;
+	}
+	else if ((ShmCharger = shmat(MeterSMId, NULL, 0)) == (void *) -1)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("shmat ShmChargerKey NG\r\n");
+		#endif
+		result = FAIL;
+	}
+
+	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T'))
+		sysFlag.isEnable4G = ShmSysConfigAndInfo->SysConfig.TelecomInterface.TelcomEnabled;
+	else
+		sysFlag.isEnable4G = OFF;
+
+	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W'))
+		sysFlag.isEnableWiFi = ShmSysConfigAndInfo->SysConfig.AthInterface.WifiMode;
+	else
+		sysFlag.isEnableWiFi = OFF;
+
+	DEBUG_INFO("sysFlag.isEnable4G: %d\n", sysFlag.isEnable4G);
+	DEBUG_INFO("sysFlag.isEnableWiFi: %d\n", sysFlag.isEnableWiFi);
+
+    return result;
+}
+
+int InitComPort()
+{
+	int fd;
+	struct termios tios;
+
+	fd = open("/dev/ttyS3", O_RDWR);
+	if(fd<=0)
+	{
+		DEBUG_ERROR("open /dev/ttyS3 NG\n");
+
+		return -1;
+	}
+
+	ioctl (fd, TCGETS, &tios);
+	tios.c_cflag = B115200| CS8 | CLOCAL | CREAD;
+	tios.c_lflag = 0;
+	tios.c_iflag = 0;
+	tios.c_oflag = 0;
+	tios.c_cc[VMIN]=0;
+	tios.c_cc[VTIME]=(unsigned char)1;		// timeout 0.5 secod
+	tios.c_lflag=0;
+	tcflush(fd, TCIFLUSH);
+	ioctl (fd, TCSETS, &tios);
+
+	return fd;
+}
+
+int InitLcdModule()
+{
+	int result = FAIL;
+	uint8_t qrcodeData[qrcode_getBufferSize(SIZE_53X53)];
+	uint8_t qrImageRaw[((53/8)+1)*53];
+	uint16_t dataMaxLen = 512;
+	uint8_t qrcontent[196];
+
+	sprintf((char*)qrcontent, "%s%s", ShmSysConfigAndInfo->SysConfig.ModelName, ShmSysConfigAndInfo->SysConfig.SerialNumber);
+	qrcode_initText(&qrcode, qrcodeData, SIZE_53X53, 0, (char*)qrcontent);
+
+	// Power on LCD
+	setPower(Uart1Fd, ON);
+
+	// Clear LCD page
+	clearScreen(Uart1Fd, NO, 0, 0, 128, 64);
+
+	// Set LCE brightness
+	setContrast(Uart1Fd, 255, 255, 1);
+
+	// Display initial screen
+	page_booting();
+
+	// QR code raw data generate
+	memset(qrImageRaw, 0x00, ARRAY_SIZE(qrImageRaw));
+	for(uint16_t idxY = 0;idxY<qrcode.size;idxY++)
+	{
+		for(uint16_t idxX = 0;idxX<qrcode.size;idxX++)
+		{
+			if(qrcode_getModule(&qrcode, idxX, idxY))
+			{
+				//drawPoint(Uart1Fd, idxX, idxY);
+				qrImageRaw[(7*idxY) + (idxX/8)] |= (0x01<<(7-(idxX%8)));
+			}
+			else
+			{
+				qrImageRaw[(7*idxY) + (idxX/8)] &= ~(0x01<<(7-(idxX%8)));
+			}
+		}
+	}
+
+	// Upload image file
+	// QR Code
+	picUploadStart(Uart1Fd, IMG_ADDR_QRCODE, 53, 53);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(qrImageRaw)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(qrImageRaw)/dataMaxLen)) || ((idx == (ARRAY_SIZE(qrImageRaw)/dataMaxLen)) && ((ARRAY_SIZE(qrImageRaw)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_QRCODE, (idx*dataMaxLen), &qrImageRaw[idx*dataMaxLen], (idx<(ARRAY_SIZE(qrImageRaw)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(qrImageRaw)%dataMaxLen)) );
+	}
+
+	// LAN icon
+	for(uint8_t idxLAN=0;idxLAN<6;idxLAN++)
+	{
+		picUploadStart(Uart1Fd, IMG_ADDR_ICON_LAN_OFF+idxLAN, 7, 7);
+		for(uint8_t idx=0;idx<=ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen;idx++)
+		{
+			if((idx < (ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)) || ((idx == (ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)) && ((ARRAY_SIZE(LAN_Icon[idxLAN])%dataMaxLen)>0)))
+				picUploadData(Uart1Fd, IMG_ADDR_ICON_LAN_OFF+idxLAN, (idx*dataMaxLen), &LAN_Icon[idxLAN][idx*dataMaxLen], (idx<(ARRAY_SIZE(LAN_Icon[idxLAN])/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(LAN_Icon[idxLAN])%dataMaxLen)) );
+		}
+	}
+
+	// RF icon
+	for(uint8_t idxRF=0;idxRF<6;idxRF++)
+	{
+		picUploadStart(Uart1Fd, IMG_ADDR_RF_0+idxRF, 19, 7);
+		for(uint8_t idx=0;idx<=ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen;idx++)
+		{
+			if((idx < (ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)) || ((idx == (ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)) && ((ARRAY_SIZE(RF_Icon[idxRF])%dataMaxLen)>0)))
+				picUploadData(Uart1Fd, IMG_ADDR_RF_0+idxRF, (idx*dataMaxLen), &RF_Icon[idxRF][idx*dataMaxLen], (idx<(ARRAY_SIZE(RF_Icon[idxRF])/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(RF_Icon[idxRF])%dataMaxLen)) );
+		}
+	}
+
+	// Init image
+	picUploadStart(Uart1Fd, IMG_ADDR_INIT, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_init)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_init)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_init)/dataMaxLen)) && ((ARRAY_SIZE(img_init)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_INIT, (idx*dataMaxLen), &img_init[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_init)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_init)%dataMaxLen)) );
+	}
+
+	// RIFD image
+	picUploadStart(Uart1Fd, IMG_ADDR_TAP_RFID, 48, 38);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_rfid)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_rfid)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_rfid)/dataMaxLen)) && ((ARRAY_SIZE(img_rfid)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_TAP_RFID, (idx*dataMaxLen), &img_rfid[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_rfid)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_rfid)%dataMaxLen)) );
+	}
+
+	// Handshake 1 image
+	picUploadStart(Uart1Fd, IMG_ADDR_HANDSHAKE_1, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_handshake_1)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_handshake_1)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_handshake_1)/dataMaxLen)) && ((ARRAY_SIZE(img_handshake_1)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_HANDSHAKE_1, (idx*dataMaxLen), &img_handshake_1[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_handshake_1)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_handshake_1)%dataMaxLen)) );
+	}
+
+	// Handshake 2 image
+	picUploadStart(Uart1Fd, IMG_ADDR_HANDSHAKE_2, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_handshake_2)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_handshake_2)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_handshake_2)/dataMaxLen)) && ((ARRAY_SIZE(img_handshake_2)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_HANDSHAKE_2, (idx*dataMaxLen), &img_handshake_2[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_handshake_2)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_handshake_2)%dataMaxLen)) );
+	}
+
+	// Maintain image
+	picUploadStart(Uart1Fd, IMG_ADDR_MAINTIAN, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_maintain)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_maintain)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_maintain)/dataMaxLen)) && ((ARRAY_SIZE(img_maintain)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_MAINTIAN, (idx*dataMaxLen), &img_maintain[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_maintain)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_maintain)%dataMaxLen)) );
+	}
+
+	// Verify image
+	picUploadStart(Uart1Fd, IMG_ADDR_VERIFY, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_verify)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify)/dataMaxLen)) && ((ARRAY_SIZE(img_verify)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_VERIFY, (idx*dataMaxLen), &img_verify[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify)%dataMaxLen)) );
+	}
+
+	// Verify OK image
+	picUploadStart(Uart1Fd, IMG_ADDR_VERIFYOK, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify_ok)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_verify_ok)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify_ok)/dataMaxLen)) && ((ARRAY_SIZE(img_verify_ok)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_VERIFYOK, (idx*dataMaxLen), &img_verify_ok[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify_ok)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify_ok)%dataMaxLen)) );
+	}
+
+	// Verify fail image
+	picUploadStart(Uart1Fd, IMG_ADDR_VERIFYFAIL, 128, 64);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_verify_fail)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_verify_fail)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_verify_fail)/dataMaxLen)) && ((ARRAY_SIZE(img_verify_fail)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_VERIFYFAIL, (idx*dataMaxLen), &img_verify_fail[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_verify_fail)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_verify_fail)%dataMaxLen)) );
+	}
+
+	// Icon alert image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_ALERT, 16, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_alert)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_alert)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_alert)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_alert)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_ALERT, (idx*dataMaxLen), &img_icon_alert[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_alert)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_alert)%dataMaxLen)) );
+	}
+
+	// Icon energy image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_ENERGY, 24, 24);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_energy)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_energy)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_energy)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_energy)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_ENERGY, (idx*dataMaxLen), &img_icon_energy[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_energy)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_energy)%dataMaxLen)) );
+	}
+
+	// Icon energy image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_COST, 24, 24);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_cost)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_cost)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_cost)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_cost)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_COST, (idx*dataMaxLen), &img_icon_cost[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_cost)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_cost)%dataMaxLen)) );
+	}
+
+	// Icon time image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_TIME, 24, 24);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_time)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_time)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_time)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_time)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_TIME, (idx*dataMaxLen), &img_icon_time[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_time)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_time)%dataMaxLen)) );
+	}
+
+	// Icon price image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_PRICE, 33, 24);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_price)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_price)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_price)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_price)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_PRICE, (idx*dataMaxLen), &img_icon_price[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_price)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_price)%dataMaxLen)) );
+	}
+
+	// Icon battery 0% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B0, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b0)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b0)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b0)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b0)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B0, (idx*dataMaxLen), &img_icon_b0[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b0)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b0)%dataMaxLen)) );
+	}
+
+	// Icon battery 20% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B20, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b20)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b20)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b20)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b20)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B20, (idx*dataMaxLen), &img_icon_b20[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b20)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b20)%dataMaxLen)) );
+	}
+
+	// Icon battery 40% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B40, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b40)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b40)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b40)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b40)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B40, (idx*dataMaxLen), &img_icon_b40[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b40)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b40)%dataMaxLen)) );
+	}
+
+	// Icon battery 60% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B60, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b60)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b60)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b60)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b60)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B60, (idx*dataMaxLen), &img_icon_b60[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b60)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b60)%dataMaxLen)) );
+	}
+
+	// Icon battery 80% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B80, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b80)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b80)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b80)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b80)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B80, (idx*dataMaxLen), &img_icon_b80[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b80)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b80)%dataMaxLen)) );
+	}
+
+	// Icon battery 100% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_B100, 48, 16);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_b100)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_b100)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_b100)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_b100)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_B100, (idx*dataMaxLen), &img_icon_b100[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_b100)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_b100)%dataMaxLen)) );
+	}
+
+	// Icon battery 100% image
+	picUploadStart(Uart1Fd, IMG_ADDR_ICON_COMPLETE, 48, 18);
+	for(uint8_t idx=0;idx<=ARRAY_SIZE(img_icon_complete)/dataMaxLen;idx++)
+	{
+		if((idx < (ARRAY_SIZE(img_icon_complete)/dataMaxLen)) || ((idx == (ARRAY_SIZE(img_icon_complete)/dataMaxLen)) && ((ARRAY_SIZE(img_icon_complete)%dataMaxLen)>0)))
+			picUploadData(Uart1Fd, IMG_ADDR_ICON_COMPLETE, (idx*dataMaxLen), &img_icon_complete[idx*dataMaxLen], (idx<(ARRAY_SIZE(img_icon_complete)/dataMaxLen)?dataMaxLen:(ARRAY_SIZE(img_icon_complete)%dataMaxLen)) );
+	}
+
+	return result;
+}
+
+//================================================
+// Main process
+//================================================
+int main(void)
+{
+	uint8_t previousMode = 0xff;
+	uint8_t previousLan = 0xff;
+
+	if(InitShareMemory() == FAIL)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("InitShareMemory NG\n");
+		#endif
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
+		}
+		sleep(5);
+		return FAIL;
+	}
+
+	Uart1Fd=InitComPort();
+	if(Uart1Fd<0)
+	{
+		#ifdef SystemLogMessage
+		DEBUG_ERROR("InitComPort NG\n");
+		#endif
+		if(ShmStatusCodeData!=NULL)
+		{
+			ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed=1;
+		}
+		sleep(5);
+		return FAIL;
+	}
+	else
+	{
+		InitLcdModule();
+	}
+	DEBUG_INFO("Initial completed\n");
+
+	for(;;)
+	{
+		// Clear LCD if page change.
+		if((previousMode != ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus) ||
+		   (previousLan != ShmSysConfigAndInfo->SysConfig.DefaultLanguage))
+		{
+			// Clear screen
+			clearScreen(Uart1Fd, NO, 0, 0, 128, 64);
+
+			previousMode = ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus;
+			previousLan = ShmSysConfigAndInfo->SysConfig.DefaultLanguage;
+		}
+
+		switch(ShmSysConfigAndInfo->SysInfo.AcChargingData[ShmCharger->gun_selectd].SystemStatus)
+		{
+			case SYS_MODE_BOOTING:
+				page_booting();
+				break;
+			case SYS_MODE_IDLE:
+				page_idle();
+				break;
+			case SYS_MODE_AUTHORIZING:
+				page_authorizing();
+				break;
+			case SYS_MODE_PREPARING:
+				page_preparing();
+				break;
+			case SYS_MODE_CHARGING:
+				page_charging();
+				break;
+			case SYS_MODE_TERMINATING:
+				page_terminating();
+				break;
+			case SYS_MODE_COMPLETE:
+				page_complete();
+				break;
+			case SYS_MODE_ALARM:
+				page_alarm();
+				break;
+			case SYS_MODE_FAULT:
+				page_fault();
+				break;
+			case SYS_MODE_MAINTAIN:
+				page_maintain();
+				break;
+			case SYS_MODE_UPDATE:
+				page_update();
+				break;
+			case SYS_MODE_RESERVATION:
+				page_reservation();
+				break;
+			case SYS_MODE_BOOKING:
+				page_booking();
+				break;
+			case SYS_MODE_DEBUG:
+				page_debug();
+				break;
+			default:
+				page_unknown();
+				break;
+		}
+
+		page_header();
+
+		usleep(1000000);
+	}
+
+	return FAIL;
+}

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

@@ -0,0 +1,859 @@
+/*
+ * 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[8+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);
+
+	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[29+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);
+
+	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;
+}
+
+
+
+
+

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

@@ -0,0 +1,152 @@
+/*
+ * 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, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, __FILE__, __LINE__, __FUNCTION__, ##args)
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, __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);
+
+typedef struct SYS_FLAG
+{
+	uint8_t isEnable4G:1;
+	uint8_t isEnableWiFi:1;
+}SYS_FLAG;
+
+extern SYS_FLAG sysFlag;
+
+#endif /* LCMCOMM_H_ */

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

@@ -0,0 +1,852 @@
+/**
+ * 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) {
+
+}
+*/

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

@@ -0,0 +1,106 @@
+/**
+ * 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_ */

+ 8 - 1
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
+apps: Module_InternalComm_Task Module_FactoryConfig_Task Module_AlarmDetect_Task Module_CSU_Task Module_Speaker_Task Module_CCS_Task Module_LcmControl_Task
 
 Module_InternalComm_Task:
 	@echo "===== Module_InternalComm_Task ==================================="
@@ -104,6 +104,13 @@ Module_CCS_Task:
 	rm -f *.o
 	mv -f Module_CCS ../Images/root
 
+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
+	rm -f *.o	
+	mv -f Module_LcmControl ../Images/root
+
 CopyFile: 
 	rm -rfv ../Images/root
 	mkdir -p ../Images/root

+ 1 - 1
EVSE/Projects/AW-CCS/Apps/Module_InternalComm.c

@@ -49,7 +49,7 @@ struct PrimaryMcuData			*ShmPrimaryMcuData;
 struct OCPP16Data 				*ShmOCPP16Data;
 struct Charger					*ShmCharger;
 
-uint16_t						stepIndex, logIndex;
+uint16_t						stepIndex=21, logIndex;
 long long						tsLast, tsNow, tsPrintLog[2];
 double							tmpPowerConsumption;
 

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


+ 20 - 12
EVSE/Projects/AW-CCS/Apps/main.c

@@ -960,23 +960,23 @@ void InitEthernet()
 	if(isInterfaceUp("eth0")==PASS)
 	{
 		memset(tmpbuf,0,256);
-		sprintf(tmpbuf,"/sbin/ifconfig eth0 %s netmask %s up",
+		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 ",
+		sprintf(tmpbuf,"route add default gw %s eth0 &",
 		ShmSysConfigAndInfo->SysConfig.Eth0Interface.EthGatewayAddress);
 		system(tmpbuf);
-		system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up");
-		system("ifconfig lo up");
+		system("/sbin/ifconfig eth0:1 192.168.201.201 netmask 255.255.255.248 up &");
+		system("ifconfig lo up &");
 	}
 
 	if(isInterfaceUp("eth1")==PASS)
 	{
 		//Init Eth1 for administrator tool
 		memset(tmpbuf,0,256);
-		sprintf(tmpbuf,"/sbin/ifconfig eth1 %s netmask %s up",
+		sprintf(tmpbuf,"/sbin/ifconfig eth1 %s netmask %s up &",
 		ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthIpAddress,
 		ShmSysConfigAndInfo->SysConfig.Eth1Interface.EthSubmaskAddress);
 		system(tmpbuf);
@@ -1108,6 +1108,7 @@ int SpawnTask()
 	system ("pkill Module_InternalComm");
 	system ("pkill Module_Speaker");
 	system ("pkill Module_ProduceUtils");
+	system ("pkill Module_LcmControl");
 
 	if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T')
 	{
@@ -1132,6 +1133,7 @@ int SpawnTask()
 	system ("/root/Module_InternalComm &");
 	system ("/root/Module_Speaker &");
 	system ("/root/Module_ProduceUtils &");
+	system ("/root/Module_LcmControl &");
 
 	return PASS;
 }
@@ -1142,7 +1144,7 @@ int InitQca7000()
 
 	system("/sbin/insmod /lib/qcaspi.ko");
 	sleep(2);
-	system("/sbin/ifconfig eth1 192.168.0.11 netmask 255.255.255.0 up");
+	system("/sbin/ifconfig eth1 192.168.253.11 netmask 255.255.255.0 up");
 	sleep(1);
 
 	return result;
@@ -1193,8 +1195,6 @@ int Initialization()
 	return result;
 }
 
-
-
 //=====================================================
 // Common routine
 //=====================================================
@@ -1360,7 +1360,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.34.00.0000.00");
+	sprintf((char*)ShmSysConfigAndInfo->SysInfo.CsuRootFsFwRev, "D0.35.00.0000.00");
 
 	// Get AC connector type from model name
 	for(uint8_t idx=0;idx<3;idx++)
@@ -2117,7 +2117,7 @@ int getEth0MacAddress()
 //==========================================
 void checkTask()
 {
-	if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T')
+	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'T') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D'))
 	{
 		if(system("pidof -s Module_4g > /dev/null") != 0)
 		{
@@ -2125,7 +2125,8 @@ void checkTask()
 			system("/root/Module_4g &");
 		}
 	}
-	else if(ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W')
+
+	if((ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'W') || (ShmSysConfigAndInfo->SysConfig.ModelName[10] == 'D'))
 	{
 		if(system("pidof -s Module_Wifi > /dev/null") != 0)
 		{
@@ -2172,6 +2173,12 @@ void checkTask()
 		DEBUG_INFO("Module_ProduceUtils not running, restart it.\n");
 		system ("/root/Module_ProduceUtils &");
 	}
+
+	if(system("pidof -s Module_LcmControl > /dev/null") != 0)
+	{
+		DEBUG_INFO("Module_LcmControl not running, restart it.\n");
+		system ("/root/Module_LcmControl &");
+	}
 }
 
 //===============================================
@@ -2566,6 +2573,7 @@ int main(void)
 						ShmCharger->gun_info[gun_index].primaryMcuCp_Pwn_Duty.max_current = CCS_PWM_DUTY_100;
 						ShmCharger->gun_info[gun_index].mcuFlag.isSetCpPwmDuty = ON;
 						ShmCharger->gun_info[gun_index].isDoEvReadyOnce = OFF;
+						system("pkill Module_CCS");
 					}
 
 					if(((ShmSysConfigAndInfo->SysConfig.AuthorisationMode == AUTH_MODE_DISABLE) && (ShmSysConfigAndInfo->SysInfo.AcChargingData[gun_index].PilotState == CP_STATE_B)) ||
@@ -2758,7 +2766,7 @@ int main(void)
 						setLedMotion(gun_index,LED_ACTION_AUTHED);
 						ShmCharger->gun_info[gun_index].ccsHandshakeState = HANDSHAKE_DUTY_5;	
 
-						system("/root/Module_CCS");
+						system("/root/Module_CCS &");
 					}
 					
 					// If control pilot detect Bx, skip watch dog time out.