大理水控初始版本
diff --git a/supwisdom/sp_menu.c b/supwisdom/sp_menu.c
new file mode 100644
index 0000000..4447d52
--- /dev/null
+++ b/supwisdom/sp_menu.c
@@ -0,0 +1,655 @@
+#include "sp_menu.h"
+#include "sp_util.h"
+#include "sp_data.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "sp_constant.h"
+#include "sp_communicate.h"
+#include "sp_display.h"
+#include "sp_upgrade.h"
+#include "../nec_hardware.h"
+
+typedef void(*menu_func_t)(sp_pos_t* pos);
+typedef struct
+{
+  char* hit;
+  menu_func_t func;
+} menu_t;
+
+static void sp_show_syspara(sp_pos_t* pos)
+{
+  uint32 ticker;
+  uint8 keycode;
+  uint8 key_press = 1;
+  uint8 max_cnt = 0;
+  uint8 offset = 0;
+  uint8 unconfirm_transnum;
+  char syspara[9][17];
+
+  MEMCLEAR(syspara, sizeof(syspara));
+  sprintf(syspara[offset++], "É豸״̬:");
+  if(pos->devlogin.login_flag == 1)
+  {
+    sprintf(syspara[offset++], "ÒÑÇ©µ½");
+  }
+  else if(pos->devlogin.login_flag == 0)
+  {
+    sprintf(syspara[offset++], "δǩµ½");
+  }
+  else if(pos->devlogin.login_flag == 2)
+  {
+    sprintf(syspara[offset++], "ÒÑ×¢Ïú");
+  }
+  sprintf(syspara[offset++], "Á´Â·×´Ì¬:");
+  if(pos->link_stat)
+  {
+    sprintf(syspara[offset++], "ÁªÍø");
+  }
+  else
+  {
+    sprintf(syspara[offset++], "ÖжÏ");
+  }
+  sprintf(syspara[offset++], "δÉÏ´«Á÷Ë®:");
+  if(pos->unconfirm_transdtl.transaddr <= pos->last_transdtl.transaddr)
+  {
+    if(pos->unconfirm_transdtl.transaddr == pos->last_transdtl.transaddr)
+    {
+      unconfirm_transnum = 1;
+    }
+    else
+    {
+      unconfirm_transnum = ((pos->last_transdtl.transaddr -
+                             pos->unconfirm_transdtl.transaddr)/sizeof(sp_transdtl_t));
+    }
+  }
+  else
+  {
+    unconfirm_transnum = 0;
+  }
+  sprintf(syspara[offset++], "%d±Ê", unconfirm_transnum);
+  sprintf(syspara[offset++], "Ïû·ÑÀàÐÍ:");
+  sprintf(syspara[offset++], "¼ÇÕËÏû·Ñ");
+
+  max_cnt = sizeof(syspara)/sizeof(syspara[0])/2;
+  offset = 0;
+  ticker = sp_get_ticker();
+  while(sp_get_ticker()-ticker <= DELAY_TIME60s)
+  {
+    keycode = sp_get_key();
+    if(keycode != SP_KEY_NONE)
+    {
+      key_press = 1;
+      switch(keycode)
+      {
+      case SP_KEY_0:
+        if(offset < max_cnt-1)
+        {
+          offset++;
+        }
+        break;
+      case SP_KEY_1:
+      case SP_KEY_2:
+      case SP_KEY_3:
+      case SP_KEY_4:
+      case SP_KEY_5:
+      case SP_KEY_6:
+      case SP_KEY_7:
+      case SP_KEY_8:
+      case SP_KEY_9:
+        offset = keycode -SP_KEY_0;
+        if(offset >= max_cnt)
+        {
+          offset = max_cnt -1;
+        }
+        break;
+      case SP_KEY_CLEAR:
+        return;
+      }
+    }
+    if(key_press)
+    {
+      disp_hint_info_two(pos, syspara[2*offset],syspara[2*offset+1],0);
+      key_press = 0;
+      ticker = sp_get_ticker();
+    }
+  }
+}
+
+static uint8 sp_link_test(sp_pos_t* pos)
+{
+  uint8 ret;
+  sp_protocol_request_t req;
+  sp_protocol_response_t resp;
+  MEMCLEAR(&req, sizeof(req));
+  MEMCLEAR(&resp, sizeof(resp));
+
+  disp_hint_info_two(pos, "ÕýÔÚÁ´Â·¼ì²â", "ÇëÉÔµÈ.....", 0);
+  sp_protocol_req_init(&req, SP_CMD_FACTORY_LINK_TEST);
+  req.data[0] = 0;
+  req.data[1] = 0x55;
+  req.data[2] = 0xAA;
+  req.datalen += 3;
+  ret = sp_comm_call(pos, &req, &resp, DELAY_TIME3s);
+  if(!ret)
+  {
+    if(resp.data[0] == 0x55 && resp.data[1] == 0xAA)
+    {
+      if(sp_check_time_valid(resp.data +2))
+      {
+        disp_hint_info_two(pos, "Á´Â·¼ì²â³É¹¦","ʱÖÓ²»ºÏ·¨", DELAY_TIME3s);
+        return ret;
+      }
+      sp_set_bcdtime(resp.data +2);
+      disp_hint_info_two(pos, "Á´Â·¼ì²â³É¹¦","ÒÑͬ²½Ê±ÖÓ", DELAY_TIME3s);
+      return ret;
+    }
+    disp_hint_info_two(pos, "Á´Â·¼ì²âʧ°Ü","ÊÕµ½´íÎó°ü", DELAY_TIME3s);
+    return 1;
+  }
+  disp_hint_info_two(pos, "Á´Â·¼ì²âʧ°Ü","Çë¼ì²âÏß·", DELAY_TIME3s);
+  return ret;
+}
+
+static void show_keyboard_test(sp_pos_t* pos, uint8 offset)
+{
+  char msg[]= {"0123456789C"};
+  char temp[17];
+  snprintf(temp,offset+1,"%s",msg);
+  disp_hint_info_three(pos, "¼üÅÌÒÀ´ÎÊäÈë","0123456789C",temp,0);
+}
+
+static uint8 sp_keyboard_test(sp_pos_t* pos)
+{
+  uint8 kcode;
+  uint32 tick;
+  uint8 offset = 0;
+  uint8 keybuf[12]= {SP_KEY_0,SP_KEY_1,SP_KEY_2,SP_KEY_3,
+                     SP_KEY_4,SP_KEY_5,SP_KEY_6,SP_KEY_7,
+                     SP_KEY_8,SP_KEY_9,SP_KEY_CLEAR,SP_KEY_ENTER
+                    };
+  show_keyboard_test(pos, offset);
+  tick = sp_get_ticker();
+  while((sp_get_ticker()-tick) < DELAY_TIME60s)
+  {
+    sp_feed_dog();
+    kcode = sp_get_key();
+    if(kcode != SP_KEY_NONE)
+    {
+      tick = sp_get_ticker();
+      switch(kcode)
+      {
+      case SP_KEY_0:
+        if(keybuf[offset] == SP_KEY_0)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_1:
+        if(keybuf[offset] == SP_KEY_1)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_2:
+        if(keybuf[offset] == SP_KEY_2)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_3:
+        if(keybuf[offset] == SP_KEY_3)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_4:
+        if(keybuf[offset] == SP_KEY_4)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_5:
+        if(keybuf[offset] == SP_KEY_5)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_6:
+        if(keybuf[offset] == SP_KEY_6)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_7:
+        if(keybuf[offset] == SP_KEY_7)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_8:
+        if(keybuf[offset] == SP_KEY_8)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_9:
+        if(keybuf[offset] == SP_KEY_9)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_CLEAR:
+        if(offset == 0)
+        {
+          disp_hint_info(pos, "È¡Ïû°´¼ü¼ì²â",DELAY_TIME2s);
+          return 1;
+        }
+        if(keybuf[offset] == SP_KEY_CLEAR)
+        {
+          ++offset;
+          show_keyboard_test(pos, offset);
+        }
+        break;
+      case SP_KEY_ENTER:
+        if(keybuf[offset] == SP_KEY_ENTER)
+        {
+          disp_hint_info_two(pos, "¼üÅ̼ì²âÕýÈ·","¼üÅÌУ׼Õý³£",DELAY_TIME3s);
+          return 0;
+        }
+        break;
+      default:
+        break;
+      }
+    }
+  }
+  return 1;
+
+}
+
+static void sp_factory_check(sp_pos_t* pos)
+{
+  sp_link_test(pos);
+  sp_keyboard_test(pos);
+}
+
+static void sp_set_devtime(sp_pos_t* pos)
+{
+  uint32 ticker;
+  uint8 kcode;
+  uint8 key_press = 1;
+  uint8 ctime[6];
+  uint8 offset;
+  char str[13];
+  char msg[17];
+
+  MEMCLEAR(str,sizeof str);
+  sp_get_bcdtime(ctime);
+  offset = 10;
+  sp_hex_to_str(ctime,5,str);
+  ticker = sp_get_ticker();
+  while(sp_get_ticker() -ticker < DELAY_TIME60s)
+  {
+    kcode = sp_get_key();
+    if(kcode != SP_KEY_NONE)
+    {
+      key_press = 1;
+      switch(kcode)
+      {
+      case SP_KEY_0:
+      case SP_KEY_1:
+      case SP_KEY_2:
+      case SP_KEY_3:
+      case SP_KEY_4:
+      case SP_KEY_5:
+      case SP_KEY_6:
+      case SP_KEY_7:
+      case SP_KEY_8:
+      case SP_KEY_9:
+        if(offset < 10)
+        {
+          str[offset++] = '0' + (kcode- SP_KEY_0);
+        }
+        break;
+      case SP_KEY_ENTER:
+        if(offset >= 10)
+        {
+          MEMCLEAR(ctime,sizeof ctime);
+          sp_str_to_bcd(str,10,ctime);
+          if(sp_check_time_valid(ctime))
+          {
+            disp_hint_info_two(pos,"ÉèÖÃʱ¼äʧ°Ü","ʱ¼ä²»ºÏ·¨", DELAY_TIME3s);
+          }
+          else
+          {
+            sp_set_bcdtime(ctime);
+            disp_hint_info_two(pos,"ÉèÖÃʱ¼ä³É¹¦"," ", DELAY_TIME2s);
+            return;
+          }
+        }
+        break;
+      case SP_KEY_CLEAR:
+        if(offset == 0)
+        {
+          return;
+        }
+        offset--;
+        str[offset] = 0;
+        break;
+      }
+    }
+    if(key_press)
+    {
+      sprintf(msg,"%s",str);
+      disp_hint_info_two(pos,"ÉèÖÃʱ¼ä(ymdHm)",msg,0);
+      ticker = sp_get_ticker();
+      key_press = 0;
+    }
+  }
+}
+
+static void sp_manual_login(sp_pos_t* pos)
+{
+  uint16 ret;
+  uint32 tick;
+  sp_protocol_response_t resp;
+  MEMCLEAR(&resp, sizeof(resp));
+  disp_hint_info_two(pos,"ÕýÔڵǼ","ÇëÉÔµÈ...",0);
+  sp_async_equipment_login(pos);
+  tick = sp_get_ticker();
+  while(sp_get_ticker() - tick < DELAY_TIME3s*2)
+  {
+    MEMCLEAR(&resp, sizeof(resp));
+    usart_read((u8*)&resp, sizeof(resp));
+    if(resp.excmd == SP_CMD_LOGIN)
+    {
+      ret = sp_confirm_login(&resp, pos);
+      break;
+    }
+    else
+    {
+      ret = RC_DEV_LOGIN_FAIL;
+    }
+  }
+  if(ret)
+  {
+    char msg[32];
+    sprintf(msg,"´íÎóÂë=%d",ret);
+    disp_hint_info_two(pos,"Ç©µ½Ê§°Ü",msg,DELAY_TIME3s);
+  }
+  else
+  {
+    disp_hint_info(pos,"Ç©µ½³É¹¦",DELAY_TIME3s);
+  }
+}
+
+static void sp_set_devphyid(sp_pos_t* pos)
+{
+  uint32 ticker;
+  uint8 kcode;
+  uint16 ret = 0;
+  uint8 key_press = 1;
+  char msg[17];
+  uint8 devphyid[4];
+  uint8 offset;
+  char str[9];
+  MEMCPY(devphyid,pos->devphyid,sizeof(pos->devphyid));
+  MEMCLEAR(str,sizeof str);
+
+  ticker = sp_get_ticker();
+  offset = 8;
+  sp_hex_to_str(devphyid,4,str);
+  while(sp_get_ticker() -ticker < DELAY_TIME60s)
+  {
+    kcode = sp_get_key();
+    if(kcode != SP_KEY_NONE)
+    {
+      key_press = 1;
+      switch(kcode)
+      {
+      case SP_KEY_0:
+      case SP_KEY_1:
+      case SP_KEY_2:
+      case SP_KEY_3:
+      case SP_KEY_4:
+      case SP_KEY_5:
+      case SP_KEY_6:
+      case SP_KEY_7:
+      case SP_KEY_8:
+      case SP_KEY_9:
+        if(offset < 8)
+        {
+          str[offset++] = '0' +(kcode -SP_KEY_0);
+        }
+        break;
+      case SP_KEY_ENTER:
+        if(offset >= 8)
+        {
+          sp_str_to_hex(str,8,devphyid);
+          if(0 != MEMCMP(pos->devphyid,devphyid,4))
+          {
+            ret = sp_save_devphyid(pos, devphyid);
+          }
+          if(!ret)
+          {
+            MEMCPY(pos->devphyid,devphyid,4);
+            sprintf(msg,"ID: %02x%02x%02x%02x",devphyid[0],devphyid[1],devphyid[2],devphyid[3]);
+            disp_hint_info_two(pos,"ÉèÖÃÎïÀíID³É¹¦",msg, DELAY_TIME2s);
+          }
+          else
+          {
+            show_error(pos,"±£´æÎïÀíIDʧ°Ü",ret);
+          }
+          return;
+        }
+        break;
+      case SP_KEY_CLEAR:
+        if(offset > 0)
+        {
+          offset--;
+          str[offset] = 0;
+        }
+        else
+        {
+          return;
+        }
+        break;
+      }
+    }
+    if(key_press)
+    {
+      sprintf(msg,"%s",str);
+      disp_hint_info_two(pos,"ÉèÖÃÎïÀíID:",msg,0);
+      ticker = sp_get_ticker();
+      key_press = 0;
+    }
+  }
+  return;
+}
+static void sp_set_deviceno(sp_pos_t* pos)
+{
+  uint32 ticker;
+  uint8 kcode;
+  uint16 ret = 0;
+  uint8 key_press = 1;
+  uint16 tempno;
+  uint8 deviceno = pos->deviceno;
+  char msg[17];
+  char temp[17];
+  ticker = sp_get_ticker();
+  while(sp_get_ticker() -ticker < DELAY_TIME60s)
+  {
+    kcode = sp_get_key();
+    if(kcode != SP_KEY_NONE)
+    {
+      key_press = 1;
+      switch(kcode)
+      {
+      case SP_KEY_0:
+      case SP_KEY_1:
+      case SP_KEY_2:
+      case SP_KEY_3:
+      case SP_KEY_4:
+      case SP_KEY_5:
+      case SP_KEY_6:
+      case SP_KEY_7:
+      case SP_KEY_8:
+      case SP_KEY_9:
+        tempno = (uint16)deviceno;
+        tempno *=10;
+        tempno += (kcode-SP_KEY_0);
+        if(tempno > 0 && tempno < DEV_MAX_DEVICENO)
+        {
+          deviceno = (uint8)tempno;
+        }
+        break;
+      case SP_KEY_ENTER:
+        if(deviceno > 0 && deviceno <= DEV_MAX_DEVICENO)
+        {
+          if(pos->deviceno != deviceno)
+          {
+            ret = sp_save_deviceno(pos,deviceno);
+          }
+          if(!ret)
+          {
+            pos->deviceno = deviceno;
+            sprintf(msg,"»úºÅ: %d",deviceno);
+            disp_hint_info_two(pos,"ÉèÖûúºÅ³É¹¦",msg, DELAY_TIME2s);
+          }
+          else
+          {
+            show_error(pos,"±£´æ»úºÅʧ°Ü",ret);
+          }
+          return;
+        }
+        else
+        {
+          sprintf(msg,"·¶Î§(1-%d)",DEV_MAX_DEVICENO);
+          disp_hint_info_two(pos,"»úºÅ´íÎó",msg, DELAY_TIME3s);
+        }
+      case SP_KEY_CLEAR:
+        if(deviceno == 0)
+        {
+          return;
+        }
+        deviceno = 0;
+        break;
+      }
+    }
+    if(key_press)
+    {
+      sprintf(temp,"ÉèÖûúºÅ(1-%d)",DEV_MAX_DEVICENO);
+      sprintf(msg,"%d",deviceno);
+      disp_hint_info_two(pos,temp,msg,0);
+      ticker = sp_get_ticker();
+      key_press = 0;
+    }
+  }
+  return;
+}
+
+static void clear_transdtl(sp_pos_t* pos)
+{
+  if(0 == sp_check_passwd(pos,"Çå¿ÕÁ÷Ë®ÃÜÂë:","\x9\x1\x4\x3\x8\x7"))
+  {
+    disp_hint_info_two(pos,"Çå¿ÕÁ÷Ë®","ÇëÉÔµÈ...",0);
+    sp_clear_transdtl(pos);
+  }
+}
+
+static void manual_upgrade(sp_pos_t* pos)
+{
+  if(0 == sp_check_passwd(pos, "ÔÚÏßÉý¼¶ÃÜÂë:","\x9\x1\x4\x3\x8\x7"))
+  {
+    sp_manual_upgrade(pos);
+  }
+}
+
+static void reset_factory(sp_pos_t* pos)
+{
+  if(0 == sp_check_passwd(pos, "»Ö¸´³ö³§ÃÜÂë:","\x9\x1\x4\x3\x8\x7"))
+  {
+    sp_reset_factory(pos);
+  }
+}
+
+void sp_menu_options(sp_pos_t* pos)
+{
+  uint32 ticker = 0;
+  uint8 keycode;
+  uint8 page;
+  uint8 max_cnt;
+  uint8 key_press = 1;
+
+  menu_t menus[] =
+  {
+    {"1.²é¿´²ÎÊý", sp_show_syspara},
+    {"2.¹¤³§²âÊÔ", sp_factory_check},
+    {"3.ÉèÖÃʱ¼ä", sp_set_devtime},
+    {"4.ÊÖ¶¯µÇ¼", sp_manual_login},
+    {"5.ÉèÖÃÎïÀíid", sp_set_devphyid},
+    {"6.ÉèÖûúºÅ", sp_set_deviceno},
+    {"7.Çå¿ÕÁ÷Ë®", clear_transdtl},
+    {"8.ÔÚÏßÉý¼¶", manual_upgrade},
+    {"9.»Ö¸´³ö³§", reset_factory}
+  };
+  max_cnt = sizeof(menus)/sizeof(menu_t)/3;
+  page = 0;
+  ticker = sp_get_ticker();
+  while(sp_get_ticker()-ticker <= DELAY_TIME60s*5)
+  {
+    sp_feed_dog();
+    keycode = sp_get_key();
+    if(keycode != SP_KEY_NONE)
+    {
+      key_press = 1;
+      switch(keycode)
+      {
+      case SP_KEY_0:
+        if(page < (max_cnt-1))
+        {
+          page++;
+        }
+        break;
+      case SP_KEY_1:
+      case SP_KEY_2:
+      case SP_KEY_3:
+      case SP_KEY_4:
+      case SP_KEY_5:
+      case SP_KEY_6:
+      case SP_KEY_7:
+      case SP_KEY_8:
+      case SP_KEY_9:
+        if(menus[keycode-SP_KEY_1].func != NULL)
+        {
+          menus[keycode-SP_KEY_1].func(pos);
+        }
+        break;
+      case SP_KEY_CLEAR:
+        if(page == 0)
+        {
+          return;
+        }
+        page--;
+        break;
+      default:
+        break;
+      }
+    }
+    if(key_press)
+    {
+      disp_hint_info_three(pos, menus[page*3].hit, menus[page*3+1].hit, menus[page*3+2].hit, 0);
+      key_press = 0;
+      ticker = sp_get_ticker();
+    }
+  }
+}