/*
运行:sudo ./12864
编译:gcc 12864.c -o 12864 -L lib -l wiringPi (需已安装wiringPi)
by:WuSiYu
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <wiringPi.h>
#include <iconv.h>
#include <sys/timeb.h>
#define LCD_RS 4 //显示屏控制线
#define LCD_RW 5
#define LCD_EN 1
#define D1 30 //显示屏数据线
#define D2 21
#define D3 22
#define D4 23
#define D5 24
#define D6 25
#define D7 26
#define D8 27
char u2g_out[255];
int this_line_data[768];
struct timeb tp;
char this_line[3200];
char buf[20];
int i,len,s,data_s,n;
FILE *data_fp;
/*===================================================================
功能:编码转换
输入:UTF8
输出:GB2312
====================================================================*/
int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen){
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0) return -1;
if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
int u2g(char *inbuf,int inlen,char *outbuf,int outlen){
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
/*===================================================================
功能:总线写入
输入:十六进制数据
输出:无
====================================================================*/
void bus_write(unsigned char data){
int t[10];
int f=0,i=0,d=data;
//进制转换
for(i=0;i<8;i++){
t[i]=data%2;
data=data/2;
}
//输出
digitalWrite(D1,t[0]);
digitalWrite(D2,t[1]);
digitalWrite(D3,t[2]);
digitalWrite(D4,t[3]);
digitalWrite(D5,t[4]);
digitalWrite(D6,t[5]);
digitalWrite(D7,t[6]);
digitalWrite(D8,t[7]);
}
/*===================================================================
功能:检查LCD忙状态
输入:无
输出:lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。
====================================================================*/
void chk_busy(){//检查忙位
digitalWrite(LCD_RS,0);
digitalWrite(LCD_RW,1);
digitalWrite(LCD_EN,1);
bus_write(0xff);
pinMode(D8, INPUT);
while(digitalRead(D8));
pinMode(D8, OUTPUT);
digitalWrite(LCD_EN,0);
}
/*====================================================================
功能:写命令
输入:8位数据
输出:无
=====================================================================*/
void WriteCmd_LCD12864(unsigned char cmdcode){
chk_busy();
digitalWrite(LCD_RS,0);
digitalWrite(LCD_RW,0);
digitalWrite(LCD_EN,1);
// delay(5);
bus_write(cmdcode);
digitalWrite(LCD_EN,0);
// delay(5);
}
/*====================================================================
功能:写数据
输入:8位数据
输出:无
=====================================================================*/
void WriteData_LCD12864(unsigned char Dispdata){
chk_busy();
digitalWrite(LCD_RS,1);
digitalWrite(LCD_RW,0);
digitalWrite(LCD_EN,1);
// delay(5);
bus_write(Dispdata);
digitalWrite(LCD_EN,0);
// delay(5);
}
/*==========================================================================
功能:发送字符串
输入:地址,字符串
输出:无
===========================================================================*/
void WriteWord_LCD12864(unsigned char a,unsigned char *d){//向LCD指定位置发送一个字符串,长度64字符之内。
unsigned char *s;
s=u2g_out;
WriteCmd_LCD12864(a);
while(*s>0){
WriteData_LCD12864(*s);
s++;
}
}
/*==========================================================================
功能:发送字符串2
输入:字符串
输出:无
===========================================================================*/
void WriteWord_LCD12864_2(unsigned char *d){//向LCD发送一屏字符串,长度64字符之内。
int i=0;
unsigned char *s;
s=u2g_out;
WriteCmd_LCD12864(0x80);
while(*s>0){
WriteData_LCD12864(*s);
s++;
i++;
if(i==16){
WriteCmd_LCD12864(0x90);
}
if(i==32){
WriteCmd_LCD12864(0x88);
}
if(i==48){
WriteCmd_LCD12864(0x98);
}
}
}
void Clean_LCD12864(unsigned char c,unsigned char d){
unsigned char l,r;
WriteCmd_LCD12864(0x34);
for(l=0;l<32;l++){
WriteCmd_LCD12864(0x80+l);
WriteCmd_LCD12864(0x80);
for(r=0;r<16;r++){
WriteData_LCD12864(c);
WriteData_LCD12864(d);
}
}
}
void Show_LCD12864(void){
unsigned char l,r;
WriteCmd_LCD12864(0x36);
for(l=0;l<32;l++){
WriteCmd_LCD12864(0x80+l);
WriteCmd_LCD12864(0x80+1);
for(r=0;r<6;r++){
WriteData_LCD12864(this_line_data[12*l+r*2]);
WriteData_LCD12864(this_line_data[12*l+r*2+1]);
}
for(r=0;r<4;r++){
WriteData_LCD12864(0x00);
}
for(r=0;r<6;r++){
WriteData_LCD12864(this_line_data[12*32+12*l+r*2]);
WriteData_LCD12864(this_line_data[12*32+12*l+r*2+1]);
}
}
}
/*==========================================================================
功能:初始化LCD
输入:无
输出:无
===========================================================================*/
void Init_LCD12864(void){ //初始化LCD屏
pinMode(D1, OUTPUT); //设置GPIO
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);
pinMode(LCD_RS, OUTPUT);
pinMode(LCD_RW, OUTPUT);
pinMode(LCD_EN, OUTPUT);
WriteCmd_LCD12864(0x38); //选择8bit数据流
delay(20);
WriteCmd_LCD12864(0x01); //清除显示,并且设定地址指针为00H
delay(20);
WriteCmd_LCD12864(0x0c); //开显示(无游标、不反白)
delay(20);
}
void do_it(void){
fgets(this_line
,3200,data_fp
);
ftime(&tp);
n++;
i=0;
data_s=0;
s=0;
for(i=0;i<len;i++){
if(this_line[i]=='-'){
this_line_data
[data_s
]=atoi(buf
); buf[0]=' ';
buf[1]=' ';
buf[2]=' ';
s=0;
data_s++;
}else{
buf[s]=this_line[i];
s++;
}
}
WriteCmd_LCD12864(0x36);
Show_LCD12864();
WriteCmd_LCD12864(0x36);
}
int main (int args, char *argv[]){
int last=0,img;
wiringPiSetup();
Init_LCD12864();
WriteCmd_LCD12864(0x01);
WriteWord_LCD12864(0x80,"Hello LCD12864");
delay(1000);
WriteCmd_LCD12864(0x01);
WriteCmd_LCD12864(0x36);
Clean_LCD12864(0x00,0x00);
WriteCmd_LCD12864(0x36);
data_fp
=fopen("all_in_one.h","r");
ftime(&tp);
last=tp.millitm;
while(1){
ftime(&tp);
if(last>tp.millitm){
if(1000-last+tp.millitm>=33){
// ftime(&tp);
// last=tp.millitm;
last=43-(1000-last);
delay(10);
do_it();
}
}else{
if(tp.millitm-last>=33){
// ftime(&tp);
// last=tp.millitm;
last+=33;
do_it();
}
}
}
}
LyoKCei/kOihjO+8mnN1ZG8gLi8xMjg2NAoJ57yW6K+R77yaZ2NjIDEyODY0LmMgLW8gMTI4NjQgLUwgbGliIC1sIHdpcmluZ1BpICjpnIDlt7Llronoo4V3aXJpbmdQaSkKCWJ577yaV3VTaVl1CiovCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdGRpbnQuaD4KI2luY2x1ZGUgPHdpcmluZ1BpLmg+CiNpbmNsdWRlIDxpY29udi5oPgojaW5jbHVkZSA8c3lzL3RpbWViLmg+CgoKI2RlZmluZSBMQ0RfUlMgNCAvL+aYvuekuuWxj+aOp+WItue6vwojZGVmaW5lIExDRF9SVyA1CiNkZWZpbmUgTENEX0VOIDEKCiNkZWZpbmUgRDEgMzAgLy/mmL7npLrlsY/mlbDmja7nur8KI2RlZmluZSBEMiAyMQojZGVmaW5lIEQzIDIyCiNkZWZpbmUgRDQgMjMKI2RlZmluZSBENSAyNAojZGVmaW5lIEQ2IDI1CiNkZWZpbmUgRDcgMjYKI2RlZmluZSBEOCAyNwoKY2hhciB1Mmdfb3V0WzI1NV07IAoKaW50IHRoaXNfbGluZV9kYXRhWzc2OF07CgpzdHJ1Y3QgdGltZWIgdHA7CgpjaGFyIHRoaXNfbGluZVszMjAwXTsKY2hhciBidWZbMjBdOwppbnQgaSxsZW4scyxkYXRhX3MsbjsKCkZJTEUgKmRhdGFfZnA7Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQrlip/og73vvJrnvJbnoIHovazmjaIK6L6T5YWl77yaVVRGOArovpPlh7rvvJpHQjIzMTIKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwppbnQgY29kZV9jb252ZXJ0KGNoYXIgKmZyb21fY2hhcnNldCxjaGFyICp0b19jaGFyc2V0LGNoYXIgKmluYnVmLGludCBpbmxlbixjaGFyICpvdXRidWYsaW50IG91dGxlbil7CglpY29udl90IGNkOwoJaW50IHJjOwoJY2hhciAqKnBpbiA9ICZpbmJ1ZjsKCWNoYXIgKipwb3V0ID0gJm91dGJ1ZjsKCgljZCA9IGljb252X29wZW4odG9fY2hhcnNldCxmcm9tX2NoYXJzZXQpOwoJaWYgKGNkPT0wKSByZXR1cm4gLTE7CgltZW1zZXQob3V0YnVmLDAsb3V0bGVuKTsKCWlmIChpY29udihjZCxwaW4sJmlubGVuLHBvdXQsJm91dGxlbik9PS0xKSByZXR1cm4gLTE7CglpY29udl9jbG9zZShjZCk7CglyZXR1cm4gMDsKfQoKaW50IHUyZyhjaGFyICppbmJ1ZixpbnQgaW5sZW4sY2hhciAqb3V0YnVmLGludCBvdXRsZW4peyAKCXJldHVybiBjb2RlX2NvbnZlcnQoInV0Zi04IiwiZ2IyMzEyIixpbmJ1ZixpbmxlbixvdXRidWYsb3V0bGVuKTsgCn0gCgovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0K5Yqf6IO977ya5oC757q/5YaZ5YWlCui+k+WFpe+8muWNgeWFrei/m+WItuaVsOaNrgrovpPlh7rvvJrml6AKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwp2b2lkIGJ1c193cml0ZSh1bnNpZ25lZCBjaGFyIGRhdGEpewoJaW50IHRbMTBdOwoJaW50IGY9MCxpPTAsZD1kYXRhOwoKCS8v6L+b5Yi26L2s5o2iCglmb3IoaT0wO2k8ODtpKyspewoJCXRbaV09ZGF0YSUyOwoJCWRhdGE9ZGF0YS8yOwoJfQoJCgkvL+i+k+WHugoJZGlnaXRhbFdyaXRlKEQxLHRbMF0pOwoJZGlnaXRhbFdyaXRlKEQyLHRbMV0pOwoJZGlnaXRhbFdyaXRlKEQzLHRbMl0pOwoJZGlnaXRhbFdyaXRlKEQ0LHRbM10pOwoJZGlnaXRhbFdyaXRlKEQ1LHRbNF0pOwoJZGlnaXRhbFdyaXRlKEQ2LHRbNV0pOwoJZGlnaXRhbFdyaXRlKEQ3LHRbNl0pOwoJZGlnaXRhbFdyaXRlKEQ4LHRbN10pOwp9Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQrlip/og73vvJrmo4Dmn6VMQ0Tlv5nnirbmgIEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCui+k+WFpe+8muaXoArovpPlh7rvvJpsY2RfYnVzeeS4ujHml7bvvIzlv5nvvIznrYnlvoXjgIJsY2QtYnVzeeS4ujDml7Ys6Zey77yM5Y+v5YaZ5oyH5Luk5LiO5pWw5o2u44CCICAgICAgCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8Kdm9pZCBjaGtfYnVzeSgpey8v5qOA5p+l5b+Z5L2NCglkaWdpdGFsV3JpdGUoTENEX1JTLDApOwoJZGlnaXRhbFdyaXRlKExDRF9SVywxKTsKCWRpZ2l0YWxXcml0ZShMQ0RfRU4sMSk7CglidXNfd3JpdGUoMHhmZik7CglwaW5Nb2RlKEQ4LCBJTlBVVCk7Cgl3aGlsZShkaWdpdGFsUmVhZChEOCkpOwoJcGluTW9kZShEOCwgT1VUUFVUKTsKCWRpZ2l0YWxXcml0ZShMQ0RfRU4sMCk7Cn0KLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQrlip/og73vvJrlhpnlkb3ku6QK6L6T5YWl77yaOOS9jeaVsOaNrgrovpPlh7rvvJrml6AKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8Kdm9pZCBXcml0ZUNtZF9MQ0QxMjg2NCh1bnNpZ25lZCBjaGFyIGNtZGNvZGUpewoJY2hrX2J1c3koKTsKCWRpZ2l0YWxXcml0ZShMQ0RfUlMsMCk7CglkaWdpdGFsV3JpdGUoTENEX1JXLDApOwoJZGlnaXRhbFdyaXRlKExDRF9FTiwxKTsKCS8vIGRlbGF5KDUpOwoJYnVzX3dyaXRlKGNtZGNvZGUpOwoJZGlnaXRhbFdyaXRlKExDRF9FTiwwKTsKCS8vIGRlbGF5KDUpOwp9Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0K5Yqf6IO977ya5YaZ5pWw5o2uCui+k+WFpe+8mjjkvY3mlbDmja4K6L6T5Ye677ya5pegCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCnZvaWQgV3JpdGVEYXRhX0xDRDEyODY0KHVuc2lnbmVkIGNoYXIgRGlzcGRhdGEpewoJY2hrX2J1c3koKTsKCWRpZ2l0YWxXcml0ZShMQ0RfUlMsMSk7CglkaWdpdGFsV3JpdGUoTENEX1JXLDApOwoJZGlnaXRhbFdyaXRlKExDRF9FTiwxKTsKCS8vIGRlbGF5KDUpOwoJYnVzX3dyaXRlKERpc3BkYXRhKTsKCWRpZ2l0YWxXcml0ZShMQ0RfRU4sMCk7CgkvLyBkZWxheSg1KTsKfQovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CuWKn+iDve+8muWPkemAgeWtl+espuS4sgrovpPlhaXvvJrlnLDlnYDvvIzlrZfnrKbkuLIK6L6T5Ye677ya5pegCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCnZvaWQgV3JpdGVXb3JkX0xDRDEyODY0KHVuc2lnbmVkIGNoYXIgYSx1bnNpZ25lZCBjaGFyICpkKXsvL+WQkUxDROaMh+WumuS9jee9ruWPkemAgeS4gOS4quWtl+espuS4sizplb/luqY2NOWtl+espuS5i+WGheOAggoJdW5zaWduZWQgY2hhciAqczsKCXUyZyhkLHN0cmxlbihkKSx1Mmdfb3V0LDI1NSk7CglzPXUyZ19vdXQ7CglXcml0ZUNtZF9MQ0QxMjg2NChhKTsKCXdoaWxlKCpzPjApewoJCVdyaXRlRGF0YV9MQ0QxMjg2NCgqcyk7IAoJCXMrKzsKCX0KfQovKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CuWKn+iDve+8muWPkemAgeWtl+espuS4sjIK6L6T5YWl77ya5a2X56ym5LiyCui+k+WHuu+8muaXoAo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwp2b2lkIFdyaXRlV29yZF9MQ0QxMjg2NF8yKHVuc2lnbmVkIGNoYXIgKmQpey8v5ZCRTENE5Y+R6YCB5LiA5bGP5a2X56ym5LiyLOmVv+W6pjY05a2X56ym5LmL5YaF44CCCglpbnQgaT0wOwoJdW5zaWduZWQgY2hhciAqczsKCXUyZyhkLHN0cmxlbihkKSx1Mmdfb3V0LDI1NSk7CglzPXUyZ19vdXQ7CglXcml0ZUNtZF9MQ0QxMjg2NCgweDgwKTsKCXdoaWxlKCpzPjApewoJCVdyaXRlRGF0YV9MQ0QxMjg2NCgqcyk7IAoJCXMrKzsKCQlpKys7CgkJaWYoaT09MTYpewoJCQlXcml0ZUNtZF9MQ0QxMjg2NCgweDkwKTsKCQl9CgkJaWYoaT09MzIpewoJCQlXcml0ZUNtZF9MQ0QxMjg2NCgweDg4KTsKCQl9CgkJaWYoaT09NDgpewoJCQlXcml0ZUNtZF9MQ0QxMjg2NCgweDk4KTsKCQl9Cgl9Cn0Kdm9pZCBDbGVhbl9MQ0QxMjg2NCh1bnNpZ25lZCBjaGFyIGMsdW5zaWduZWQgY2hhciBkKXsKCXVuc2lnbmVkIGNoYXIgbCxyOwoJV3JpdGVDbWRfTENEMTI4NjQoMHgzNCk7Cglmb3IobD0wO2w8MzI7bCsrKXsKCQlXcml0ZUNtZF9MQ0QxMjg2NCgweDgwK2wpOwoJCVdyaXRlQ21kX0xDRDEyODY0KDB4ODApOwoJCWZvcihyPTA7cjwxNjtyKyspewoJCQlXcml0ZURhdGFfTENEMTI4NjQoYyk7CgkJCVdyaXRlRGF0YV9MQ0QxMjg2NChkKTsKCQl9Cgl9Cn0Kdm9pZCBTaG93X0xDRDEyODY0KHZvaWQpewoJdW5zaWduZWQgY2hhciBsLHI7CglXcml0ZUNtZF9MQ0QxMjg2NCgweDM2KTsKCWZvcihsPTA7bDwzMjtsKyspewoJCVdyaXRlQ21kX0xDRDEyODY0KDB4ODArbCk7CgkJV3JpdGVDbWRfTENEMTI4NjQoMHg4MCsxKTsKCQlmb3Iocj0wO3I8NjtyKyspewoJCQlXcml0ZURhdGFfTENEMTI4NjQodGhpc19saW5lX2RhdGFbMTIqbCtyKjJdKTsKCQkJV3JpdGVEYXRhX0xDRDEyODY0KHRoaXNfbGluZV9kYXRhWzEyKmwrcioyKzFdKTsKCQl9CgkJCgkJZm9yKHI9MDtyPDQ7cisrKXsKCQkJV3JpdGVEYXRhX0xDRDEyODY0KDB4MDApOwoJCX0KCgkJZm9yKHI9MDtyPDY7cisrKXsKCQkJV3JpdGVEYXRhX0xDRDEyODY0KHRoaXNfbGluZV9kYXRhWzEyKjMyKzEyKmwrcioyXSk7CgkJCVdyaXRlRGF0YV9MQ0QxMjg2NCh0aGlzX2xpbmVfZGF0YVsxMiozMisxMipsK3IqMisxXSk7CgkJfQoJfQp9Ci8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0K5Yqf6IO977ya5Yid5aeL5YyWTENECui+k+WFpe+8muaXoArovpPlh7rvvJrml6AKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8Kdm9pZCBJbml0X0xDRDEyODY0KHZvaWQpewkJCS8v5Yid5aeL5YyWTENE5bGPCglwaW5Nb2RlKEQxLCBPVVRQVVQpOwkvL+iuvue9rkdQSU8KCXBpbk1vZGUoRDIsIE9VVFBVVCk7CglwaW5Nb2RlKEQzLCBPVVRQVVQpOwoJcGluTW9kZShENCwgT1VUUFVUKTsKCXBpbk1vZGUoRDUsIE9VVFBVVCk7CglwaW5Nb2RlKEQ2LCBPVVRQVVQpOwoJcGluTW9kZShENywgT1VUUFVUKTsKCXBpbk1vZGUoRDgsIE9VVFBVVCk7CgoJcGluTW9kZShMQ0RfUlMsIE9VVFBVVCk7CglwaW5Nb2RlKExDRF9SVywgT1VUUFVUKTsKCXBpbk1vZGUoTENEX0VOLCBPVVRQVVQpOwoKCVdyaXRlQ21kX0xDRDEyODY0KDB4MzgpOyAgICAgICAvL+mAieaLqThiaXTmlbDmja7mtYEKCWRlbGF5KDIwKTsKCVdyaXRlQ21kX0xDRDEyODY0KDB4MDEpOyAgICAgICAvL+a4hemZpOaYvuekuu+8jOW5tuS4lOiuvuWumuWcsOWdgOaMh+mSiOS4ujAwSAoJZGVsYXkoMjApOwoJV3JpdGVDbWRfTENEMTI4NjQoMHgwYyk7ICAgICAgIC8v5byA5pi+56S6KOaXoOa4uOagh+OAgeS4jeWPjeeZvSkKCWRlbGF5KDIwKTsKfQoKdm9pZCBkb19pdCh2b2lkKXsKCWZnZXRzKHRoaXNfbGluZSwzMjAwLGRhdGFfZnApOwoKCWZ0aW1lKCZ0cCk7CglwcmludGYoIiVkLS0iLCB0cC5taWxsaXRtKTsKCglwcmludGYoIiVkXG4iLCBuKTsKCW4rKzsKCWxlbiA9IHN0cmxlbih0aGlzX2xpbmUpOwoKCWk9MDsKCWRhdGFfcz0wOwoJcz0wOwoJZm9yKGk9MDtpPGxlbjtpKyspewoJCWlmKHRoaXNfbGluZVtpXT09Jy0nKXsKCQkJdGhpc19saW5lX2RhdGFbZGF0YV9zXT1hdG9pKGJ1Zik7CgkJCWJ1ZlswXT0nICc7CgkJCWJ1ZlsxXT0nICc7CgkJCWJ1ZlsyXT0nICc7CgkJCXM9MDsKCQkJZGF0YV9zKys7CgkJfWVsc2V7CgkJCWJ1ZltzXT10aGlzX2xpbmVbaV07CgkJCXMrKzsKCQl9Cgl9CglXcml0ZUNtZF9MQ0QxMjg2NCgweDM2KTsKCVNob3dfTENEMTI4NjQoKTsKCVdyaXRlQ21kX0xDRDEyODY0KDB4MzYpOwp9CgppbnQgbWFpbiAoaW50IGFyZ3MsIGNoYXIgKmFyZ3ZbXSl7CglpbnQgbGFzdD0wLGltZzsKCgl3aXJpbmdQaVNldHVwKCk7CglJbml0X0xDRDEyODY0KCk7CgoJV3JpdGVDbWRfTENEMTI4NjQoMHgwMSk7CglXcml0ZVdvcmRfTENEMTI4NjQoMHg4MCwiSGVsbG8gTENEMTI4NjQiKTsKCWRlbGF5KDEwMDApOwoKCgoJV3JpdGVDbWRfTENEMTI4NjQoMHgwMSk7CglXcml0ZUNtZF9MQ0QxMjg2NCgweDM2KTsKCUNsZWFuX0xDRDEyODY0KDB4MDAsMHgwMCk7CglXcml0ZUNtZF9MQ0QxMjg2NCgweDM2KTsKCglkYXRhX2ZwPWZvcGVuKCJhbGxfaW5fb25lLmgiLCJyIik7CgoJZnRpbWUoJnRwKTsKCWxhc3Q9dHAubWlsbGl0bTsKCgl3aGlsZSgxKXsKCgkJZnRpbWUoJnRwKTsKCgkJaWYobGFzdD50cC5taWxsaXRtKXsKCQkJaWYoMTAwMC1sYXN0K3RwLm1pbGxpdG0+PTMzKXsKCQkJCS8vIGZ0aW1lKCZ0cCk7CgkJCQkvLyBsYXN0PXRwLm1pbGxpdG07CgkJCQlsYXN0PTQzLSgxMDAwLWxhc3QpOwoJCQkJcHJpbnRmKCIlZC0tIiwgbGFzdCk7CgkJCQlkZWxheSgxMCk7CgkJCQlkb19pdCgpOwoJCQl9CgkJfWVsc2V7CgkJCWlmKHRwLm1pbGxpdG0tbGFzdD49MzMpewoJCQkJLy8gZnRpbWUoJnRwKTsKCQkJCS8vIGxhc3Q9dHAubWlsbGl0bTsKCQkJCWxhc3QrPTMzOwoJCQkJcHJpbnRmKCIlZC0tIiwgbGFzdCk7CgkJCQlkb19pdCgpOwoJCQl9CgkJfQoJfQp9Cg==