Merge tag '1.0.7' into develop

tag 1.0.7
diff --git a/supwisdom/sp_communicate.c b/supwisdom/sp_communicate.c
index 28dfe83..79b5601 100644
--- a/supwisdom/sp_communicate.c
+++ b/supwisdom/sp_communicate.c
@@ -27,7 +27,7 @@
 }
 
 static uint8 sp_usart_recv(sp_pos_t* pos, sp_protocol_response_t* resp,
-                               uint32 timeout_ms)
+                           uint32 timeout_ms)
 {
   uint32 tick;
   uint16 len;
@@ -98,8 +98,7 @@
   ret = sp_usart_recv(pos, &resp, COMM_WAIT_TIME);
   if(ret)
   {
-    ret = RC_CARD_AUTHENTICATION;
-    return ret;
+    return RC_CARD_AUTHENTICATION;
   }
 
   sp_unpack_init(&unpack,resp.data,resp.datalen);
@@ -109,31 +108,36 @@
     sp_unpack_value(&unpack,&field);
     if(IS_KEY(PK_INT_PERMIT, field.key))
     {
-      card->permit = field.val.intval;
+      card->permit = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_STR_LIMITMSG, field.key))
     {
-      MEMCPY(card->limitmsg, field.val.strval, field.strlen);
+      MEMCLEAR(card->limitmsg,sizeof card->limitmsg);
+      MEMCPY(card->limitmsg,field.val.strval, field.strlen);
     }
     else if(IS_KEY(PK_INT_WATERLIMIT,field.key))
     {
-      card->waterlimit = field.val.intval;
+      card->waterlimit = (uint16)field.val.intval;
     }
     else if(IS_KEY(PK_INT_COBILLNO,field.key))
     {
-      card->cobillno = field.val.intval;
+      card->cobillno = (uint32)field.val.intval;
     }
     else if(IS_KEY(PK_INT_FEEAMOUNT,field.key))
     {
-      card->feepara.fee_amt = field.val.intval;
+      card->feepara.fee_amt = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_FEEUNIT, field.key))
     {
-      card->feepara.fee_unit = field.val.intval;
+      card->feepara.fee_unit = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_FEESTART, field.key))
     {
-      card->feepara.fee_start = field.val.intval;
+      card->feepara.fee_start = (uint8)field.val.intval;
+    }
+    else if(IS_KEY(PK_INT_AMOUNT_LIMIT,field.key))
+    {
+      card->amountlimit = (uint32)field.val.intval;
     }
   }
   //disp_hint_info(pos,"Éí·ÝÈÏÖ¤³É¹¦",DELAY_TIME1s);
@@ -204,7 +208,12 @@
     return;
   }
   MEMCLEAR(&resp,sizeof resp);
-  sp_usart_recv(pos,&resp,COMM_WAIT_TIME);
+  ret = sp_usart_recv(pos,&resp,COMM_WAIT_TIME);
+  if(ret)
+  {
+    disp_hint_info_two(pos,"µÇ¼ʧ°Ü","µÇ¼³¬Ê±",DELAY_TIME3s);
+    return;
+  }
   ret = sp_confirm_login(&resp,pos);
   if(ret)
   {
@@ -260,8 +269,7 @@
   ret = sp_usart_recv(pos, &resp, COMM_WAIT_TIME);
   if(ret)
   {
-    ret = RC_QRCODE_FAILURE;
-    return ret;
+    return RC_QRCODE_FAILURE;
   }
 
   sp_unpack_init(&unpack,resp.data,resp.datalen);
@@ -271,15 +279,16 @@
     sp_unpack_value(&unpack,&field);
     if(IS_KEY(PK_STR_SHORT_URL, field.key))
     {
+      MEMCLEAR(card->qrcode.qrcode_url,sizeof card->qrcode.qrcode_url);
       MEMCPY(card->qrcode.qrcode_url, field.val.strval, field.strlen);
     }
     else if(IS_KEY(PK_INT_COBILLNO, field.key))
     {
-      card->cobillno = field.val.intval;
+      card->cobillno = (uint32)field.val.intval;
     }
     else if(IS_KEY(PK_INT_VAILDTIME, field.key))
     {
-      card->qrcode.validtime = field.val.intval;
+      card->qrcode.validtime = (uint32)field.val.intval;
     }
   }
   card->qrcode.starttime = sp_get_ticker();
@@ -318,8 +327,7 @@
   ret = sp_usart_recv(pos, &resp, COMM_WAIT_TIME);
   if(ret)
   {
-    ret = RC_QRCODE_QUERY_FAIL;
-    return ret;
+    return RC_QRCODE_QUERY_FAIL;
   }
 
   sp_unpack_init(&unpack,resp.data,resp.datalen);
@@ -329,35 +337,47 @@
     sp_unpack_value(&unpack,&field);
     if(IS_KEY(PK_INT_PERMIT, field.key))
     {
-      card->permit = field.val.intval;
+      card->permit = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_COBILLNO, field.key))
     {
-      card->cobillno = field.val.intval;
+      card->cobillno = (uint32)field.val.intval;
     }
     else if(IS_KEY(PK_INT_AUTHSTATUS, field.key))
     {
-      card->qrcode.authstatus = field.val.intval;
+      card->qrcode.authstatus = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_PAYSTATUS, field.key))
     {
-      card->qrcode.paystatus = field.val.intval;
+      card->qrcode.paystatus = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_PAYAMT, field.key))
     {
-      card->qrcode.paidAmount = field.val.intval;
+      card->qrcode.paidAmount = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_FEEAMOUNT,field.key))
     {
-      card->feepara.fee_amt = field.val.intval;
+      card->feepara.fee_amt = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_FEEUNIT, field.key))
     {
-      card->feepara.fee_unit = field.val.intval;
+      card->feepara.fee_unit = (uint8)field.val.intval;
+    }
+    else if(IS_KEY(PK_INT_FEESTART,field.key))
+    {
+      card->feepara.fee_start = (uint8)field.val.intval;
+    }
+    else if(IS_KEY(PK_INT_WAITTIME,field.key))
+    {
+      card->qrcode.waittime = (uint32)field.val.intval;
     }
     else if(IS_KEY(PK_INT_WATERLIMIT, field.key))
     {
-      card->waterlimit = field.val.intval;
+      card->waterlimit = (uint16)field.val.intval;
+    }
+    else if(IS_KEY(PK_INT_AMOUNT_LIMIT,field.key))
+    {
+      card->amountlimit = (uint16)field.val.intval;
     }
   }
   return resp.retcode;
@@ -533,11 +553,11 @@
     sp_unpack_value(&unpack,&field);
     if(IS_KEY(PK_INT_OFFLINEMAXHOUR, field.key))
     {
-      offline_maxhour = field.val.intval;
+      offline_maxhour = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_INT_PULSEINHML, field.key))
     {
-      unit = field.val.intval;
+      unit = (uint8)field.val.intval;
     }
     else if(IS_KEY(PK_BIN_SYSTIME, field.key))
     {
diff --git a/supwisdom/sp_communicate.h b/supwisdom/sp_communicate.h
index 8a6f59a..c065f20 100644
--- a/supwisdom/sp_communicate.h
+++ b/supwisdom/sp_communicate.h
@@ -81,6 +81,8 @@
 #define PK_INT_FEESTART				"17"
 #define PK_INT_PERMIT				"18"
 #define PK_STR_LIMITMSG				"19"
+#define PK_INT_AMOUNT_LIMIT			"20"
+#define PK_INT_WAITTIME				"21"
 
 #define SP_CMD_UPGRADE 0x20         	//ÔÚÏßÉý¼¶
 #define SP_CMD_TRANSDTL_ACCOUNT 0x22    //¼ÇÕËÁ÷Ë®
diff --git a/supwisdom/sp_config.h b/supwisdom/sp_config.h
index 5039ab6..3daed08 100644
--- a/supwisdom/sp_config.h
+++ b/supwisdom/sp_config.h
@@ -35,7 +35,7 @@
 #define DEV_TYPE "G401201"
 #define DEV_OFFLINE_DEFAULT_HOUR 168
 #define DEV_BLKBITMAP_DONE 1984
-#define DEV_MAX_DEVICENO 99
+#define DEV_MAX_DEVICENO 64
 
 #define PRO_VERSION GIT_VERSION
 #define BUILD_DATE __DATE__ 		// " " __TIME__
@@ -159,6 +159,7 @@
   uint32 starttime;		//¶þάÂ뿪ʼʱ¼ä
   uint32 nowtime;		//¶þάÂ뵱ǰʱ¼ä
   uint32 validtime;		//¶þάÂëÓÐЧʱ¼ä
+  uint32 waittime;		//³öË®µÈ´ýʱ¼ä
   uint8 authstatus;		//Óû§È·ÈÏ״̬£¨0-δȷÈÏ£¬1-ÒÑÈ·ÈÏ£©
   uint8 paystatus;		//Ö§¸¶×´Ì¬£¨0-´ýÖ§¸¶£¬ 1-ÒÑÖ§¸¶£¬ 2-´ú¿Û£¬3 - ¹Ø±Õ£©
   uint8 paidAmount;		//µ±¶©µ¥ÊÇÒÑÖ§¸¶×´Ì¬£¬·µ»ØÖ§¸¶³É¹¦½ð¶î £¬ ·ñÔòÊÇ 0
@@ -232,10 +233,11 @@
   uint8 cardtype;
   uint8 expiredate[4];
 
-  uint8 waterlimit;		//µ¥´Î³öË®ÉÏÏÞ£¨100ml£©
-  uint32 cobillno;		//½»Ò×¶©µ¥±àºÅ,BCDÂë
+  uint16 waterlimit;		//µ¥´Î³öË®Á÷Á¿ÉÏÏÞ£¨100ml£©
+  uint16 amountlimit;		//µ¥´Î³öË®½ð¶îÉÏÏÞ (·Ö)
+  uint32 cobillno;		//½»Ò×¶©µ¥±àºÅ
   uint8	permit;			//ÊÇ·ñÔÊÐíÏû·Ñ£¬0-ÔÊÐí£¬1-²»ÔÊÐí
-  uint8 limitmsg[45];		//ÏÞÖÆÏû·ÑÐÅÏ¢
+  char limitmsg[45];		//ÏÞÖÆÏû·ÑÐÅÏ¢
   sp_qrcode_t qrcode;	//¶þάÂë
   sp_feepara_t feepara;
 } sp_card_t;
diff --git a/supwisdom/sp_consume.c b/supwisdom/sp_consume.c
index 579a3af..7545390 100644
--- a/supwisdom/sp_consume.c
+++ b/supwisdom/sp_consume.c
@@ -10,7 +10,6 @@
 #include "sp_consume.h"
 #include "sp_communicate.h"
 
-static uint32 count = 0;
 static uint8 menu_cnt = 0;
 static uint16 sp_calc_payamt_by_flowsensor(sp_pos_t* pos, sp_card_t* card)
 {
@@ -34,8 +33,6 @@
     return 0;
   }
   usedcount = sp_flowsensor_get_count()/pos->sysconf.flowsensor_unit;
-  //usedcount = count/pos->sysconf.flowsensor_unit;
-  count++;
   if(usedcount < pos->purchase.paid_num)
   {
     //ûÓдﵽ¿Û·ÑÁ÷Á¿
@@ -124,8 +121,27 @@
 }
 
 //¶ÁÈ¡µÚÒ»±ÊδÉÏ´«Á÷Ë®Ïû·ÑÈÕÆÚʱ¼ä
-static uint8 sp_read_unconfirm_first_record(uint8 termtime[6])
+static uint8 sp_read_unconfirm_first_record(const sp_pos_t* pos,uint8 termtime[6])
 {
+  sp_transdtl_t record;
+  uint16 ret;
+  uint8 crc[2];
+  //¼ì²âµ±Ç°ÊÇ·ñÓÐδÉÏ´«µÄÁ÷Ë®
+  if(pos->unconfirm_transdtl.transaddr <= pos->last_transdtl.transaddr)
+  {
+    ret = sp_flash_read((uint32)pos->unconfirm_transdtl.transaddr, (uint8*)&record,
+                        sizeof(record));
+    if(!ret)
+    {
+      sp_protocol_crc((uint8*)&record, sizeof(record)-2,crc);
+      if(MEMCMP(record.crc,crc, 2) == 0)
+      {
+        MEMCPY(termtime,record.transdate, 3);
+        MEMCPY(termtime +3,record.transtime,3);
+        return 0;
+      }
+    }
+  }
   return 1;
 }
 
@@ -142,7 +158,7 @@
     return 0;
   }
   memset(record_termtime,0,sizeof(record_termtime));
-  ret = sp_read_unconfirm_first_record(record_termtime);
+  ret = sp_read_unconfirm_first_record(pos,record_termtime);
   if(ret)
   {
     return 0;
@@ -178,23 +194,6 @@
   return 0;
 }
 
-static uint16 sp_card_valid_check(const sp_card_t* card)
-{
-  uint8 ctime[6];
-  /*
-  if(card->cardno < 1)
-  {
-    return RC_CARDNO_EXCEPT;
-  }
-  */
-  sp_get_bcdtime(ctime);
-  if(memcmp(card->expiredate +1, ctime, 3) < 0)
-  {
-    return RC_CARD_EXPIRED;
-  }
-  return 0;
-}
-
 static uint16 sp_check_dev(const sp_pos_t* pos)
 {
   uint16 ret;
@@ -228,18 +227,25 @@
   return 0;
 }
 
+static uint16 do_card_check(sp_pos_t* pos,sp_card_t* card)
+{
+  if(card->permit == 1)
+  {
+    return RC_LIMIT_CONSUMPTION;
+  }
+  return 0;
+}
+
 static uint16 do_new(sp_pos_t* pos, sp_card_t* card)
 {
   uint16 ret;
-  sp_transdtl_t record;
-  MEMCLEAR(&record, sizeof(record));
+  MEMCLEAR(card,sizeof(sp_card_t));
   card->cardtype = pos->cardState.tag_type;
   MEMCPY(card->cardphyid, pos->cardState.snr, 4);
   ret = sp_card_read(card);
   if(ret)
   {
-    ret = RC_CARD_INVALID;
-    return ret;
+    return RC_CARD_INVALID;
   }
   if(pos->load_para_status)
   {
@@ -256,18 +262,17 @@
     return ret;
   }
 
-  ret = sp_card_valid_check(card);
-  if(ret)
-  {
-    return ret;
-  }
   ret = sp_card_authentication(pos, card);
   if(ret)
   {
-    ret = RC_CARD_AUTHENTICATION;
     return ret;
   }
-  ret = sp_prepare_behalf_transdtl(pos, card, &record);
+  ret = do_card_check(pos,card);
+  if(ret)
+  {
+    return ret;
+  }
+  ret = sp_prepare_behalf_transdtl(pos, card);
   if(ret)
   {
     return ret;
@@ -290,7 +295,6 @@
 static uint16 do_work(sp_pos_t* pos, sp_card_t* card)
 {
   uint16 ret;
-  sp_valve_on();
   //¼ÆËãÏû·Ñ½ð¶î
   ret = sp_calc_payamt_by_flowsensor(pos, card);
   if(ret)
@@ -321,21 +325,33 @@
 static uint16 do_stop(sp_pos_t* pos, sp_card_t* card)
 {
   uint16 ret;
-  sp_transdtl_t record;
+  char msg[32];
   sp_valve_off();
 
-  if(pos->purchase.paid_num > 0)
+  /**
+  **ÓÉÓÚÊÇÏȿ۷ѺóʹÓ㬷ÀÖ¹Ö»²å¿¨Ê±¿Û·Ñ
+  **/
+  if(pos->purchase.used_num == 0)
   {
-    MEMCLEAR(&record, sizeof(record));
-    ret = sp_prepare_below_transdtl(pos, card, &record);
-    if(ret)
-    {
-      return ret;
-    }
+    pos->purchase.paid_num = 0;
+    pos->purchase.paid_sum = 0;
+  }
+  ret = sp_prepare_below_transdtl(pos, card);
+  if(ret)
+  {
+    return ret;
+  }
+  if(pos->purchase.paid_sum > 0)
+  {
+    sprintf(msg,"¹²¼Æ %0.2fÔª",pos->purchase.paid_sum/100.0f);
+    disp_hint_info_two(pos,"½áÊø¼Æ·Ñ",msg,DELAY_TIME2s);
+  }
+  else
+  {
+    disp_hint_info_two(pos,"½áÊø¼Æ·Ñ","Ãâ·ÑʹÓÃ",DELAY_TIME2s);
   }
   pos->paymode = PAYMODE_INIT;
   pos->sysconf.work_mode = 0;
-  count = 0;
   MEMCLEAR(&pos->purchase, sizeof(sp_purchase_t));
   MEMCLEAR(card, sizeof(sp_card_t));
   return 0;
@@ -349,11 +365,11 @@
   if(pos->purchase.paid_sum > 0)
   {
     sprintf(msg,"¹²¼Æ %0.2fÔª",pos->purchase.paid_sum/100.0f);
-    disp_hint_info_two(pos,"½áÊø¼Æ·Ñ",msg,DELAY_TIME2s);
+    disp_hint_info_two(pos,"ÔÝÍ£¼Æ·Ñ",msg,DELAY_TIME2s);
   }
   else
   {
-    disp_hint_info_two(pos,"½áÊø¼Æ·Ñ","Ãâ·ÑʹÓÃ",DELAY_TIME2s);
+    disp_hint_info_two(pos,"ÔÝÍ£¼Æ·Ñ","Ãâ·ÑʹÓÃ",DELAY_TIME2s);
   }
 }
 
@@ -364,7 +380,6 @@
     show_error(pos,"²Ù×÷ʧ°Ü:",errcode);
     pos->paymode = PAYMODE_INIT;
     pos->sysconf.work_mode = 0;
-    count = 0;
     MEMCLEAR(&pos->purchase, sizeof(sp_purchase_t));
   }
 }
@@ -436,9 +451,14 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
-    if(pos->purchase.paid_num > card->waterlimit)
+    if(pos->purchase.used_num > card->waterlimit)
     {
-      disp_hint_info_two(pos,"Í£Ö¹³öË®","ÒÑ´ïµ¥´Î³öË®ÉÏÏÞ",DELAY_TIME2s);
+      disp_hint_info_two(pos, "Í£Ö¹³öË®","ÒÑ´ïµ¥´Î³öË®ÉÏÏÞ", DELAY_TIME2s);
+      cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+    }
+    else if(pos->purchase.paid_sum > card->amountlimit)
+    {
+      disp_hint_info_two(pos, "Í£Ö¹³öË®","ÒÑ´ïµ¥´Î½ð¶îÉÏÏÞ", DELAY_TIME2s);
       cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
     }
     cardWorkState->pause_tick = timer_get_ticker();
@@ -489,7 +509,7 @@
     cardWorkState->current_state = CARDWORKSTATUS_NONE;
     break;
   case CARDWORKSTATUS_WORKING:
-    cardWorkState->current_state = CARDWORKSTATUS_PAUSE;
+    cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
     break;
   case CARDWORKSTATUS_PAUSE:
     if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) == 0)
@@ -525,7 +545,7 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
-    cardWorkState->current_state = CARDWORKSTATUS_STOPPED;
+    cardWorkState->current_state = CARDWORKSTATUS_NONE;
     cardWorkState->tick = timer_get_ticker();
     break;
   case CARDWORKSTATUS_STOPPED:
@@ -617,8 +637,6 @@
 void sp_qrcode_handle(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState)
 {
   uint16 ret = 0;
-  sp_transdtl_t record;
-  MEMCLEAR(&record, sizeof(record));
   switch(cardWorkState->current_state)
   {
   case CARDWORKSTATUS_NONE:
@@ -629,7 +647,8 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
-	disp_hint_info_two(pos, "ÇëÇó¶þάÂë","ÇëÉÔµÈ...",0);
+    disp_hint_info_two(pos, "ÇëÇó¶þάÂë","ÇëÉÔµÈ...",0);
+    MEMCLEAR(&CARD,sizeof(sp_card_t));
     ret = sp_qrcode_init(pos, &CARD);
     if(ret)
     {
@@ -637,7 +656,7 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
-    ret = sp_prepare_behalf_transdtl(pos, &CARD, &record);
+    ret = sp_prepare_behalf_transdtl(pos, &CARD);
     if(ret)
     {
       cardWorkState->errcode = RC_QRCODE_TIMEOUT;
@@ -654,8 +673,7 @@
     CARD.qrcode.nowtime = sp_get_ticker();
     if((CARD.qrcode.nowtime - CARD.qrcode.starttime) < CARD.qrcode.validtime*DELAY_TIME1s)
     {
-      show_home(pos);
-      show_home_qrcode(CARD.qrcode.qrcode_url);
+      show_home_qrcode(pos,CARD.qrcode.qrcode_url);
       if(CARD.qrcode.nowtime - tick > DELAY_TIME2s)
       {
         tick = CARD.qrcode.nowtime;
@@ -670,6 +688,7 @@
           else
           {
             do_start(pos);
+            CARD.qrcode.starttime = CARD.qrcode.nowtime;
             cardWorkState->last_state = cardWorkState->current_state;
             cardWorkState->current_state = CARDWORKSTATUS_WORKING;
           }
@@ -695,15 +714,32 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
-    if(pos->purchase.paid_num > CARD.waterlimit)
+    if(pos->purchase.used_num >CARD.waterlimit)
     {
       disp_hint_info_two(pos, "Í£Ö¹³öË®","ÒÑ´ïµ¥´Î³öË®ÉÏÏÞ", DELAY_TIME2s);
       cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
     }
+    else if(pos->purchase.paid_sum > CARD.amountlimit)
+    {
+      disp_hint_info_two(pos, "Í£Ö¹³öË®","ÒÑ´ïµ¥´Î½ð¶îÉÏÏÞ", DELAY_TIME2s);
+      cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+    }
+    /**È·ÈϳöË®ºó³¬¹ýµÈ´ýʱ¼äδ³öˮֹͣ³öË®**/
+    CARD.qrcode.nowtime = sp_get_ticker();
+    if((CARD.qrcode.nowtime - CARD.qrcode.starttime) > CARD.qrcode.waittime*DELAY_TIME1s)
+    {
+      if(pos->purchase.used_num == 0)
+      {
+        disp_hint_info_two(pos, "Í£Ö¹³öË®","δ¼ì²âµ½³öË®", DELAY_TIME2s);
+        cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+      }
+    }
+
     cardWorkState->last_state = cardWorkState->current_state;
     cardWorkState->pause_tick = sp_get_ticker();
     break;
   case CARDWORKSTATUS_STOPPING:
+#if 0
     if(cardWorkState->last_state == CARDWORKSTATUS_NONE
         || cardWorkState->last_state == CARDWORKSTATUS_READY)
     {
@@ -725,6 +761,17 @@
     }
     cardWorkState->current_state = CARDWORKSTATUS_NONE;
     cardWorkState->last_state = cardWorkState->current_state;
+#endif
+
+    ret = do_stop(pos, &CARD);
+    if(ret)
+    {
+      cardWorkState->errcode = ret;
+      cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+      break;
+    }
+    cardWorkState->current_state = CARDWORKSTATUS_NONE;
+    cardWorkState->last_state = cardWorkState->current_state;
     break;
   case CARDWORKSTATUS_ERROR:
     do_error(pos,cardWorkState->errcode);
diff --git a/supwisdom/sp_data.c b/supwisdom/sp_data.c
index f2fdac3..2275abc 100644
--- a/supwisdom/sp_data.c
+++ b/supwisdom/sp_data.c
@@ -12,7 +12,6 @@
 {
   uint8 crc[2];
   uint8 buff[sizeof(sp_last_transdtl_t)];
-  MEMCLEAR(buff, sizeof(buff));
 
   pos->last_transdtl.this_offset += sizeof(sp_last_transdtl_t);
   if(pos->last_transdtl.this_offset >= DEF_FLASH_PageSize)
@@ -20,9 +19,9 @@
     sp_flash_erase(ADDR_LAST_TRANSNO);
     pos->last_transdtl.this_offset = 0;
   }
-  sp_protocol_crc((uint8*)&pos->last_transdtl, sizeof(buff)-2, pos->last_transdtl.crc);
+  sp_protocol_crc((uint8*)&pos->last_transdtl, sizeof(sp_last_transdtl_t)-2, pos->last_transdtl.crc);
   sp_flash_write(pos->last_transdtl.this_offset+ADDR_LAST_TRANSNO,
-                 (uint8*)&pos->last_transdtl, sizeof(buff));
+                 (uint8*)&pos->last_transdtl, sizeof(sp_last_transdtl_t));
 
   sp_flash_read(pos->last_transdtl.this_offset+ADDR_LAST_TRANSNO, buff, sizeof(buff));
   sp_protocol_crc(buff, sizeof(buff)-2, crc);
@@ -36,9 +35,6 @@
 
 static uint16 sp_write_behalf_record(sp_pos_t* pos, sp_transdtl_t* record)
 {
-  uint8 buf[record_behalf_len];
-  MEMCLEAR(buf, sizeof(buf));
-
   pos->last_transdtl.transaddr += sizeof(sp_transdtl_t);
   if(pos->last_transdtl.transaddr % DEF_FLASH_PageSize == 0)
   {
@@ -48,7 +44,7 @@
     }
     sp_flash_erase(pos->last_transdtl.transaddr);
   }
-  sp_flash_write(pos->last_transdtl.transaddr, (uint8*)record, sizeof(buf));
+  sp_flash_write(pos->last_transdtl.transaddr, (uint8*)record, record_behalf_len);
   return 0;
 }
 
@@ -56,10 +52,8 @@
 {
   uint8 crc[2];
   uint8 buff[sizeof(sp_transdtl_t)];
-  MEMCLEAR(crc, sizeof(crc));
-  MEMCLEAR(buff, sizeof(buff));
 
-  sp_protocol_crc((uint8*)record, sizeof(buff)-2, record->crc);
+  sp_protocol_crc((uint8*)record, sizeof(sp_transdtl_t)-2, record->crc);
   sp_flash_write(pos->last_transdtl.transaddr+record_behalf_len,
                  (uint8*)record+record_behalf_len, record_below_len);
   sp_flash_read(pos->last_transdtl.transaddr, buff, sizeof(buff));
@@ -73,52 +67,49 @@
 }
 
 //Ïû·Ñ³õʼ»¯ºó´æ´¢Éϰ벿·ÖÁ÷Ë®£¬·ÀÖ¹Ïû·Ñʧ°ÜÎÞÁ÷Ë®ÐÅÏ¢
-uint16 sp_prepare_behalf_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record)
+uint16 sp_prepare_behalf_transdtl(sp_pos_t* pos, sp_card_t* card)
 {
-  uint8 ret = 0;
   uint8 ctime[6];
-  MEMCLEAR(ctime, sizeof(ctime));
+  sp_transdtl_t record;
+  MEMCLEAR(&record, sizeof(record));
 
   sp_get_bcdtime(ctime);
-  memcpy(record->devphyid, pos->devphyid, sizeof(pos->devphyid));
-  memcpy(record->transdate, ctime, 3);
-  memcpy(record->transtime, ctime+3, 3);
-  record->cobillno = card->cobillno;
-  memcpy(record->cardphyid, card->cardphyid, sizeof(card->cardphyid));
+  memcpy(record.devphyid, pos->devphyid, sizeof(pos->devphyid));
+  memcpy(record.transdate, ctime, 3);
+  memcpy(record.transtime, ctime+3, 3);
+  record.cobillno = card->cobillno;
+  memcpy(record.cardphyid, card->cardphyid, sizeof(card->cardphyid));
   if(pos->paymode == PAYMODE_QRCODE)
   {
-    record->transway = 2;
+    record.transway = 2;
   }
   else
   {
-    record->transway = 1;
+    record.transway = 1;
   }
-  ret = sp_write_behalf_record(pos, record);
-  if(ret)
-    return ret;
+  sp_write_behalf_record(pos, &record);
   return sp_write_last_record(pos);
 }
 
 //ÈôÏû·Ñ³É¹¦£¬´æ´¢Ï°벿·ÖÁ÷Ë®ÐÅÏ¢
-uint16 sp_prepare_below_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record)
+uint16 sp_prepare_below_transdtl(sp_pos_t* pos, sp_card_t* card)
 {
-  uint8 buff[record_behalf_len];
-  MEMCLEAR(buff, sizeof(buff));
+  sp_transdtl_t record;
+  MEMCLEAR(&record, sizeof(record));
 
-  record->amount = pos->purchase.paid_sum;
+  sp_flash_read(pos->last_transdtl.transaddr, (uint8*)&record, record_behalf_len);
+  record.amount = pos->purchase.paid_sum;
   if(pos->paymode == PAYMODE_QRCODE)
   {
-    record->paidAmount = card->qrcode.paidAmount;
+    record.paidAmount = card->qrcode.paidAmount;
   }
   else
   {
-    record->paidAmount = 0;
+    record.paidAmount = 0;
   }
-  record->flowsensors = pos->purchase.paid_num;
-  record->transtatus = 1;
-  sp_flash_read(pos->last_transdtl.transaddr, buff, sizeof(buff));
-  MEMCPY(record, buff, sizeof(buff));
-  return sp_write_below_record(pos, record);
+  record.flowsensors = pos->purchase.paid_num;
+  record.transtatus = 1;
+  return sp_write_below_record(pos, &record);
 }
 
 //Ñ­»·´æ´¢Ã¿Ò»±ÊδÉÏ´«Á÷Ë®¼Ç¼µÄµØÖ·
@@ -126,18 +117,17 @@
 {
   uint8 crc[2];
   uint8 buff[sizeof(sp_unconfirm_transdtl_t)];
-  MEMCLEAR(buff, sizeof(buff));
 
-  pos->unconfirm_transdtl.this_offset += sizeof(buff);
+  pos->unconfirm_transdtl.this_offset += sizeof(sp_unconfirm_transdtl_t);
   if(pos->unconfirm_transdtl.this_offset >= DEF_FLASH_PageSize)
   {
     sp_flash_erase(ADDR_UNCONFIRM_TRANSNO);
     pos->unconfirm_transdtl.this_offset = 0;
   }
-  sp_protocol_crc((uint8*)&pos->unconfirm_transdtl, sizeof(buff)-2,
+  sp_protocol_crc((uint8*)&pos->unconfirm_transdtl, sizeof(sp_unconfirm_transdtl_t)-2,
                   pos->unconfirm_transdtl.crc);
   sp_flash_write(pos->unconfirm_transdtl.this_offset+ADDR_UNCONFIRM_TRANSNO,
-                 (uint8*)&pos->unconfirm_transdtl, sizeof(buff));
+                 (uint8*)&pos->unconfirm_transdtl, sizeof(sp_unconfirm_transdtl_t));
 
   sp_flash_read(pos->unconfirm_transdtl.this_offset+ADDR_UNCONFIRM_TRANSNO, buff,
                 sizeof(buff));
@@ -221,7 +211,8 @@
 uint16 sp_clear_transdtl(sp_pos_t* pos)
 {
   uint32 i;
-  uint16 ret = sp_flash_erase(ADDR_LAST_TRANSNO);
+  uint16 ret;
+  ret = sp_flash_erase(ADDR_LAST_TRANSNO);
   ret |= sp_flash_erase(ADDR_UNCONFIRM_TRANSNO);
   for(i = ADDR_TRANSDTL_BEGIN; i < ADDR_TRANSDTL_END; i += DEF_FLASH_PageSize)
   {
@@ -232,10 +223,8 @@
 
 static uint16 sp_init_device(sp_pos_t* pos)
 {
-  uint16 ret;
   disp_hint_info_two(pos,"É豸³õʼ»¯","Çå¿ÕÁ÷Ë®",0);
-  ret |= sp_clear_transdtl(pos);
-  return  ret;
+  return sp_clear_transdtl(pos);
 }
 
 void sp_reset_factory(sp_pos_t* pos)
@@ -347,11 +336,12 @@
 
 uint16 sp_config_init(sp_pos_t* pos)
 {
-  uint16 ret = 0;
   uint8 crc[2];
   sp_config_t config;
-  MEMCLEAR(&config, sizeof(config));
   disp_hint_info_two(pos,"É豸²ÎÊý³õʼ»¯", "ÇëÉÔµÈ...",0);
+  MEMCLEAR(&config, sizeof(config));
+  config.deviceno = 1;
+  MEMCPY(config.devphyid,"\x40\x12\x01\x00",4);
   sp_protocol_crc((uint8*)&config,sizeof(sp_config_t)-2,config.crc);
   sp_flash_erase(ADDR_CONFIG_PARA);
   sp_flash_write(ADDR_CONFIG_PARA,(uint8*)&config,sizeof(sp_config_t));
@@ -361,6 +351,5 @@
   {
     return RC_CONFPARA_CRC_ERR;
   }
-  ret = sp_flash_erase(ADDR_CONFIG_PARA);
-  return ret;
+  return sp_parse_config(pos,&config);
 }
diff --git a/supwisdom/sp_data.h b/supwisdom/sp_data.h
index 1ed4942..399b8f5 100644
--- a/supwisdom/sp_data.h
+++ b/supwisdom/sp_data.h
@@ -5,8 +5,8 @@
 #include "sp_communicate.h"
 
 //Á÷Ë®´¦Àí
-uint16 sp_prepare_behalf_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record);
-uint16 sp_prepare_below_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record);
+uint16 sp_prepare_behalf_transdtl(sp_pos_t* pos, sp_card_t* card);
+uint16 sp_prepare_below_transdtl(sp_pos_t* pos, sp_card_t* card);
 uint16 sp_read_lastrecord(const sp_pos_t* pos, sp_transdtl_t* dtl);
 uint16 sp_confirm_record(const sp_pos_t* pos, sp_transdtl_t* dtl);
 uint16 sp_query_record(const sp_pos_t* pos, uint8 refno[16], sp_transdtl_t* dtl);
diff --git a/supwisdom/sp_display.c b/supwisdom/sp_display.c
index b81672a..76ab136 100644
--- a/supwisdom/sp_display.c
+++ b/supwisdom/sp_display.c
@@ -64,10 +64,23 @@
   glcd_draw_string_xy(0, GLCD_BUTTOM_Y, line_buff);
 }
 
+static void show_code_bottom(sp_pos_t* pos)
+{
+  sprintf(line_buff,"%02d:%02x%02x%02x%02x",pos->deviceno, pos->devphyid[0],
+          pos->devphyid[1], pos->devphyid[2], pos->devphyid[3]);
+  glcd_draw_string_xy(0, GLCD_BUTTOM_Y, line_buff);
+}
+
 static char last_qrcode_url[32]= {0};
-void show_home_qrcode(char* qrcode_url)
+void show_home_qrcode(sp_pos_t* pos,char* qrcode_url)
 {
   uint8 i,j;
+  uint8 pixel;
+
+  show_title();
+  show_code_bottom(pos);
+  snprintf(line_buff,sizeof line_buff,"%s               ","ÇëɨÂë>>");
+  gb2312_16_draw_str(0, GLCD_CONTENT_Y_ONE, line_buff);
   if(MEMCMP(qrcode_url,last_qrcode_url,(int)strlen(qrcode_url)) != 0)
   {
     sprintf(last_qrcode_url,"%s",qrcode_url);
@@ -79,7 +92,7 @@
   {
     for(j=0; j<MAX_MODULESIZE*2; j++)
     {
-      uint8_t pixel = m_byModuleData[i/2][j/2];
+      pixel = m_byModuleData[i/2][j/2];
 
       glcd_set_pixel(j+70, 12+i, pixel);
       glcd_set_pixel(j+70, 12+i+1, pixel);
@@ -267,7 +280,7 @@
     sprintf(msg, "%s", "Á÷Á¿¼ÆË㵥λδÉèÖÃ");
     break;
   case RC_CARD_AUTHENTICATION:
-    sprintf(msg, "%s", "¿¨ÈÏ֤ʧ°Ü");
+    sprintf(msg, "%s", "Éí·ÝÈÏÖ¤³¬Ê±");
     break;
   case RC_LIMIT_CONSUMPTION:
     sprintf(msg, "%s", "¸ÃÓû§±»ÏÞÖÆÏû·Ñ");
diff --git a/supwisdom/sp_display.h b/supwisdom/sp_display.h
index 3160248..71468e3 100644
--- a/supwisdom/sp_display.h
+++ b/supwisdom/sp_display.h
@@ -24,7 +24,7 @@
 	void show_home(sp_pos_t* pos);
 	void show_money(sp_pos_t* pos, uint32 money);
 	void show_manage_passwd(sp_pos_t* pos, const char* hint,uint8 passwd[],uint8 len);
-	void show_home_qrcode(char* qrcode_url);
+	void show_home_qrcode(sp_pos_t* pos,char* qrcode_url);
 	
 	void disp_hint_info(sp_pos_t* pos, const char* msg1,uint32 ms);
 	void disp_hint_info_two(sp_pos_t* pos, const char* msg1,const char* msg2,uint32 ms);
diff --git a/supwisdom/sp_menu.c b/supwisdom/sp_menu.c
index d9d1b0a..5ae99f1 100644
--- a/supwisdom/sp_menu.c
+++ b/supwisdom/sp_menu.c
@@ -548,6 +548,46 @@
   }
 }
 
+static void flowsensor_calibrate(sp_pos_t* pos)
+{
+  uint32 ticker;
+  uint8 kcode;
+  uint32 count;
+  uint32 temp;
+  char msg[32];
+
+  sp_valve_on();
+  sp_flowsensor_count_clear();
+  disp_hint_info_two(pos,"Á÷Á¿¼ÆÊý²âÊÔ","¼ÆËã100ml¼ÆÊý",0);
+  count = 0;
+  ticker = sp_get_ticker();
+  while(sp_get_ticker() -ticker < DELAY_TIME60s*5)
+  {
+    sp_feed_dog();
+    sp_valve_control();
+    kcode = sp_get_key();
+    if(kcode != SP_KEY_NONE)
+    {
+      if(kcode == SP_KEY_CLEAR)
+      {
+        sp_valve_off();
+        return;
+      }
+      ticker = sp_get_ticker();
+    }
+    temp = sp_flowsensor_get_count();
+    if(temp != count)
+    {
+      count = temp;
+      sprintf(msg,"Âö³å¸öÊý:%d",temp);
+      disp_hint_info_two(pos,"Á÷Á¿¼ÆÊý²âÊÔ",msg,DELAY_TIME100ms);
+    }
+  }
+  sp_valve_off();
+  sprintf(msg,"Âö³å¸öÊý:%d",sp_flowsensor_get_count());
+  disp_hint_info_two(pos,"Á÷Á¿¼ÆÊý²âÊÔ",msg,DELAY_TIME3s);
+}
+
 static void test_valve_on(sp_pos_t* pos)
 {
   sp_valve_on();
@@ -613,7 +653,8 @@
     {"3.¿ªÆô·§ÃÅ", test_valve_on},
     {"4.¹Ø±Õ·§ÃÅ", test_valve_off},
     {"5.Á÷Á¿²âÊÔ", test_flowsensor},
-    {"6.ͨѶ²âÊÔ", test_link}
+    {"6.ͨѶ²âÊÔ", test_link},
+    {"7.Á÷Á¿¼ÆÊýУ׼",flowsensor_calibrate}
   };
   max_cnt = (sizeof(menus)/sizeof(menu_t) -1)/3 + 1;
   page = 0;