修复刷卡报错问题和二维码有效期bug
diff --git a/g401302/project/g401302.uvopt b/g401302/project/g401302.uvopt
index c727890..c912168 100644
--- a/g401302/project/g401302.uvopt
+++ b/g401302/project/g401302.uvopt
@@ -759,10 +759,10 @@
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <Focus>0</Focus>
-      <ColumnNumber>34</ColumnNumber>
+      <ColumnNumber>0</ColumnNumber>
       <tvExpOptDlg>0</tvExpOptDlg>
-      <TopLine>592</TopLine>
-      <CurrentLine>607</CurrentLine>
+      <TopLine>394</TopLine>
+      <CurrentLine>401</CurrentLine>
       <bDave2>0</bDave2>
       <PathWithFileName>..\..\supwisdom\sp_consume.c</PathWithFileName>
       <FilenameWithoutPath>sp_consume.c</FilenameWithoutPath>
diff --git a/supwisdom/sp_communicate.c b/supwisdom/sp_communicate.c
index e52ec0f..c86690a 100644
--- a/supwisdom/sp_communicate.c
+++ b/supwisdom/sp_communicate.c
@@ -80,7 +80,15 @@
   while(size-- > 0)
   {
     sp_unpack_value(&unpack,&field);
-    if(IS_KEY(PK_INT_WATERLIMIT,field.key))
+    if(IS_KEY(PK_INT_PERMIT, field.key))
+    {
+      card->permit = field.val.intval;
+    }
+    else if(IS_KEY(PK_STR_LIMITMSG, field.key))
+    {
+      MEMCPY(card->limitmsg, field.val.strval, field.strlen);
+    }
+    else if(IS_KEY(PK_INT_WATERLIMIT,field.key))
     {
       card->waterlimit = field.val.intval;
     }
@@ -270,7 +278,11 @@
   while(size-- > 0)
   {
     sp_unpack_value(&unpack,&field);
-    if(IS_KEY(PK_INT_COBILLNO, field.key))
+    if(IS_KEY(PK_INT_PERMIT, field.key))
+    {
+      card->permit = field.val.intval;
+    }
+    else if(IS_KEY(PK_INT_COBILLNO, field.key))
     {
       card->cobillno = field.val.intval;
     }
@@ -294,6 +306,10 @@
     {
       card->feepara.fee_unit = field.val.intval;
     }
+    else if(IS_KEY(PK_INT_WATERLIMIT, field.key))
+    {
+      card->waterlimit = field.val.intval;
+    }
   }
   return resp.retcode;
 }
@@ -558,23 +574,16 @@
   if(ticker - pos->last_comm_status.sendtime > COMM_WAIT_TIME)
   {
     if(pos->devlogin.last_login_ticker == 0 || pos->devlogin.login_flag == 0
-		|| ticker - pos->devlogin.last_login_ticker > DELAY_TIME60s*30)
+        || ticker - pos->devlogin.last_login_ticker > DELAY_TIME60s*30)
     {
-      if(ticker - pos->devlogin.last_login_ticker > DELAY_TIME60s*60)
-      {
         pos->devlogin.last_login_ticker = ticker;
         sp_async_equipment_login(pos);
-      }
     }
-    else if(ticker < pos->heartbeat.last_heartbeat_ticker
-            || pos->heartbeat.last_heartbeat_ticker == 0
-            || ticker - pos->heartbeat.last_heartbeat_ticker > DELAY_TIME15s*2)
+    if(pos->heartbeat.last_heartbeat_ticker == 0
+        || ticker - pos->heartbeat.last_heartbeat_ticker > DELAY_TIME60s)
     {
-      if(ticker - pos->heartbeat.last_heartbeat_ticker > DELAY_TIME60s)
-      {
         pos->heartbeat.last_heartbeat_ticker = ticker;
         sp_async_heartbeat(pos);
-      }
     }
     else
     {
diff --git a/supwisdom/sp_communicate.h b/supwisdom/sp_communicate.h
index da422f3..3258eff 100644
--- a/supwisdom/sp_communicate.h
+++ b/supwisdom/sp_communicate.h
@@ -79,6 +79,8 @@
 #define PK_INT_AUTHSTATUS			"15"
 #define PK_INT_PAYSTATUS			"16"
 #define PK_INT_FEESTART				"17"
+#define PK_INT_PERMIT				"18"
+#define PK_STR_LIMITMSG				"19"
 
 #define SP_CMD_UPGRADE 0x20         	//ÔÚÏßÉý¼¶
 #define SP_CMD_TRANSDTL_ACCOUNT 0x22    //¼ÇÕËÁ÷Ë®
diff --git a/supwisdom/sp_config.h b/supwisdom/sp_config.h
index b57a05b..948e86a 100644
--- a/supwisdom/sp_config.h
+++ b/supwisdom/sp_config.h
@@ -234,6 +234,8 @@
 
   uint8 waterlimit;		//µ¥´Î³öË®ÉÏÏÞ£¨100ml£©
   uint32 cobillno;		//½»Ò×¶©µ¥±àºÅ,BCDÂë
+  uint8	permit;			//ÊÇ·ñÔÊÐíÏû·Ñ£¬0-ÔÊÐí£¬1-²»ÔÊÐí
+  uint8 limitmsg[45];		//ÏÞÖÆÏû·ÑÐÅÏ¢
   sp_qrcode_t qrcode;	//¶þάÂë
   sp_feepara_t feepara;
 } sp_card_t;
diff --git a/supwisdom/sp_constant.h b/supwisdom/sp_constant.h
index 3081fc0..a7dd95b 100644
--- a/supwisdom/sp_constant.h
+++ b/supwisdom/sp_constant.h
@@ -54,5 +54,7 @@
 #define STATUS_KEEPOPEN					1	//³£¿ª¿¨
 #define STATUS_CLOSED					0	//È¡Ïû³£¿ª¿¨
 
+#define RC_LIMIT_CONSUMPTION			70	//ÏÞÖÆÏû·Ñ
+
 #endif
 
diff --git a/supwisdom/sp_consume.c b/supwisdom/sp_consume.c
index 4052bfd..737b25a 100644
--- a/supwisdom/sp_consume.c
+++ b/supwisdom/sp_consume.c
@@ -286,25 +286,10 @@
   return 0;
 }
 
-static uint16 do_work_check(const sp_pos_t* pos)
-{
-  //ÅжÏÏû·Ñ½ð¶îÈç¹û´óÓÚ20»òÕßÁ¬ÐøÏû·Ñ³¬¹ý2Сʱ£¬ÔòÍ£Ö¹³öË®
-  if(pos->purchase.used_num >= 1000 || pos->purchase.paid_sum >= 1000)
-  {
-    return RC_CARD_TIMEOUT;
-  }
-  return 0;
-}
-
 static uint16 do_work(sp_pos_t* pos, sp_card_t* card)
 {
   uint16 ret = 0;
   sp_valve_on();
-  ret = do_work_check(pos);
-  if(ret)
-  {
-    return ret;
-  }
   //¼ÆËãÏû·Ñ½ð¶î
   ret = sp_calc_payamt_by_flowsensor(pos, card);
   if(ret)
@@ -468,7 +453,7 @@
     cardWorkState->current_state = CARDWORKSTATUS_STOPPED;
     break;
   case CARDWORKSTATUS_STOPPED:
-    cardWorkState->current_state = CARDWORKSTATUS_NONE;
+    disp_hint_info(pos, "Çë°Î¿¨", DELAY_TIME2s);
     break;
   case CARDWORKSTATUS_FEECARD_WORKING:
     if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) != 0)
@@ -476,11 +461,9 @@
       cardWorkState->current_state = CARDWORKSTATUS_NONE;
       break;
     }
-    //show_menu_options();
     break;
   case CARDWORKSTATUS_ERROR:
     do_error(pos, cardWorkState->errcode);
-    cardWorkState->current_state = CARDWORKSTATUS_NONE;
     break;
   default:
     Delay_ms(DELAY_TIME200ms);
@@ -657,19 +640,27 @@
     break;
   case CARDWORKSTATUS_READY:
     CARD.qrcode.nowtime = sp_get_ticker();
-    if((CARD.qrcode.nowtime - CARD.qrcode.starttime) > CARD.qrcode.validtime)
+    if((CARD.qrcode.nowtime - CARD.qrcode.starttime) < CARD.qrcode.validtime*DELAY_TIME1s)
     {
       show_home(pos);
       show_home_qrcode(CARD.qrcode.qrcode_url);
-      if(CARD.qrcode.nowtime - tick > DELAY_TIME3s)
+      if(CARD.qrcode.nowtime - tick > DELAY_TIME2s)
       {
         tick = CARD.qrcode.nowtime;
         ret = sp_qrcode_query(pos, &CARD);
         if(!ret && CARD.qrcode.authstatus)
         {
-          do_start(pos);
-          cardWorkState->last_state = cardWorkState->current_state;
-          cardWorkState->current_state = CARDWORKSTATUS_WORKING;
+          if(CARD.permit)
+          {
+            cardWorkState->errcode = RC_LIMIT_CONSUMPTION;
+            cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+          }
+          else
+          {
+            do_start(pos);
+            cardWorkState->last_state = cardWorkState->current_state;
+            cardWorkState->current_state = CARDWORKSTATUS_WORKING;
+          }
         }
       }
     }
@@ -692,6 +683,11 @@
       cardWorkState->current_state = CARDWORKSTATUS_ERROR;
       break;
     }
+    if(pos->purchase.paid_num > CARD.waterlimit)
+    {
+      disp_hint_info(pos, "ÒÑ´ïµ¥´Î³öË®ÉÏÏÞ", DELAY_TIME2s);
+      cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+    }
     cardWorkState->last_state = cardWorkState->current_state;
     cardWorkState->pause_tick = sp_get_ticker();
     break;
diff --git a/supwisdom/sp_display.c b/supwisdom/sp_display.c
index 676e27d..860a451 100644
--- a/supwisdom/sp_display.c
+++ b/supwisdom/sp_display.c
@@ -162,120 +162,124 @@
   switch(errcode)
   {
   case RC_PSAM_ERR:
-    sprintf(msg,"%s", "SAM¸´Î»Ê§°Ü");
+    sprintf(msg, "%s", "SAM¸´Î»Ê§°Ü");
     break;
   case RC_CARD_LOGIN:
-    sprintf(msg,"%s", "ÑéÖ¤ÃØÔ¿Ê§°Ü");
+    sprintf(msg, "%s", "ÑéÖ¤ÃØÔ¿Ê§°Ü");
     break;
   case RC_CARD_READ:
-    sprintf(msg,"%s", "¶Á¿¨Ê§°Ü");
+    sprintf(msg, "%s", "¶Á¿¨Ê§°Ü");
     break;
   case RC_CARD_WRITE:
-    sprintf(msg,"%s", "д¿¨Ê§°Ü");
+    sprintf(msg, "%s", "д¿¨Ê§°Ü");
     break;
   case RC_FLASH_ERR:
-    sprintf(msg,"%s", "FLASHÒì³£");
+    sprintf(msg, "%s", "FLASHÒì³£");
     break;
   case RC_HARDWARE_ERR:
-    sprintf(msg,"%s", "¹Ì¼þÒì³£");
+    sprintf(msg, "%s", "¹Ì¼þÒì³£");
     break;
   case RC_FLASH_NO_RIGHT:
-    sprintf(msg,"%s", "FLASHÏÞÖÆ");
+    sprintf(msg, "%s", "FLASHÏÞÖÆ");
     break;
   case RC_CARD_NORIGHT:
-    sprintf(msg,"%s", "¿¨ÎÞȨÏÞ");
+    sprintf(msg, "%s", "¿¨ÎÞȨÏÞ");
     break;
   case RC_CARD_EXPIRED:
-    sprintf(msg,"%s", "¿¨ÒѹýÆÚ");
+    sprintf(msg, "%s", "¿¨ÒѹýÆÚ");
     break;
   case RC_CARD_LOST:
-    sprintf(msg,"%s", "¿¨ÒÑËø¶¨");
+    sprintf(msg, "%s", "¿¨ÒÑËø¶¨");
     break;
   case RC_CARDNO_EXCEPT:
-    sprintf(msg,"%s", "¿¨Òì³£");
+    sprintf(msg, "%s", "¿¨Òì³£");
     break;
   case RC_CARD_TIMEOUT:
-    sprintf(msg,"%s", "ʹÓÃÌ«¾Ã");
+    sprintf(msg, "%s", "ʹÓÃÌ«¾Ã");
     break;
   case RC_CARDBAL_EXCEPT:
-    sprintf(msg,"%s", "Óà¶îÒì³£");
+    sprintf(msg, "%s", "Óà¶îÒì³£");
     break;
   case RC_CARDBAL_LACK:
-    sprintf(msg,"%s", "ÇëÁª»úÏû·Ñ");
+    sprintf(msg, "%s", "ÇëÁª»úÏû·Ñ");
     break;
   case RC_DEVPHYID_NOTSET:
-    sprintf(msg,"%s", "δÉèÖûúºÅ");
+    sprintf(msg, "%s", "δÉèÖûúºÅ");
     break;
   case RC_FEERATE_NOTSET:
-    sprintf(msg,"%s", "δÉèÖ÷ÑÂÊ");
+    sprintf(msg, "%s", "δÉèÖ÷ÑÂÊ");
     break;
   case RC_DEV_OFFLINE_ERROR:
-    sprintf(msg,"%s", "É豸ÍÑ»úÌ«¾Ã");
+    sprintf(msg, "%s", "É豸ÍÑ»úÌ«¾Ã");
     break;
   case RC_TRANSDTL_FULL:
-    sprintf(msg,"%s", "Á÷Ë®ÒÑÂú");
+    sprintf(msg, "%s", "Á÷Ë®ÒÑÂú");
     break;
   case RC_FILE09_CRC_ERR:
-    sprintf(msg,"%s", "09CRC´íÎó");
+    sprintf(msg, "%s", "09CRC´íÎó");
     break;
   case RC_FILE10_CRC_ERR:
-    sprintf(msg,"%s", "10CRC´íÎó");
+    sprintf(msg, "%s", "10CRC´íÎó");
     break;
   case RC_CARD_INVALID:
-    sprintf(msg,"%s", "ÎÞЧ¿¨");
+    sprintf(msg, "%s", "ÎÞЧ¿¨");
     break;
   case RC_FEENUM_ERROR:
-    sprintf(msg,"%s", "·ÑÂʸöÊý´íÎó");
+    sprintf(msg, "%s", "·ÑÂʸöÊý´íÎó");
     break;
   case RC_NOTSUPPORT:
-    sprintf(msg,"%s", "²»Ö§³Ö");
+    sprintf(msg, "%s", "²»Ö§³Ö");
     break;
   case RC_NOT_SAME_CARD:
-    sprintf(msg,"%s", "²»Í¬¿¨");
+    sprintf(msg, "%s", "²»Í¬¿¨");
     break;
   case RC_MODE_NOT_SUPPORT:
-    sprintf(msg,"%s", "ģʽ²»Ö§³Ö");
+    sprintf(msg, "%s", "ģʽ²»Ö§³Ö");
     break;
   case RC_UPDPROG_ERR:
-    sprintf(msg,"%s", "Éý¼¶Ê§°Ü");
+    sprintf(msg, "%s", "Éý¼¶Ê§°Ü");
     break;
   case RC_CONFPARA_CRC_ERR:
-    sprintf(msg,"%s", "ÅäÖÃCRC´íÎó");
+    sprintf(msg, "%s", "ÅäÖÃCRC´íÎó");
     break;
   case RC_TRANSDTL_NO_ERR:
-    sprintf(msg,"%s", "Á÷Ë®ºÅÒì³£");
+    sprintf(msg, "%s", "Á÷Ë®ºÅÒì³£");
     break;
   case RC_DEVICENO_OUT:
-    sprintf(msg,"%s", "»úºÅ¹ý´ó");
+    sprintf(msg, "%s", "»úºÅ¹ý´ó");
     break;
   case RC_QRCODE_FAILURE:
-  	sprintf(msg,"%s", "¶þάÂë»ñȡʧ°Ü");
-	break;
+    sprintf(msg, "%s", "¶þάÂë»ñȡʧ°Ü");
+    break;
   case RC_QRCODE_TIMEOUT:
-  	sprintf(msg,"%s", "¶þάÂ볬ʱ");
-	break;
+    sprintf(msg, "%s", "¶þάÂ볬ʱ");
+    break;
   case RC_QRCODE_QUERY_FAIL:
-  	sprintf(msg,"%s", "¶þάÂëÈÏ֤ʧ°Ü");
-	break;
+    sprintf(msg, "%s", "¶þάÂëÈÏ֤ʧ°Ü");
+    break;
   case RC_DEV_NOT_LOGIN:
-  	sprintf(msg,"%s", "É豸δǩµ½");
-	break;
+    sprintf(msg, "%s", "É豸δǩµ½");
+    break;
   case RC_DEV_FAULT:
-  	sprintf(msg,"%s", "É豸ÒÉËÆ¹ÊÕÏ");
-	break;
+    sprintf(msg, "%s", "É豸ÒÉËÆ¹ÊÕÏ");
+    break;
   case RC_DEV_NOSET_FLOWSENSOR_UNIT:
-  	sprintf(msg,"%s", "Á÷Á¿¼ÆË㵥λδÉèÖÃ");
-	break;
+    sprintf(msg, "%s", "Á÷Á¿¼ÆË㵥λδÉèÖÃ");
+    break;
   case RC_CARD_AUTHENTICATION:
-  	sprintf(msg,"%s", "¿¨ÈÏ֤ʧ°Ü");
-	break;
+    sprintf(msg, "%s", "¿¨ÈÏ֤ʧ°Ü");
+    break;
+  case RC_LIMIT_CONSUMPTION:
+    sprintf(msg, "%s", "¸ÃÓû§±»ÏÞÖÆÏû·Ñ");
+    break;
   default:
     sprintf(msg,"´íÎóÂë=0x%04x",errcode);
   }
   disp_hint_info_two(pos,hint,msg,DELAY_TIME3s);
 }
 
-void disp_hint_info_three(sp_pos_t* pos,const char* msg1,const char* msg2,const char* msg3,uint32 ms)
+void disp_hint_info_three(sp_pos_t* pos,const char* msg1,const char* msg2,
+                          const char* msg3,uint32 ms)
 {
   show_title();
   show_bottom(pos);