大理水控初始版本
diff --git a/supwisdom/main.c b/supwisdom/main.c
new file mode 100644
index 0000000..c5fdc97
--- /dev/null
+++ b/supwisdom/main.c
@@ -0,0 +1,53 @@
+//пªÆÕË®¿Ø³ÌÐò
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "sp_config.h"
+#include "sp_display.h"
+#include "sp_data.h"
+#include "sp_util.h"
+#include "sp_consume.h"
+#include "sp_communicate.h"
+
+static sp_pos_t POS;
+
+int main(void)
+{
+ uint32 tick = 0;
+ uint32 lasttick = 0;
+ sp_cardworkstate_t cardWorkState;
+ MEMCLEAR(&POS, sizeof(POS));
+ MEMCLEAR(&cardWorkState, sizeof(cardWorkState));
+ sp_init();
+ sp_key_init();
+ Delay_ms(DELAY_TIME1s);
+ sp_load_config(&POS);
+
+ show_home(&POS);
+
+ while(1)
+ {
+ tick = sp_get_ticker();
+ sp_feed_dog();
+ sp_valve_control();
+ sp_confirm_paymode(&POS, &cardWorkState);
+ sp_communicate(&POS);
+ if(POS.paymode == PAYMODE_QRCODE)
+ {
+ if(tick - lasttick >= DELAY_TIME100ms)
+ {
+ lasttick = tick;
+ sp_qrcode_handle(&POS, &cardWorkState);
+ }
+ }
+ else
+ {
+ if(tick - lasttick >= DELAY_TIME100ms)
+ {
+ lasttick = tick;
+ sp_test_card_state(&POS, &cardWorkState, tick);
+ sp_card_handle(&POS, &cardWorkState);
+ }
+ }
+ }
+}
diff --git a/supwisdom/sp_card.c b/supwisdom/sp_card.c
new file mode 100644
index 0000000..5c6796a
--- /dev/null
+++ b/supwisdom/sp_card.c
@@ -0,0 +1,98 @@
+#include "../nec_apdu.h"
+#include "sp_des.h"
+#include "sp_constant.h"
+#include "sp_util.h"
+#include "sp_card.h"
+
+static uint8* prcv_buff = NULL;
+static uint8 rcv_len = 0;
+
+uint16 sp_select_sfi(uint8 sfi[2])
+{
+ uint16 ret;
+ uint8 cmd_buff[10];
+
+ cmd_buff[0] = 0x00; //CLA
+ cmd_buff[1] = 0xA4; //INS
+ cmd_buff[2] = 0x00; //P1
+ cmd_buff[3] = 0x00; //P2
+ cmd_buff[4] = 0x02; //Lc
+ memcpy(cmd_buff + 5, sfi, 2);
+
+ ret = card_cpu_exchange(cmd_buff, 2 + 5, 0, &prcv_buff, &rcv_len);
+ if(ret != RETCODE_OK)
+ {
+ return ret;
+ }
+ return 0;
+}
+
+uint16 sp_select_adf(void)
+{
+ uint16 ret;
+ uint8 cmd_buff[] = {"\x00\xA4\x04\x00\x0F\xD1\x56\x00\x00\x01\xBD\xF0\xCA\xCB\xB4\xEF\xD6\xA7\xB8\xB6"};
+ ret = card_cpu_exchange(cmd_buff, sizeof(cmd_buff) - 1, 0, &prcv_buff, &rcv_len);
+ if(ret != RETCODE_OK)
+ {
+ return ret;
+ }
+ return 0;
+}
+
+uint8 sp_card_request(sp_card_t* cardpcd)
+{
+
+ uint8 sak;
+ uint8 snr[8];
+
+ if(!card_request(&sak, snr))
+ {
+ if((sak & 0x20))
+ {
+ if(!card_cpu_mode())
+ {
+ Delay_ms(200);
+ if(sp_select_sfi("\x3f\x00") == 0)
+ {
+ sp_select_adf();
+ cardpcd->cardphyid[0] = snr[3];
+ cardpcd->cardphyid[1] = snr[2];
+ cardpcd->cardphyid[2] = snr[1];
+ cardpcd->cardphyid[3] = snr[0];
+ cardpcd->cardtype = TAG_TYPE_CPU;
+ return 0;
+ }
+ }
+ }
+ else
+ {
+ cardpcd->cardtype = TAG_TYPE_UNKONWN;
+ return 1;
+ }
+ }
+ return 1;
+}
+
+int8 sp_check_cpu_exist(void)
+{
+ return card_cpu_exist();
+}
+
+static uint16 sp_cpu_read(sp_card_t* card)
+{
+ uint16 ret = 0;
+ MEMCLEAR(card->citizen_cardno, sizeof(card->citizen_cardno));
+ MEMCPY(card->expiredate, "\x20\x22\x08\x02", 4);
+ return ret;
+}
+
+uint16 sp_card_read(sp_card_t* card)
+{
+ switch(card->cardtype)
+ {
+ case TAG_TYPE_CPU:
+ return sp_cpu_read(card);
+ default:
+ return 1;
+ }
+}
diff --git a/supwisdom/sp_card.h b/supwisdom/sp_card.h
new file mode 100644
index 0000000..5981cfa
--- /dev/null
+++ b/supwisdom/sp_card.h
@@ -0,0 +1,26 @@
+#ifndef _SP_CARD_H_
+#define _SP_CARD_H_
+
+#include "sp_config.h"
+
+#define SP_FILE09 0x01
+#define SP_FILE10 0x02
+#define SP_FILE12 0x04
+#define SP_FILE15 0x08
+
+#define WATER_RECORD_NO 4
+#define RETCODE_OK 0x9000
+#define RETCODE_INSUFFICIENT 0x9401 //Óà¶î²»×ã
+#define RC_CPU_FILENOTFOUND 0x6A82
+#define RC_CPU_NO_EXTAUTH 0x6982
+#define RC_CPU_FILE_NOT_EXIST 0x6A83
+#define RC_CPU_NOMAC 0x9406
+
+#define CARD_STATUS_OK 0
+
+uint8 sp_card_request(sp_card_t* cardpcd);
+int8 sp_check_cpu_exist(void);
+int8 sp_card_rf_reset(void);
+uint16 sp_card_read(sp_card_t* card);
+
+#endif
diff --git a/supwisdom/sp_communicate.c b/supwisdom/sp_communicate.c
new file mode 100644
index 0000000..7e3ac69
--- /dev/null
+++ b/supwisdom/sp_communicate.c
@@ -0,0 +1,590 @@
+#include "sp_communicate.h"
+#include "sp_util.h"
+#include "sp_flash.h"
+#include "sp_constant.h"
+#include "sp_data.h"
+#include "sp_msgpack.h"
+#include "sp_display.h"
+#include "../sys_hw/drv_usart.h"
+
+static void sp_usart_send(sp_pos_t* pos, sp_protocol_request_t* req)
+{
+ uint8 sendBuff[264];
+ MEMCLEAR(sendBuff, sizeof(sendBuff));
+
+ pos->last_comm_status.command = req->excmd;
+ pos->last_comm_status.sendtime = sp_get_ticker();
+
+ sp_protocol_crc((uint8*)req +2, req->datalen, (uint8*)req +2 +req->datalen);
+ req->datalen += 2;
+ MEMCPY(sendBuff, req, req->datalen+2);
+ usart_send(sendBuff, req->datalen+2);
+}
+
+static uint8 sp_usart_recv(sp_pos_t* pos, sp_protocol_response_t* resp, int32 timeout_ms)
+{
+ uint32 tick = 0;
+ tick = sp_get_ticker();
+ while(1)
+ {
+ MEMCLEAR(resp, sizeof(sp_protocol_response_t));
+ usart_read((u8*)resp, sizeof(sp_protocol_response_t));
+ if(pos->last_comm_status.command == resp->excmd)
+ {
+ MEMCLEAR(&(pos->last_comm_status), sizeof(sp_comm_status_t));
+ return resp->retcode;
+ }
+ if((sp_get_ticker() - tick) >= timeout_ms)
+ {
+ return 1;
+ }
+ }
+}
+uint8 sp_comm_call(sp_pos_t* pos, sp_protocol_request_t* req,
+ sp_protocol_response_t* resp, int32 timeout_ms)
+{
+ sp_usart_send(pos, req);
+ return sp_usart_recv(pos, resp, timeout_ms);
+}
+
+void sp_protocol_req_init(sp_protocol_request_t* req, uint8 command)
+{
+ MEMCLEAR(req,sizeof(sp_protocol_request_t));
+ req->command = PROTOCOL_COMMAND_V2;
+ req->excmd = command;
+ req->flag = PROTOCOL_FLAG_PACK(req->flag);
+ req->flag = PROTOCOL_WITHOUT_MAC(req->flag);
+ req->datalen = 3;
+}
+
+static uint16 sp_confirm_card_authentication(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 size;
+ uint16 ret;
+ int32 timeout_ms = COMM_WAIT_TIME;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+ sp_protocol_response_t resp;
+
+ disp_hint_info(pos,"ÕýÔÚÉí·ÝÈÏÖ¤ÖÐ",DELAY_TIME2s);
+ ret = sp_usart_recv(pos, &resp, timeout_ms);
+ if(ret)
+ {
+ ret = RC_CARD_AUTHENTICATION;
+ return ret;
+ }
+
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_INT_WATERLIMIT,field.key))
+ {
+ card->waterlimit = field.val.intval;
+ }
+ else if(IS_KEY(PK_BIN_BILLNO,field.key))
+ {
+ MEMCPY(card->billno, field.val.binval, field.strlen);
+ }
+ else if(IS_KEY(PK_INT_FEEAMOUNT,field.key))
+ {
+ card->feepara.fee_amt = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FEEUNIT, field.key))
+ {
+ card->feepara.fee_unit = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FEESTART, field.key))
+ {
+ card->feepara.fee_start = field.val.intval;
+ }
+ }
+ disp_hint_info(pos,"Éí·ÝÈÏÖ¤³É¹¦",DELAY_TIME1s);
+ return 0;
+}
+
+//ºǫ́¶Ô¿¨µÄÉí·ÝÈÏÖ¤
+uint16 sp_card_authentication(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 ctime[6];
+ sp_protocol_request_t req;
+ cw_pack_context pack;
+ MEMCLEAR(&req, sizeof(req));
+ MEMCLEAR(&pack, sizeof(req));
+ MEMCLEAR(ctime, sizeof ctime);
+
+ sp_get_bcdtime(ctime);
+ sp_protocol_req_init(&req, SP_CMD_CARD_AUTHENTICATION);
+ sp_pack_init(&pack, req.data, sizeof(req.data));
+ cw_pack_map_size(&pack,4);
+
+ sp_pack_put_bin(&pack, PK_BIN_CARDPHYID, card->cardphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_CITIZEN_CARDNO, card->citizen_cardno, 12);
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, pos->devphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_DEVTIME, ctime, 6);
+
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return sp_confirm_card_authentication(pos, card);
+}
+
+//É豸ǩµ½
+uint16 sp_async_equipment_login(sp_pos_t* pos)
+{
+ sp_protocol_request_t req;
+ cw_pack_context pack;
+ uint8 ctime[6];
+ MEMCLEAR(ctime, sizeof(ctime));
+ pos->heartbeat.heart_status = HEART_SEND;
+
+ sp_get_bcdtime(ctime);
+ sp_protocol_req_init(&req, SP_CMD_LOGIN);
+ sp_pack_init(&pack, req.data, sizeof(req.data));
+ cw_pack_map_size(&pack, 5);
+
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, pos->devphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_DEVTIME, ctime, 6);
+ sp_pack_put_str(&pack, PK_STR_DEVTYPE, DEV_TYPE);
+ sp_pack_put_str(&pack, PK_STR_VERSION, PRO_VERSION);
+ sp_pack_put_bin(&pack, PK_BIN_DEVICEKEY, (pos->sysconf.deviceKey), 8);
+
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return 0;
+}
+
+//ÐÄÌøÈ·ÈÏ£¬¼ì²âÍøÂçÊÇ·ñÕý³£
+uint16 sp_async_heartbeat(sp_pos_t* pos)
+{
+ uint8 ctime[6];
+ uint8 unconfirm_transnum = 0;
+ sp_protocol_request_t req;
+ cw_pack_context pack;
+
+ pos->heartbeat.heart_status = HEART_SEND;
+ if(pos->unconfirm_transdtl.transaddr <= pos->last_transdtl.transaddr)
+ {
+ unconfirm_transnum = ((pos->last_transdtl.transaddr - pos->unconfirm_transdtl.transaddr) /
+ sizeof(sp_transdtl_t)) + 1;
+ }
+ else
+ {
+ unconfirm_transnum = 0;
+ }
+ sp_protocol_req_init(&req, SP_CMD_HEARTBEAT);
+ sp_pack_init(&pack, req.data, sizeof(req.data));
+ cw_pack_map_size(&pack, 6);
+
+ sp_get_bcdtime(ctime);
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, pos->devphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_DEVTIME, ctime, 6);
+ sp_pack_put_str(&pack, PK_STR_DEVTYPE, DEV_TYPE);
+ sp_pack_put_str(&pack, PK_STR_VERSION, PRO_VERSION);
+ sp_pack_put_int(&pack, PK_INT_UNTRANSCONST, unconfirm_transnum);
+ sp_pack_put_int(&pack, PK_INT_WORKMODE, pos->sysconf.work_mode);
+
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return 0;
+}
+
+static uint16 sp_confirm_qrcode_init(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 size;
+ uint16 ret;
+ int32 timeout_ms = COMM_WAIT_TIME;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+ sp_protocol_response_t resp;
+
+ ret = sp_usart_recv(pos, &resp, timeout_ms);
+ if(ret)
+ {
+ ret = RC_QRCODE_FAILURE;
+ return ret;
+ }
+
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_STR_SHORT_URL, field.key))
+ {
+ MEMCPY(card->qrcode.qrcode_url, field.val.strval, field.strlen);
+ }
+ else if(IS_KEY(PK_BIN_BILLNO, field.key))
+ {
+ MEMCPY(card->billno, field.val.binval, field.strlen);
+ }
+ else if(IS_KEY(PK_INT_VAILDTIME, field.key))
+ {
+ card->qrcode.validtime = field.val.intval;
+ }
+ }
+ card->qrcode.starttime = sp_get_ticker();
+ return 0;
+}
+
+//¶þάÂë»ñÈ¡
+uint16 sp_qrcode_init(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 ctime[6];
+ sp_protocol_request_t req;
+ cw_pack_context pack;
+
+ sp_get_bcdtime(ctime);
+ sp_protocol_req_init(&req, SP_CMD_SHORTURL);
+ sp_pack_init(&pack, req.data, sizeof(req.data));
+ cw_pack_map_size(&pack, 2);
+
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, pos->devphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_DEVTIME, ctime, 6);
+
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return sp_confirm_qrcode_init(pos, card);
+}
+
+//¶þάÂëÈ·ÈÏ£¬»ñȡ֧¸¶×´Ì¬
+static uint16 sp_confirm_qrcode_query(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 size;
+ uint16 ret;
+ int32 timeout_ms = COMM_WAIT_TIME;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+ sp_protocol_response_t resp;
+
+ ret = sp_usart_recv(pos, &resp, timeout_ms);
+ if(ret)
+ {
+ ret = RC_QRCODE_QUERY_FAIL;
+ return ret;
+ }
+
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_BIN_BILLNO, field.key))
+ {
+ MEMCPY(card->billno, field.val.binval, field.strlen);
+ }
+ else if(IS_KEY(PK_INT_AUTHSTATUS, field.key))
+ {
+ card->qrcode.authstatus = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_PAYSTATUS, field.key))
+ {
+ card->qrcode.paystatus = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_PAYAMT, field.key))
+ {
+ card->qrcode.paidAmount = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FEEAMOUNT,field.key))
+ {
+ card->feepara.fee_amt = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FEEUNIT, field.key))
+ {
+ card->feepara.fee_unit = field.val.intval;
+ }
+ }
+ return resp.retcode;
+}
+
+uint16 sp_qrcode_query(sp_pos_t* pos, sp_card_t* card)
+{
+ uint8 ctime[6];
+ sp_protocol_request_t req;
+ cw_pack_context pack;
+
+ sp_get_bcdtime(ctime);
+ sp_protocol_req_init(&req, SP_CMD_QRCODE_PAY_QUERY);
+ sp_pack_init(&pack, req.data, sizeof(req.data));
+ cw_pack_map_size(&pack, 2);
+
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, pos->devphyid, 4);
+ sp_pack_put_bin(&pack, PK_BIN_BILLNO, card->billno, sizeof(card->billno));
+
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return sp_confirm_qrcode_query(pos, card);
+}
+
+//Á÷Ë®ÉÏ´«
+static uint8 transdtl_account_bilLno[10];
+static uint16 sp_async_upload_transdtl(sp_pos_t* pos, sp_transdtl_t* transdtl)
+{
+ uint8 crc[2];
+ cw_pack_context pack;
+ sp_protocol_request_t req;
+
+ MEMCPY(transdtl_account_bilLno, transdtl->billno, sizeof(transdtl->billno));
+ sp_protocol_req_init(&req, SP_CMD_TRANSDTL_ACCOUNT);
+ sp_pack_init(&pack,req.data,sizeof(req.data));
+ cw_pack_map_size(&pack,10);
+
+ sp_pack_put_bin(&pack, PK_BIN_DEVPHYID, transdtl->devphyid,4);
+ sp_pack_put_bin(&pack, PK_BIN_TRANSDATE, transdtl->transdate,3);
+ sp_pack_put_bin(&pack, PK_BIN_TRANSTIME, transdtl->transtime,3);
+ sp_pack_put_bin(&pack, PK_BIN_BILLNO, transdtl->billno, sizeof(transdtl->billno));
+ sp_pack_put_bin(&pack, PK_BIN_CARDPHYID, transdtl->cardphyid,
+ sizeof(transdtl->cardphyid));
+ sp_pack_put_int(&pack, PK_INT_TRANSWAY, transdtl->transway);
+ sp_pack_put_int(&pack, PK_INT_AMOUNT, transdtl->amount);
+ sp_pack_put_int(&pack, PK_INT_PAYAMT, transdtl->paidAmount);
+ sp_pack_put_int(&pack, PK_INT_FLOWSENSORS, transdtl->flowsensors);
+ sp_pack_put_int(&pack, PK_INT_FLAG, transdtl->transtatus);
+
+ sp_protocol_crc((uint8*)transdtl, sizeof(sp_transdtl_t)-2,crc);
+ req.datalen += sp_pack_length(&pack);
+ sp_usart_send(pos, &req);
+ return 0;
+}
+
+//È·ÈÏÁ÷ˮ״̬
+static uint8 sp_confirm_transdtl_account(sp_protocol_response_t* resp, sp_pos_t* pos)
+{
+ uint8 size;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ if(!resp->retcode)
+ {
+ sp_unpack_init(&unpack, resp->data, resp->datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_BIN_BILLNO,field.key))
+ {
+ if(MEMCMP(field.val.binval, transdtl_account_bilLno,
+ sizeof(transdtl_account_bilLno)) == 0)
+ {
+ pos->unconfirm_transdtl.transaddr+= sizeof(sp_transdtl_t);
+ if(ADDR_TRANSDTL_END <= pos->unconfirm_transdtl.transaddr)
+ {
+ pos->unconfirm_transdtl.transaddr= ADDR_TRANSDTL_BEGIN;
+ }
+ return sp_write_unconfirm_record(pos);
+ }
+ }
+ }
+ }
+ return resp->retcode;
+
+}
+
+static uint8 sp_confirm_heartbeat(sp_protocol_response_t* resp, sp_pos_t* pos)
+{
+ uint8 size;
+ uint8 ctime[6];
+ uint8 systime[7];
+ uint8 login_flag = 0;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ if(resp->retcode)
+ {
+ return resp->retcode;
+ }
+ pos->heartbeat.heart_status = HEART_RECV;
+
+ sp_unpack_init(&unpack,resp->data,resp->datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_BIN_SYSTIME, field.key))
+ {
+ if(field.strlen == 7)
+ {
+ MEMCPY(systime,field.val.binval,7);
+ sp_get_bcdtime(ctime);
+ if(MEMCMP(ctime,systime +1,5) != 0)
+ {
+ if(!sp_check_time_valid(systime +1))
+ {
+ sp_set_bcdtime(systime +1);
+ }
+ }
+ }
+ }
+ else if(IS_KEY(PK_STR_STATUS, field.key))
+ {
+ if(MEMCMP(field.val.strval, "normal", field.strlen) == 0)
+ {
+ login_flag = 1;
+ }
+ else if(MEMCMP(field.val.strval, "logout", field.strlen) == 0)
+ {
+ login_flag = 0;
+ }
+ else if(MEMCMP(field.val.strval, "closed", field.strlen) == 0)
+ {
+ login_flag = 2;
+ }
+ }
+ }
+ sp_save_heartbeat_info(pos, login_flag);
+ return resp->retcode;
+}
+
+uint8 sp_confirm_login(sp_protocol_response_t* resp, sp_pos_t* pos)
+{
+ uint8 size;
+ uint8 ctime[6];
+ uint8 systime[7];
+ uint8 login_flag = 0;
+ uint8 unit = 0;
+ uint8 offline_maxhour = 0;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ MEMCLEAR(ctime, sizeof(ctime));
+ MEMCLEAR(systime, sizeof(systime));
+ if(resp->retcode)
+ {
+ return resp->retcode;
+ }
+ pos->heartbeat.heart_status = HEART_RECV;
+
+ sp_unpack_init(&unpack,resp->data,resp->datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_INT_OFFLINEMAXHOUR, field.key))
+ {
+ offline_maxhour = field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_PULSEINHML, field.key))
+ {
+ unit = field.val.intval;
+ }
+ else if(IS_KEY(PK_BIN_SYSTIME, field.key))
+ {
+ if(field.strlen == 7)
+ {
+ MEMCPY(systime,field.val.binval,7);
+ sp_get_bcdtime(ctime);
+ if(MEMCMP(ctime,systime +1,5) != 0)
+ {
+ if(!sp_check_time_valid(systime +1))
+ {
+ sp_set_bcdtime(systime +1);
+ }
+ }
+ }
+ }
+ }
+
+ login_flag = 1;
+ sp_save_login_info(pos, login_flag, unit, offline_maxhour);
+ return resp->retcode;
+}
+
+static protocol_cmd_t protocol_cmds[] =
+{
+ {SP_CMD_TRANSDTL_ACCOUNT, sp_confirm_transdtl_account},
+ {SP_CMD_HEARTBEAT, sp_confirm_heartbeat},
+ {SP_CMD_LOGIN, sp_confirm_login},
+ {0, NULL}
+};
+
+static uint16 sp_async_confirm_process(sp_pos_t* pos)
+{
+ uint8 ret = 0;
+ uint8 i = 0;
+ int32 timeout_ms = COMM_WAIT_TIME;
+ sp_protocol_response_t resp;
+
+ ret = sp_usart_recv(pos, &resp, timeout_ms);
+ if(ret)
+ {
+ return ret;
+ }
+ while(protocol_cmds[i].func != NULL && protocol_cmds[i].cmd != 0)
+ {
+ if(protocol_cmds[i].cmd == resp.excmd)
+ {
+ return protocol_cmds[i].func(&resp, pos);
+ }
+ ++i;
+ }
+ return 1;
+}
+
+//¼ì²âÉ豸ͨѶ״̬£¬¿ÕÏÐʱ¼ä½øÐÐÁ÷Ë®´¦ÀíµÈ¹¤×÷
+static void sp_check_and_switch_linkstat(sp_pos_t* pos)
+{
+ if(pos->heartbeat.heart_status == HEART_SEND)
+ {
+ //ÒÑ·¢ËÍÐÄÌø£¬Î´ÊÕµ½Ó¦´ð
+ pos->link_stat = 0;
+ pos->heartbeat.heart_status = HEART_INIT;
+ }
+ else if(pos->heartbeat.heart_status == HEART_RECV)
+ {
+ //ÒÑ·¢ËÍÐÄÌø£¬ÊÕµ½Ó¦´ð
+ pos->link_stat = 1;
+ pos->heartbeat.heart_status = HEART_INIT;
+ }
+}
+
+void sp_communicate(sp_pos_t* pos)
+{
+ uint16 ret = 0;
+ uint32 ticker = 0;
+ sp_transdtl_t transdtl;
+
+ if(pos->deviceno == 0)
+ {
+ return;
+ }
+ ticker = sp_get_ticker();
+ 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*60*24)
+ {
+ 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_TIME60s*2)
+ {
+ pos->heartbeat.last_heartbeat_ticker = ticker;
+ sp_async_heartbeat(pos);
+ }
+ else
+ {
+ sp_check_and_switch_linkstat(pos);
+ if(pos->link_stat)
+ {
+ //¼ì²âµ±Ç°ÊÇ·ñÓÐδÉÏ´«µÄÁ÷Ë®
+ if(pos->unconfirm_transdtl.transaddr <= pos->last_transdtl.transaddr)
+ {
+ ret = sp_flash_read((uint32)pos->unconfirm_transdtl.transaddr, (uint8*)&transdtl,
+ sizeof(transdtl));
+ if(!ret)
+ {
+ if(!pos->sysconf.work_mode)
+ {
+ pos->heartbeat.last_heartbeat_ticker = ticker;
+ sp_async_upload_transdtl(pos, &transdtl);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sp_async_confirm_process(pos);
+}
diff --git a/supwisdom/sp_communicate.h b/supwisdom/sp_communicate.h
new file mode 100644
index 0000000..b8daf77
--- /dev/null
+++ b/supwisdom/sp_communicate.h
@@ -0,0 +1,139 @@
+#ifndef _SP_COMMUNICATE_H_
+#define _SP_COMMUNICATE_H_
+
+#include "sp_config.h"
+
+#define PROTOCOL_COMMAND_V2 0x80
+#define PROTOCOL_WITH_MAC(x) ((x) | 0x80)
+#define PROTOCOL_WITHOUT_MAC(x) ((x) & 0x7F)
+#define PROTOCOL_FLAG_PACK(x) ((x) | 0x01)
+#define PROTOCOL_FLAG_DES_PACK(x) ((x) & 0xFE)
+
+#define PK_BIN_DEVPHYID "a"
+#define PK_INT_CARDNO "b"
+#define PK_BIN_CARDVERNO "c"
+#define PK_INT_DEVSEQNO "d"
+#define PK_STR_VERSION "e"
+#define PK_INT_BLKINDEX "f"
+#define PK_BIN_TRANSDATE "g"
+#define PK_BIN_TRANSTIME "h"
+#define PK_INT_PAYAMT "i"
+#define PK_INT_AMOUNT "j"
+#define PK_INT_FLAG "k"
+#define PK_STR_AVAIABLE "l"
+#define PK_BIN_SYSTIME "m"
+#define PK_STR_UPGRADE "n"
+#define PK_BIN_BLKBITMAP "o"
+#define PK_BIN_FILECRC "p"
+#define PK_INT_FILESIZE "q"
+#define PK_INT_SEQNO "r"
+#define PK_BIN_FILEDATA "s"
+#define PK_INT_MAXSEQNO "t"
+#define PK_INT_SECONDS "u"
+#define PK_INT_CREDIT_TOTAL "v"
+#define PK_INT_CREDIT_PAYCNT "w"
+#define PK_INT_CREDIT_AVAILABAL "x"
+#define PK_INT_CREDIT_NO "y"
+#define PK_BIN_EXPIRE "z"
+#define PK_INT_FEETYPE "A"
+#define PK_BIN_CARDPHYID "B"
+#define PK_STR_STATUS "C"
+#define PK_INT_BALANCE "D"
+#define PK_INT_OFFLINE_FORBID_FLAG "E"
+#define PK_INT_CREDIT_PAYCNT_LACK "F"
+#define PK_INT_ONCETIME_LIMIT "G"
+#define PK_INT_DAYTOTAL_LIMIT "H"
+#define PK_INT_COUNT "J"
+#define PK_BIN_BLKLIST "K"
+#define PK_INT_CREDIT_NEXT_NO "L"
+#define PK_BIN_RANDOM "M"
+#define PK_INT_DEVICENO "N"
+#define PK_BIN_DEVTIME "O"
+#define PK_STR_DEVTYPE "P"
+#define PK_BIN_SAMNO "Q"
+#define PK_INT_PARAVERNO "R"
+#define PK_INT_PARA_GROUPID "S"
+#define PK_INT_FEEVERNO "T"
+#define PK_INT_FEE_CFGID "U"
+#define PK_BIN_WSCLIENT_ID "V"
+#define PK_INT_WSCLIENT_STATUS "W"
+#define PK_INT_FLOWSENSORS "X"
+#define PK_BIN_SOFT_MD5 "Y"
+#define PK_INT_CUSTID "Z"
+#define PK_STR_SHORT_URL "0"
+#define PK_INT_WATERSTATUS "1"
+#define PK_INT_WATERMUCH "2"
+
+#define PK_BIN_BILLNO "3"
+#define PK_INT_TRANSWAY "4"
+#define PK_INT_UNTRANSCONST "5"
+#define PK_BIN_DEVICEKEY "6"
+#define PK_INT_WORKMODE "7"
+#define PK_INT_OFFLINEMAXHOUR "8"
+#define PK_INT_PULSEINHML "9"
+#define PK_BIN_CITIZEN_CARDNO "10"
+#define PK_INT_WATERLIMIT "11"
+#define PK_INT_FEEAMOUNT "12"
+#define PK_INT_FEEUNIT "13"
+#define PK_INT_VAILDTIME "14"
+#define PK_INT_AUTHSTATUS "15"
+#define PK_INT_PAYSTATUS "16"
+#define PK_INT_FEESTART "17"
+
+#define SP_CMD_UPGRADE 0x20 //ÔÚÏßÉý¼¶
+#define SP_CMD_TRANSDTL_ACCOUNT 0x22 //¼ÇÕËÁ÷Ë®
+#define SP_CMD_HEARTBEAT 0x24 //ÐÄÌø
+#define SP_CMD_CARD_AUTHENTICATION 0x26 //¿¨ÔÚÏßÈÏÖ¤
+#define SP_CMD_LOGIN 0x2C //怬
+#define SP_CMD_FACTORY_LINK_TEST 0x2E //¹¤³§Á´Â·²âÊÔ
+#define SP_CMD_SHORTURL 0x28 //»ñÈ¡¶þάÂë¶ÌµØÖ·
+#define SP_CMD_QRCODE_PAY_QUERY 0x2A //¶þάÂëÏû·ÑÈ·ÈÏ
+
+#define IS_PUSH_FLOW(cmd) (0x1&(cmd))
+
+#pragma pack(push)
+#pragma pack(1)
+
+typedef struct
+{
+ uint16 datalen;
+ uint8 command;
+ uint8 excmd; // ÇëÇóÃüÁîÒªÇóżÊý
+ uint8 flag;
+ uint8 data[256];
+} sp_protocol_request_t;
+
+typedef struct
+{
+ uint16 datalen;
+ uint8 command;
+ uint8 excmd; // ÇëÇóÃüÁîÒªÇóżÊý
+ uint8 flag;
+ uint8 retcode;
+ uint8 data[256];
+} sp_protocol_response_t;
+
+#pragma pack(pop)
+
+typedef uint8(* protocol_cmd_func_t)(sp_protocol_response_t* resp, sp_pos_t* pos);
+
+typedef struct
+{
+ uint8 cmd;
+ protocol_cmd_func_t func;
+} protocol_cmd_t;
+
+void sp_communicate(sp_pos_t* pos);
+uint16 sp_card_authentication(sp_pos_t* pos, sp_card_t* card);
+uint16 sp_async_equipment_login(sp_pos_t* pos);
+uint16 sp_async_heartbeat(sp_pos_t* pos);
+uint16 sp_async_upload_transdtl(sp_pos_t* pos, sp_transdtl_t* dtl);
+uint16 sp_qrcode_init(sp_pos_t* pos, sp_card_t* card);
+uint16 sp_qrcode_query(sp_pos_t* pos, sp_card_t* card);
+
+//ͨѶ
+uint8 sp_comm_call(sp_pos_t* pos, sp_protocol_request_t* req,
+ sp_protocol_response_t* resp, int32 timeout_ms);
+void sp_protocol_req_init(sp_protocol_request_t* req, uint8 command);
+#endif
+
diff --git a/supwisdom/sp_config.h b/supwisdom/sp_config.h
new file mode 100644
index 0000000..81f4140
--- /dev/null
+++ b/supwisdom/sp_config.h
@@ -0,0 +1,280 @@
+#ifndef _SP_CONFIG_H
+#define _SP_CONFIG_H
+
+#include "sp_version.h"
+#include "../nec_hardware.h"
+
+#ifndef int8
+#define int8 signed char
+#endif
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+#ifndef int16
+#define int16 signed short
+#endif
+
+#ifndef uint16
+#define uint16 unsigned short
+#endif
+
+#ifndef int32
+#define int32 signed int
+#endif
+
+#ifndef uint32
+#define uint32 unsigned int
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define DEV_TYPE "G401302"
+#define DEV_OFFLINE_DEFAULT_HOUR 168
+#define DEV_BLKBITMAP_DONE 1984
+#define DEV_MAX_DEVICENO 99
+
+#define PRO_VERSION GIT_VERSION
+#define BUILD_DATE __DATE__ // " " __TIME__
+#ifdef FLOWSENSOR
+#define PURCHASE_FLOWSENSOR 1
+#else
+#define PURCHASE_FLOWSENSOR 0
+#endif
+
+enum
+{
+ SP_KEY_NONE = 0xFF,
+ SP_KEY_0 = 0,
+ SP_KEY_1 = 1,
+ SP_KEY_2 = 2,
+ SP_KEY_3 = 3,
+ SP_KEY_4 = 4,
+ SP_KEY_5 = 5,
+ SP_KEY_6 = 6,
+ SP_KEY_7 = 7,
+ SP_KEY_8 = 8,
+ SP_KEY_9 = 9,
+ SP_KEY_ENTER = 12,
+ SP_KEY_CLEAR = 11
+};
+
+typedef enum
+{
+ PAYMODE_INIT = 0,
+ PAYMODE_CARD = 1,
+ PAYMODE_QRCODE = 2,
+} sp_paymode_e;
+
+#pragma pack(push)
+#pragma pack(1)
+
+typedef struct
+{
+ uint8 command;
+ uint32 sendtime;
+} sp_comm_status_t;
+
+typedef struct
+{
+ uint32 last_heartbeat_ticker;
+ uint8 hwVer[16]; //É豸°æ±¾ºÅ
+ uint8 offlineRecordCount; //δÉÏ´«Á÷Ë®ÊýÁ¿
+ uint8 workMode; //µ±Ç°×´Ì¬£¬0-¿ÕÏУ¬1-ÕýÔÚʹÓã¬9-ÒÉËÆ¹ÊÕÏ
+ uint8 heart_status; //ÐÄÌø×´Ì¬£¬0-³õʼ»¯£¬1-·¢ËÍ£¬2-½ÓÊÕ
+} sp_heartbeat_t;
+
+typedef struct
+{
+ uint32 last_login_ticker;
+ uint8 login_flag; //0-δǩµ½£¬1-ÒÑÇ©µ½£¬2-×¢Ïú
+ uint8 hwVer[16]; //É豸°æ±¾ºÅ
+ uint8 deviceKey; //É豸¹¤×÷ÃÜÔ¿
+} sp_login_t;
+
+//Ïû·ÑÁ÷Ë®ÐÅÏ¢½á¹¹
+typedef struct
+{
+ uint8 devphyid[4]; //É豸±àºÅ
+ uint8 transdate[3]; //YYDDMM¸ñʽÈÕÆÚ
+ uint8 transtime[3];
+ uint8 billno[10]; //½»Ò×¶©µ¥±àºÅ
+ uint8 cardphyid[4]; //¿¨ÎïÀíid
+ uint8 transway; //½»Ò×·½Ê½£¬0-³õʼ£¬1-Ë¢¿¨£¬2-ɨÂë
+ uint8 amount; //ʵ¼ÊÖ§¸¶½ð¶î
+ uint8 paidAmount; //ÒÑÖ§¸¶½ð¶î£¬µ±ÊÇÏȿ۷ÑģʽÏ£¬¼Ç¼ÒÑÖ§¸¶µÄ½ð¶î
+ uint8 flowsensors; //ʵ¼ÊʹÓüÆÁ¿£¨µ¥Î»£º°ÙºÁÉý£©
+ uint8 transtatus; //Á÷ˮ״̬£¬0-³õʼ£¬1-³É¹¦£¬2-ʧ°Ü
+ uint8 reverse[1]; //ռλ·û
+ uint8 crc[2]; //len=32
+} sp_transdtl_t;
+
+typedef struct
+{
+ uint8 offline_work_hour; //ÔÊÐíÍÑ»ú¹¤×÷×î´óСʱ 0 ~ 168 Сʱ£¬0 ±íʾ²»ÏÞÖÆ
+ uint8 deviceno; //»úºÅ
+ uint8 devphyid[4]; //ÎïÀíID
+ uint8 flowsensor_unit; // 100ml¶ÔÓ¦Âö³åÊý
+ uint8 unused[54];
+ uint8 login_flag; //0-δǩµ½£¬1-ÒÑÇ©µ½£¬2-ÒÑ×¢Ïú
+ uint8 crc[2];
+} sp_config_t;
+
+typedef struct
+{
+ uint32 transaddr; //µØÖ·
+ uint16 this_offset; //Ò³Æ«ÒÆÎ»
+ uint8 crc[2]; //len=8
+} sp_last_transdtl_t;
+
+typedef struct
+{
+ uint32 transaddr; //µØÖ·
+ uint16 this_offset; //Ò³Æ«ÒÆÎ»
+ uint8 crc[2]; //len=8
+} sp_unconfirm_transdtl_t;
+
+//Ïû·ÑÐÅÏ¢
+typedef struct
+{
+ uint32 free_used_num; //ÒÑÃâ·ÑʹÓüÆÁ¿(µ¥Î»:100ml)
+
+ uint8 starttime[6]; //Ë¢¿¨Ê±¼ä
+ /*Ïȿۿîºó³öË®*/
+ uint16 prepaid_num; //µ¥´Î¿ÉÓüÆÁ¿(µ¥Î»:100ml)
+ uint16 prepaid_amt; //µ¥´ÎÔ¤¸¶½ðÇ®
+
+ uint16 paid_num; //ÀۼƿÉÓüÆÁ¿(µ¥Î»:100ml)
+ uint16 paid_sum; //ÀÛ¼ÆÖ§¸¶½ð¶î
+ uint16 used_num; //ÒÑʹÓüÆÁ¿(µ¥Î»:100ml)
+} sp_purchase_t;
+
+//¶þάÂëÐÅÏ¢
+typedef struct
+{
+ char qrcode_url[32]; ///¶þάÂë¶ÌÂë
+ uint32 starttime; //¶þάÂ뿪ʼʱ¼ä
+ uint32 nowtime; //¶þάÂ뵱ǰʱ¼ä
+ uint32 validtime; //¶þάÂëÓÐЧʱ¼ä
+ uint8 authstatus; //Óû§È·ÈÏ״̬£¨0-δȷÈÏ£¬1-ÒÑÈ·ÈÏ£©
+ uint8 paystatus; //Ö§¸¶×´Ì¬£¨0-´ýÖ§¸¶£¬ 1-ÒÑÖ§¸¶£¬ 2-´ú¿Û£¬3 - ¹Ø±Õ£©
+ uint8 paidAmount; //µ±¶©µ¥ÊÇÒÑÖ§¸¶×´Ì¬£¬·µ»ØÖ§¸¶³É¹¦½ð¶î £¬ ·ñÔòÊÇ 0
+} sp_qrcode_t;
+
+//É豸²ÎÊý
+typedef struct
+{
+ uint8 dev_offline_maxhour; //É豸ÍÑ»ú×î´ó¹¤×÷ʱ¼ä(Сʱ),0-²»ÏÞÖÆ,168-ĬÈÏʱ¼ä
+ uint8 flowsensor_unit; //100ml¶ÔÓ¦Âö³åÊý
+ uint8 hwVer[16]; //É豸°æ±¾ºÅ
+ uint8 deviceKey[8]; //É豸¹¤×÷ÃØÔ¿
+ uint8 work_mode; //É豸¹¤×÷״̬
+} sp_sysconf_t;
+
+
+typedef struct
+{
+ uint8 tag_type;
+ uint8 cur_state;
+ uint8 snr[8];
+ uint32 firsttick; //Ê״ζÁ¿¨Ê±¼ä
+ uint32 lasttick; //×îºó¶Á¿¨Ê±¼ä
+} sp_cardstate_t;
+
+typedef struct
+{
+ uint8 current_state; //µ±Ç°¹¤×÷״̬
+ uint16 errcode;
+ uint32 tick;
+ uint8 last_state; //ÉÏÒ»´Î״̬
+
+ uint8 pause_status; //Óû§Ê¹ÓÃ״̬£¬0--ʹÓÃÖУ¬!0--ÔÝÍ£
+ uint32 pause_tick; //ÔÝͣʱµÄʱ¼ä
+} sp_cardworkstate_t;
+
+//Ë®¿ØÆ÷É豸ÐÅÏ¢
+typedef struct
+{
+ uint8 link_stat; //0--Á´Â·¹¤×÷ÖУ¬1---Á´Â·¿ÉÓÃ
+ uint8 load_para_status; //0--Õý³££¬!0--´íÎó
+ uint8 deviceno;
+ uint8 local_deviceno;
+ uint8 devphyid[4];
+
+ sp_cardstate_t cardState;
+ sp_sysconf_t sysconf;
+ sp_comm_status_t last_comm_status;
+ sp_heartbeat_t heartbeat;
+ sp_login_t devlogin;
+ sp_last_transdtl_t last_transdtl;
+ sp_unconfirm_transdtl_t unconfirm_transdtl;
+
+ sp_paymode_e paymode;
+ sp_purchase_t purchase;
+} sp_pos_t;
+
+//·ÑÂÊÐÅÏ¢
+typedef struct
+{
+ uint8 fee_start; //T°ÙºÁÉý¿ªÊ¼;
+ uint8 fee_unit; //µ¥´Î¿Û·Ñ¿ÉÓÃÁ÷Á¿£¨µ¥Î»:100ml£©
+ uint8 fee_amt; //µ¥´Î¿Û·Ñ½ð¶î£¬ÒÔ·ÖΪµ¥Î»
+} sp_feepara_t;
+
+//¿¨½á¹¹ÐÅÏ¢
+typedef struct
+{
+ uint8 cardphyid[4];
+ uint8 citizen_cardno[12]; //ÊÐÃñºÅ
+ uint8 cardtype;
+ uint8 expiredate[4];
+
+ uint8 waterlimit; //µ¥´Î³öË®ÉÏÏÞ£¨100ml£©
+ uint8 billno[10]; //½»Ò×¶©µ¥±àºÅ,BCDÂë
+ sp_qrcode_t qrcode; //¶þάÂë
+ sp_feepara_t feepara;
+} sp_card_t;
+
+#pragma pack(pop)
+
+typedef enum
+{
+ HEART_INIT = 0,
+ HEART_SEND = 1,
+ HEART_RECV = 2
+} sp_heart_status_t;
+
+typedef enum
+{
+ TAG_TYPE_UNKONWN = 0, //δ֪¿¨ÀàÐÍ
+ TAG_TYPE_M1, //M1¿¨
+ TAG_TYPE_CPU //CPU¿¨
+} sp_cardTag_type;
+
+typedef enum
+{
+ STATE_NONE = 0,
+ STATE_EXIST,
+ STATE_ERROR=0xFF
+} sp_cardState_type;
+
+typedef enum
+{
+ CARDWORKSTATUS_NONE = 0,
+ CARDWORKSTATUS_READY,
+ CARDWORKSTATUS_WORKING,
+ CARDWORKSTATUS_WORKING_WITHOUTCARD,
+ CARDWORKSTATUS_PAUSE,
+ CARDWORKSTATUS_STOPPING,
+ CARDWORKSTATUS_STOPPED,
+ CARDWORKSTATUS_TAKEOFF,
+ CARDWORKSTATUS_WORKERROR,
+ CARDWORKSTATUS_FEECARD_WORKING,
+ CARDWORKSTATUS_SET_DEV,
+ CARDWORKSTATUS_ERROR=0xff
+} sp_cardWorkState_type;
+
+#endif
diff --git a/supwisdom/sp_constant.h b/supwisdom/sp_constant.h
new file mode 100644
index 0000000..3081fc0
--- /dev/null
+++ b/supwisdom/sp_constant.h
@@ -0,0 +1,58 @@
+#ifndef _SP_CONSTANT_H_
+#define _SP_CONSTANT_H_
+
+///////////////////////////////////////////////////////////////////////////////
+#define RC_CPU_FILENOTFOUND 0x6A82
+#define RC_CPU_RECORDNOTFOUND 0x6A83
+#define RC_CPU_NOMAC 0x9406
+
+////////////////////////////////////////////////////////////////////////////////
+#define RC_SUCCESS 0 // ³É¹¦
+#define RC_PSAM_ERR 1 //SAM¸´Î»Ê§°Ü
+#define RC_CARD_LOGIN 2 //ÑéÖ¤ÃÜԿʧ°Ü
+#define RC_CARD_READ 3 //¶Á¿¨Ê§°Ü
+#define RC_CARD_WRITE 4 //д¿¨Ê§°Ü
+#define RC_FLASH_ERR 5 //FLASH´íÎó
+#define RC_HARDWARE_ERR 6 //Ó²¼þ¼ÓÔØ´íÎó
+#define RC_FLASH_NO_RIGHT 7 //·Ç¿Éдflash
+
+#define RC_CARD_NORIGHT 11 //¿¨ÎÞȨÏÞ
+#define RC_CARD_EXPIRED 12 //¹ýÆÚ¿¨
+#define RC_CARD_AUTHENTICATION 13 //¿¨ÈÏ֤ʧ°Ü
+#define RC_CARD_LOST 14 //ºÚÃûµ¥¿¨
+#define RC_CARDNO_EXCEPT 17 //¿¨ºÅÒì³£
+#define RC_CARD_TIMEOUT 18 //ʹÓÃʱ¼äÌ«³¤
+#define RC_CARDBAL_EXCEPT 19 //¿¨Óà¶îÒì³£
+#define RC_CARDBAL_LACK 20 //¿¨Óà¶î²»×ã
+
+#define RC_DEVPHYID_NOTSET 21 //É豸µØÖ·Î´ÉèÖÃ
+#define RC_FEERATE_NOTSET 22 //·ÑÂÊδ³õʼ»¯
+#define RC_DEV_OFFLINE_ERROR 23 // É豸ÍÑ»ú¹¤×÷Ì«³¤
+#define RC_FILE09_CRC_ERR 25 ////¼Ç¼CRC´íÎó
+#define RC_FILE10_CRC_ERR 26 //Ë®¿ØÇ®°üCRC´íÎó
+#define RC_CARD_INVALID 27 //ÎÞЧ¿¨
+#define RC_FEENUM_ERROR 28 //·ÑÂʸöÊý´íÎó
+#define RC_NOTSUPPORT 29 //²»Ö§³Ö
+#define RC_NOT_SAME_CARD 30 //²»Í¬¿¨
+
+#define RC_MODE_NOT_SUPPORT 42 //Ïû·Ñģʽ²»Ö§³Ö
+#define RC_UPDPROG_ERR 43 //Éý¼¶Ê§°Ü
+
+#define RC_CONFPARA_CRC_ERR 55 //ÅäÖòÎÊýcrc´íÎó
+#define RC_TRANSDTL_FULL 58 // Á÷Ë®ÒÑÂú
+#define RC_TRANSDTL_NO_ERR 59 //Á÷Ë®ºÅÒì³£
+#define RC_DEVICENO_OUT 60 // »úºÅ¹ý´ó
+
+#define RC_QRCODE_FAILURE 61 //¶þάÂë»ñȡʧ°Ü
+#define RC_QRCODE_TIMEOUT 62 //¶þάÂ볬ʱ
+#define RC_QRCODE_QUERY_FAIL 63 //¶þάÂëÈÏ֤ʧ°Ü
+
+#define RC_DEV_LOGIN_FAIL 64 //É豸µÇ¼ʧ°Ü
+#define RC_DEV_NOT_LOGIN 65 //É豸δǩµ½
+#define RC_DEV_FAULT 66 //É豸ÒÉËÆ¹ÊÕÏ
+#define RC_DEV_NOSET_FLOWSENSOR_UNIT 67 //É豸Á÷Á¿¼ÆË㵥λδÉèÖÃ
+#define STATUS_KEEPOPEN 1 //³£¿ª¿¨
+#define STATUS_CLOSED 0 //È¡Ïû³£¿ª¿¨
+
+#endif
+
diff --git a/supwisdom/sp_consume.c b/supwisdom/sp_consume.c
new file mode 100644
index 0000000..587e2a4
--- /dev/null
+++ b/supwisdom/sp_consume.c
@@ -0,0 +1,729 @@
+#include "sp_util.h"
+#include "sp_constant.h"
+#include "sp_display.h"
+#include "sp_flash.h"
+#include "sp_card.h"
+#include "sp_des.h"
+#include "sp_msgpack.h"
+#include "sp_menu.h"
+#include "sp_data.h"
+#include "sp_consume.h"
+#include "sp_communicate.h"
+
+static int count = 0;
+static uint16 sp_calc_payamt_by_flowsensor(sp_pos_t* pos, sp_card_t* card)
+{
+ uint32 usedcount = 0;
+
+ if(pos->purchase.paid_num < 1)
+ {
+ //Ê×ÏÈÔ¤¿ÛÒ»±Ê
+ if(card->feepara.fee_start > 0)
+ {
+ //ǰnË®Ãâ·Ñ
+ pos->purchase.prepaid_num = card->feepara.fee_start;
+ pos->purchase.prepaid_amt = 0;
+ }
+ else
+ {
+ pos->purchase.prepaid_num = card->feepara.fee_unit;
+ pos->purchase.prepaid_amt = card->feepara.fee_amt;
+ }
+ pos->purchase.used_num = 0;
+ return 0;
+ }
+ //usedcount = sp_flowsensor_get_count()/pos->sysconf.flowsensor_uint;
+ usedcount = count/pos->sysconf.flowsensor_unit;
+ count++;
+ if(usedcount < pos->purchase.paid_num)
+ {
+ //ûÓдﵽ¿Û·ÑÁ÷Á¿
+ return 0;
+ }
+ pos->purchase.used_num = pos->purchase.paid_num;
+ pos->purchase.prepaid_num = card->feepara.fee_unit;
+ pos->purchase.prepaid_amt = card->feepara.fee_amt;
+ return 0;
+}
+
+//¼ÇÕËģʽÏû·Ñ
+uint16 sp_account_purchase(uint16 amount)
+{
+ return 0;
+}
+
+static uint8 gPICC_SNR[4]; /* ¿¨Æ¬SNºÅ */
+
+void sp_test_card_state(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState, uint32 tick)
+{
+ uint8 ret = 0;
+ sp_card_t cardpcd;
+ switch(pos->cardState.cur_state)
+ {
+ case STATE_NONE:
+ MEMCLEAR(&cardpcd, sizeof(cardpcd));
+ if(sp_card_request(&cardpcd) == 0)
+ {
+ MEMCPY(pos->cardState.snr, cardpcd.cardphyid, sizeof(cardpcd.cardphyid));
+ MEMCPY(gPICC_SNR, cardpcd.cardphyid, sizeof(cardpcd.cardphyid));
+ pos->cardState.tag_type = cardpcd.cardtype;
+ pos->cardState.cur_state = STATE_EXIST;
+ pos->cardState.firsttick = tick;
+ pos->cardState.lasttick = tick;
+ }
+ else
+ {
+ cardWorkState->errcode = RC_CARD_INVALID;
+ }
+ break;
+ case STATE_EXIST:
+ //¼ì²â¿¨ÊÇ·ñ¼ÌÐø´æÔÚ
+ if(pos->cardState.tag_type == TAG_TYPE_CPU)
+ {
+ ret = sp_check_cpu_exist();
+ if(ret)
+ {
+ pos->cardState.cur_state = STATE_NONE;
+ break;
+ }
+ else
+ {
+ memcpy(pos->cardState.snr, gPICC_SNR, 8);
+ pos->cardState.lasttick = tick;
+ }
+ }
+ break;
+ default:
+ pos->cardState.cur_state = STATE_NONE;
+ break;
+ }
+}
+
+static uint16 sp_dev_config_check(const sp_pos_t* pos)
+{
+ uint8 devphyid[4];
+ MEMCLEAR(devphyid, sizeof(devphyid));
+ if(MEMCMP(pos->devphyid, devphyid, sizeof(devphyid)) == 0)
+ {
+ return RC_DEVPHYID_NOTSET;
+ }
+ if(pos->devlogin.login_flag != 1)
+ {
+ return RC_DEV_NOT_LOGIN;
+ }
+ if(pos->sysconf.work_mode == 9)
+ {
+ return RC_DEV_FAULT;
+ }
+ if(pos->sysconf.flowsensor_unit == 0)
+ {
+ return RC_DEV_NOSET_FLOWSENSOR_UNIT;
+ }
+ return 0;
+}
+
+//¶ÁÈ¡µÚÒ»±ÊδÉÏ´«Á÷Ë®Ïû·ÑÈÕÆÚʱ¼ä
+static uint8 sp_read_unconfirm_first_record(uint8 termtime[6])
+{
+ return 1;
+}
+
+static uint16 sp_dev_offline_check(const sp_pos_t* pos)
+{
+ uint8 ret;
+ uint8 record_termtime[6];
+ uint8 ctime[6];
+ int32 nowtime;
+ int32 dtltime;
+
+ if(pos->sysconf.dev_offline_maxhour == 0)
+ {
+ return 0;
+ }
+ memset(record_termtime,0,sizeof(record_termtime));
+ ret = sp_read_unconfirm_first_record(record_termtime);
+ if(ret)
+ {
+ return 0;
+ }
+ sp_get_bcdtime(ctime);
+ nowtime = format_time_covert_secs(ctime);
+ dtltime = format_time_covert_secs(record_termtime);
+
+ /**
+ *Á÷ˮʱ¼ä´óÓÚÉ豸ʱÖÓÇÒ³¬¹ý24Сʱ
+ **/
+ if((dtltime > nowtime) &&
+ ((dtltime - nowtime) > (24*60*DELAY_TIME60s)))
+ {
+ if(sp_valve_state())
+ {
+ sp_valve_off();
+ }
+ return RC_DEV_OFFLINE_ERROR;
+ }
+ /**
+ *Á÷ˮʱ¼äСÓÚÉ豸ʱÖÓÇÒ³¬¹ýãÐÖµ
+ **/
+ if((dtltime < nowtime) &&
+ ((nowtime - dtltime) > (pos->sysconf.dev_offline_maxhour*3600)))
+ {
+ if(sp_valve_state())
+ {
+ sp_valve_off();
+ }
+ return RC_DEV_OFFLINE_ERROR;
+ }
+ 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 = 0;
+ uint8 ctime[6];
+ MEMCLEAR(ctime, sizeof(ctime));
+ sp_get_bcdtime(ctime);
+ if(pos->load_para_status)
+ {
+ return pos->load_para_status;
+ }
+ ret = sp_dev_config_check(pos);
+ if(ret)
+ {
+ return ret;
+ }
+ ret = sp_dev_offline_check(pos);
+ if(ret)
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+static uint16 do_idle(sp_pos_t* pos)
+{
+ uint8 ctime[6];
+ MEMCLEAR(ctime, sizeof(ctime));
+ sp_get_bcdtime(ctime);
+ show_home(pos);
+ return 0;
+}
+
+static uint16 do_new(sp_pos_t* pos, sp_card_t* card)
+{
+ uint16 ret = 0;
+ sp_transdtl_t record;
+ MEMCLEAR(&record, sizeof(record));
+ 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;
+ }
+ ret = sp_card_authentication(pos, card);
+ if(ret)
+ {
+ ret = RC_CARD_AUTHENTICATION;
+ return ret;
+ }
+ if(pos->load_para_status)
+ {
+ return pos->load_para_status;
+ }
+ ret = sp_dev_config_check(pos);
+ if(ret)
+ {
+ return ret;
+ }
+ ret = sp_dev_offline_check(pos);
+ if(ret)
+ {
+ return ret;
+ }
+
+ ret = sp_card_valid_check(card);
+ if(ret)
+ {
+ return ret;
+ }
+ ret = sp_prepare_behalf_transdtl(pos, card, &record);
+ if(ret)
+ {
+ return ret;
+ }
+ pos->sysconf.work_mode = 1;
+ pos->paymode = PAYMODE_CARD;
+ return 0;
+}
+
+static uint16 do_start(sp_pos_t* pos)
+{
+ MEMCLEAR(&pos->purchase,sizeof(sp_purchase_t));
+ sp_flowsensor_count_clear();
+ sp_get_bcdtime(pos->purchase.starttime);
+ sp_valve_on();
+ show_money(pos, pos->purchase.paid_sum);
+ 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)
+ {
+ return ret;
+ }
+ if(pos->purchase.prepaid_amt > 0)
+ {
+ //ĬÈϼÇÕËģʽ
+ ret = sp_account_purchase(pos->purchase.prepaid_amt);
+ if(ret)
+ {
+ return ret;
+ }
+ }
+
+ if(pos->purchase.prepaid_num > 0)
+ {
+ pos->purchase.paid_num += pos->purchase.prepaid_num;
+ pos->purchase.paid_sum += pos->purchase.prepaid_amt;
+ pos->purchase.prepaid_num = 0;
+ pos->purchase.prepaid_amt = 0;
+ }
+ show_money(pos, pos->purchase.paid_sum);
+ return 0;
+}
+
+static uint16 do_stop(sp_pos_t* pos, sp_card_t* card)
+{
+ uint16 ret;
+ sp_transdtl_t record;
+ sp_valve_off();
+
+ if(pos->purchase.paid_num > 0)
+ {
+ MEMCLEAR(&record, sizeof(record));
+ ret = sp_prepare_below_transdtl(pos, card, &record);
+ if(ret)
+ {
+ return ret;
+ }
+ }
+ 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;
+}
+
+static void do_pause(sp_pos_t* pos)
+{
+ char msg[17];
+ MEMCLEAR(msg, sizeof(msg));
+ sp_valve_off();
+ 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);
+ }
+}
+
+static void do_error(sp_pos_t* pos, uint16 errcode)
+{
+ if(errcode)
+ {
+ show_error(pos,"²Ù×÷ʧ°Ü:",errcode);
+ pos->paymode = PAYMODE_INIT;
+ pos->sysconf.work_mode = 0;
+ count = 0;
+ MEMCLEAR(&pos->purchase, sizeof(sp_purchase_t));
+ }
+}
+
+static uint16 sp_card_exist_handle(sp_pos_t* pos, sp_card_t* card,
+ sp_cardworkstate_t* cardWorkState)
+{
+ uint16 ret = 0;
+ uint16 err = 0;
+ sp_card_t cardpcd;
+ switch(cardWorkState->current_state)
+ {
+ case CARDWORKSTATUS_NONE:
+ if(timer_get_ticker() - pos->cardState.firsttick < 1500)
+ {
+ break;
+ }
+ ret = do_new(pos, card);
+ if(ret)
+ {
+ if(0x1018 == ret || 0x2001 == ret||
+ 0x1014 == ret || 0x1030 == ret)
+ {
+ if(0 == sp_card_request(&cardpcd))
+ {
+ break;
+ }
+ }
+ cardWorkState->errcode = ret;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_READY;
+ break;
+ case CARDWORKSTATUS_READY:
+ if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) != 0)
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ }
+ ret = do_start(pos);
+ if(ret)
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_WORKING;
+ break;
+ case CARDWORKSTATUS_PAUSE:
+ cardWorkState->current_state = CARDWORKSTATUS_WORKING;
+ break;
+ case CARDWORKSTATUS_WORKING:
+ if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) != 0)
+ {
+ ret = RC_NOT_SAME_CARD;
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+ break;
+ }
+ cardWorkState->pause_status = 0;
+ ret = do_work(pos, card);
+ if(ret)
+ {
+ show_error(pos,"Ïû·Ñʧ°Ü",ret);
+ err = do_stop(pos, card);
+ if(err != 0)
+ {
+ ret = err;
+ }
+ 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->pause_tick = timer_get_ticker();
+ break;
+ case CARDWORKSTATUS_STOPPING:
+ ret = do_stop(pos, card);
+ if(ret)
+ {
+ cardWorkState->errcode = ret;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPED;
+ break;
+ case CARDWORKSTATUS_STOPPED:
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ case CARDWORKSTATUS_FEECARD_WORKING:
+ if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) != 0)
+ {
+ 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);
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ }
+ cardWorkState->errcode = ret;
+ return ret;
+}
+
+static uint16 sp_card_noexist_handle(sp_pos_t* pos, sp_card_t* card,
+ sp_cardworkstate_t* cardWorkState)
+{
+ //Óп¨µ½ÎÞ¿¨
+ uint16 ret = 0;
+ switch(cardWorkState->current_state)
+ {
+ case CARDWORKSTATUS_NONE:
+ do_idle(pos);
+ break;
+ case CARDWORKSTATUS_READY:
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ case CARDWORKSTATUS_WORKING:
+ cardWorkState->current_state = CARDWORKSTATUS_PAUSE;
+ break;
+ case CARDWORKSTATUS_PAUSE:
+ if(MEMCMP(pos->cardState.snr, card->cardphyid, 4) == 0)
+ {
+ //¿¨ÄÃ×ßÒ»·ÖÖÓÖ®ÄÚĬÈÏÔÝͣʹÓÃ
+ if((timer_get_ticker() - cardWorkState->pause_tick) <= DELAY_TIME60s)
+ {
+ if(!cardWorkState->pause_status)
+ {
+ do_pause(pos);
+ show_home(pos);
+ }
+ show_home(pos);
+ cardWorkState->pause_status = 1;
+ }
+ else
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+ cardWorkState->pause_status = 0;
+ }
+ }
+ else
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+ cardWorkState->pause_status = 0;
+ }
+ cardWorkState->last_state = CARDWORKSTATUS_PAUSE;
+ break;
+ case CARDWORKSTATUS_STOPPING:
+ ret = do_stop(pos, card);
+ if(ret)
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPED;
+ cardWorkState->tick = timer_get_ticker();
+ break;
+ case CARDWORKSTATUS_STOPPED:
+ if(timer_get_ticker() - cardWorkState->tick > DELAY_TIME3s)
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ cardWorkState->last_state = cardWorkState->current_state;
+ cardWorkState->tick = 0;
+ }
+ break;
+ case CARDWORKSTATUS_SET_DEV:
+ if(sp_check_passwd(pos, "É豸¹ÜÀíÃÜÂë", "\x9\x1\x4\x3\x8\x7") == 0)
+ {
+ sp_menu_options(pos);
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ case CARDWORKSTATUS_ERROR:
+ do_error(pos,cardWorkState->errcode);
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ default:
+ Delay_ms(DELAY_TIME200ms);
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ break;
+ }
+ cardWorkState->errcode = ret;
+ return ret;
+}
+
+static sp_card_t CARD;
+void sp_card_handle(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState)
+{
+ if(pos->cardState.cur_state)
+ {
+ sp_card_exist_handle(pos, &CARD, cardWorkState);
+ }
+ else
+ {
+ sp_card_noexist_handle(pos, &CARD, cardWorkState);
+ }
+}
+
+void sp_confirm_paymode(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState)
+{
+ uint8 keycode = SP_KEY_NONE;
+ keycode = sp_get_key();
+ //ÔÚ¿¨Ïû·ÑÔÝÍ£Çé¿öϰ´ÈÎÒâ¼üΪ½áÊøµ±Ç°Ïû·Ñ״̬
+ if(keycode >= SP_KEY_0 && keycode <= SP_KEY_ENTER && pos->cardState.cur_state == STATE_NONE
+ && cardWorkState->current_state == CARDWORKSTATUS_PAUSE && pos->paymode == PAYMODE_CARD)
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+ return;
+ }
+ //Ïû·Ñģʽ³õʼ»¯×´Ì¬Ï°´È·ÈϼüÑ¡Ôñ¶þάÂëÏû·Ñ
+ if((keycode == SP_KEY_ENTER) && (pos->paymode == PAYMODE_INIT))
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ pos->paymode = PAYMODE_QRCODE;
+ return;
+ }
+ //¶þάÂëģʽϰ´È¡Ïû¼üΪֹͣ¹¤×÷
+ if((pos->paymode == PAYMODE_QRCODE) && (keycode == SP_KEY_CLEAR))
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_STOPPING;
+ return;
+ }
+ //°´0¼ü½øÈëÉ豸²Ù×÷½çÃæ
+ if(keycode == SP_KEY_0 && (pos->paymode == PAYMODE_INIT))
+ {
+ cardWorkState->current_state = CARDWORKSTATUS_SET_DEV;
+ return;
+ }
+}
+
+//¶þάÂëÏû·Ñ´¦Àí
+uint32 tick = 0;
+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:
+ ret = sp_check_dev(pos);
+ if(ret)
+ {
+ cardWorkState->errcode = ret;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ ret = sp_qrcode_init(pos, &CARD);
+ if(ret)
+ {
+ cardWorkState->errcode = ret;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ ret = sp_prepare_behalf_transdtl(pos, &CARD, &record);
+ if(ret)
+ {
+ cardWorkState->errcode = RC_QRCODE_TIMEOUT;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ pos->sysconf.work_mode = 1;
+ CARD.qrcode.starttime = sp_get_ticker();
+ disp_hint_info(pos, "ÕýÔÚÉú³É¶þάÂë", DELAY_TIME2s);
+ cardWorkState->last_state = cardWorkState->current_state;
+ cardWorkState->current_state = CARDWORKSTATUS_READY;
+ break;
+ case CARDWORKSTATUS_READY:
+ CARD.qrcode.nowtime = sp_get_ticker();
+ if((CARD.qrcode.nowtime - CARD.qrcode.starttime) > CARD.qrcode.validtime)
+ {
+ show_home(pos);
+ show_home_qrcode(CARD.qrcode.qrcode_url);
+ if(CARD.qrcode.nowtime - tick > DELAY_TIME3s)
+ {
+ 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;
+ }
+ }
+ }
+ else
+ {
+ cardWorkState->errcode = RC_QRCODE_TIMEOUT;
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ }
+ break;
+ case CARDWORKSTATUS_WORKING:
+ ret = do_work(pos, &CARD);
+ if(ret)
+ {
+ show_error(pos,"Ïû·Ñʧ°Ü",ret);
+ ret = do_stop(pos, &CARD);
+ if(ret)
+ {
+ cardWorkState->errcode = ret;
+ }
+ cardWorkState->current_state = CARDWORKSTATUS_ERROR;
+ break;
+ }
+ cardWorkState->last_state = cardWorkState->current_state;
+ cardWorkState->pause_tick = sp_get_ticker();
+ break;
+ case CARDWORKSTATUS_STOPPING:
+ if(cardWorkState->last_state == CARDWORKSTATUS_NONE
+ || cardWorkState->last_state == CARDWORKSTATUS_READY)
+ {
+ disp_hint_info(pos,"È¡ÏûË¢Âë!", DELAY_TIME2s);
+ pos->paymode = PAYMODE_INIT;
+ pos->sysconf.work_mode = 0;
+ }
+ else
+ {
+ if(cardWorkState->last_state != CARDWORKSTATUS_PAUSE)
+ do_pause(pos);
+ 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);
+ cardWorkState->current_state = CARDWORKSTATUS_NONE;
+ cardWorkState->last_state = cardWorkState->current_state;
+ break;
+ default:
+ Delay_ms(DELAY_TIME200ms);
+ break;
+ }
+}
diff --git a/supwisdom/sp_consume.h b/supwisdom/sp_consume.h
new file mode 100644
index 0000000..e6ba62c
--- /dev/null
+++ b/supwisdom/sp_consume.h
@@ -0,0 +1,12 @@
+#ifndef CONSUME_H_
+#define CONSUME_H_
+
+#include "sp_config.h"
+
+void sp_card_handle(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState);
+void sp_test_card_state(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState, uint32 tick);
+void sp_qrcode_handle(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState);
+void sp_confirm_paymode(sp_pos_t* pos, sp_cardworkstate_t* cardWorkState);
+
+#endif
+
diff --git a/supwisdom/sp_data.c b/supwisdom/sp_data.c
new file mode 100644
index 0000000..020b476
--- /dev/null
+++ b/supwisdom/sp_data.c
@@ -0,0 +1,366 @@
+#include "sp_data.h"
+#include "sp_util.h"
+#include "sp_flash.h"
+#include "sp_constant.h"
+#include "sp_display.h"
+
+#define record_behalf_len 25
+#define record_below_len 7
+
+//Ñ»·¼Ç¼ÿһ±ÊÁ÷Ë®¼Ç¼µÄµØÖ·
+static uint16 sp_write_last_record(sp_pos_t* pos)
+{
+ 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)
+ {
+ 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_flash_write(pos->last_transdtl.this_offset+ADDR_LAST_TRANSNO,
+ (uint8*)&pos->last_transdtl, sizeof(buff));
+
+ sp_flash_read(pos->last_transdtl.this_offset+ADDR_LAST_TRANSNO, buff, sizeof(buff));
+ sp_protocol_crc(buff, sizeof(buff)-2, crc);
+ if(MEMCMP(pos->last_transdtl.crc,crc,2)!=0)
+ {
+ pos->load_para_status = RC_FLASH_ERR;
+ return RC_FLASH_ERR;
+ }
+ return 0;
+}
+
+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)
+ {
+ if(pos->last_transdtl.transaddr >= ADDR_TRANSDTL_END)
+ {
+ pos->last_transdtl.transaddr = ADDR_TRANSDTL_BEGIN;
+ }
+ sp_flash_erase(pos->last_transdtl.transaddr);
+ }
+ sp_flash_write(pos->last_transdtl.transaddr, (uint8*)record, sizeof(buf));
+ return 0;
+}
+
+static uint16 sp_write_below_record(sp_pos_t* pos, sp_transdtl_t* record)
+{
+ 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_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));
+ sp_protocol_crc(buff, sizeof(buff)-2, crc);
+ if(MEMCMP(record->crc, crc, 2) != 0)
+ {
+ pos->load_para_status = RC_FLASH_ERR;
+ return RC_FLASH_ERR;
+ }
+ return 0;
+}
+
+//Ïû·Ñ³õʼ»¯ºó´æ´¢Éϰ벿·ÖÁ÷Ë®£¬·ÀÖ¹Ïû·Ñʧ°ÜÎÞÁ÷Ë®ÐÅÏ¢
+uint16 sp_prepare_behalf_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record)
+{
+ uint8 ret = 0;
+ uint8 ctime[6];
+ MEMCLEAR(ctime, sizeof(ctime));
+
+ sp_get_bcdtime(ctime);
+ memcpy(record->devphyid, pos->devphyid, sizeof(pos->devphyid));
+ memcpy(record->transdate, ctime, 3);
+ memcpy(record->transtime, ctime+3, 3);
+ memcpy(record->billno, card->billno, sizeof(card->billno));
+ memcpy(record->cardphyid, card->cardphyid, sizeof(card->cardphyid));
+ if(pos->paymode == PAYMODE_QRCODE)
+ {
+ record->transway = 2;
+ }
+ else
+ {
+ record->transway = 1;
+ }
+ ret = sp_write_behalf_record(pos, record);
+ if(ret)
+ return ret;
+ return sp_write_last_record(pos);
+}
+
+//ÈôÏû·Ñ³É¹¦£¬´æ´¢Ï°벿·ÖÁ÷Ë®ÐÅÏ¢
+uint16 sp_prepare_below_transdtl(sp_pos_t* pos, sp_card_t* card, sp_transdtl_t* record)
+{
+ uint8 buff[record_behalf_len];
+ MEMCLEAR(buff, sizeof(buff));
+
+ record->amount = pos->purchase.paid_sum;
+ if(pos->paymode == PAYMODE_QRCODE)
+ {
+ record->paidAmount = card->qrcode.paidAmount;
+ }
+ else
+ {
+ 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);
+}
+
+//Ñ»·´æ´¢Ã¿Ò»±ÊδÉÏ´«Á÷Ë®¼Ç¼µÄµØÖ·
+uint16 sp_write_unconfirm_record(sp_pos_t* pos)
+{
+ uint8 crc[2];
+ uint8 buff[sizeof(sp_unconfirm_transdtl_t)];
+ MEMCLEAR(buff, sizeof(buff));
+
+ pos->unconfirm_transdtl.this_offset += sizeof(buff);
+ 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,
+ pos->unconfirm_transdtl.crc);
+ sp_flash_write(pos->unconfirm_transdtl.this_offset+ADDR_UNCONFIRM_TRANSNO,
+ (uint8*)&pos->unconfirm_transdtl, sizeof(buff));
+
+ sp_flash_read(pos->unconfirm_transdtl.this_offset+ADDR_UNCONFIRM_TRANSNO, buff,
+ sizeof(buff));
+ sp_protocol_crc(buff, sizeof(buff)-2, crc);
+ if(MEMCMP(pos->unconfirm_transdtl.crc, crc, 2) !=0)
+ {
+ pos->load_para_status = RC_FLASH_ERR;
+ return RC_FLASH_ERR;
+ }
+ return 0;
+}
+
+static uint16 sp_init_last_transdtl_ptr(sp_last_transdtl_t* record)
+{
+ record->transaddr = ADDR_TRANSDTL_BEGIN -sizeof(sp_transdtl_t);
+ record->this_offset = 0;
+ sp_protocol_crc((uint8*)record,sizeof(sp_last_transdtl_t) -2,record->crc);
+ return sp_flash_page_write(ADDR_LAST_TRANSNO,(uint8*)record,sizeof(sp_last_transdtl_t));
+}
+
+static uint16 sp_init_unconfirm_transdtl_ptr(sp_unconfirm_transdtl_t* record)
+{
+ record->transaddr = ADDR_TRANSDTL_BEGIN;
+ record->this_offset = 0;
+ sp_protocol_crc((uint8*)record,sizeof(sp_unconfirm_transdtl_t) -2,record->crc);
+ return sp_flash_page_write(ADDR_UNCONFIRM_TRANSNO,(uint8*)record,
+ sizeof(sp_unconfirm_transdtl_t));
+}
+
+static uint8 sp_load_last_transdtl_ptr(sp_pos_t* pos)
+{
+ uint8 crc[2];
+ sp_flash_page_read(ADDR_LAST_TRANSNO,(uint8*)&pos->last_transdtl,
+ sizeof(sp_last_transdtl_t));
+ sp_protocol_crc((uint8*)&pos->last_transdtl,sizeof(sp_last_transdtl_t) -2,crc);
+ if(MEMCMP(pos->last_transdtl.crc,crc,2) != 0)
+ {
+ sp_init_last_transdtl_ptr(&pos->last_transdtl);
+ }
+ return 0;
+}
+static uint8 sp_load_unconfirm_transdtl_ptr(sp_pos_t* pos)
+{
+ uint8 crc[2];
+ sp_flash_page_read(ADDR_UNCONFIRM_TRANSNO,(uint8*)&pos->unconfirm_transdtl,
+ sizeof(sp_unconfirm_transdtl_t));
+ sp_protocol_crc((uint8*)&pos->unconfirm_transdtl,sizeof(sp_unconfirm_transdtl_t) -2,crc);
+ if(MEMCMP(pos->unconfirm_transdtl.crc,crc,2) != 0)
+ {
+ sp_init_unconfirm_transdtl_ptr(&pos->unconfirm_transdtl);
+ }
+ return 0;
+}
+
+static uint16 sp_parse_config(sp_pos_t* pos, sp_config_t* config)
+{
+ pos->sysconf.dev_offline_maxhour = config->offline_work_hour;
+ if(pos->sysconf.dev_offline_maxhour == 0)
+ {
+ pos->sysconf.dev_offline_maxhour = DEV_OFFLINE_DEFAULT_HOUR;
+ }
+ pos->sysconf.flowsensor_unit = config->flowsensor_unit;
+ pos->deviceno = config->deviceno;
+ pos->devlogin.login_flag = config->login_flag;
+ MEMCPY(pos->devphyid,config->devphyid,4);
+ return 0;
+}
+static uint16 sp_read_config(sp_pos_t* pos, sp_config_t* config)
+{
+ uint8 crc[2];
+ sp_flash_read(ADDR_CONFIG_PARA,(uint8*)config,sizeof(sp_config_t));
+ sp_protocol_crc((uint8*)config,sizeof(sp_config_t) -2,crc);
+ if(memcmp(config->crc,crc,2) != 0)
+ {
+ return RC_CONFPARA_CRC_ERR;
+ }
+ sp_parse_config(pos, config);
+ return 0;
+}
+
+uint16 sp_clear_transdtl(sp_pos_t* pos)
+{
+ uint32 i;
+ uint16 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)
+ {
+ ret |= sp_flash_erase(i);
+ }
+ return ret;
+}
+
+static uint16 sp_init_device(sp_pos_t* pos)
+{
+ uint16 ret;
+ disp_hint_info_two(pos,"É豸³õʼ»¯","Çå¿ÕÁ÷Ë®",0);
+ ret |= sp_clear_transdtl(pos);
+ return ret;
+}
+
+void sp_reset_factory(sp_pos_t* pos)
+{
+ uint16 ret;
+ disp_hint_info_two(pos,"»Ö¸´³ö³§ÖÐ","ÇëÉÔµÈ...",0);
+ ret = sp_flash_erase(ADDR_CONFIG_PARA);
+ ret |=sp_clear_transdtl(pos);
+ if(!ret)
+ {
+ disp_hint_info_two(pos,"³õʼ»¯³É¹¦","µÈ´ýÖØÆô",0);
+ }
+ else
+ {
+ disp_hint_info_two(pos,"³õʼ»¯Ê§°Ü","µÈ´ýÖØÆô",0);
+ }
+ sp_reset();
+}
+
+uint16 sp_load_config(sp_pos_t* pos)
+{
+ uint16 ret;
+ sp_config_t config;
+ MEMCLEAR(&config,sizeof config);
+ ret |= sp_read_config(pos, &config);
+ if(ret)
+ {
+ sp_config_init(pos);
+ sp_init_device(pos);
+ }
+ ret |= sp_load_last_transdtl_ptr(pos);
+ ret |= sp_load_unconfirm_transdtl_ptr(pos);
+ return ret;
+}
+
+uint16 sp_save_config(sp_pos_t* pos, sp_config_t* config)
+{
+ uint8 buffer[sizeof(sp_config_t)];
+ uint8 crc[2];
+ 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));
+ sp_flash_read(ADDR_CONFIG_PARA,buffer,sizeof buffer);
+ sp_protocol_crc(buffer,sizeof(buffer)-2,crc);
+ if(memcmp(config->crc,crc,2) != 0)
+ {
+ return RC_CONFPARA_CRC_ERR;
+ }
+ sp_parse_config(pos, config);
+ return 0;
+}
+
+uint16 sp_save_deviceno(sp_pos_t* pos, uint8 deviceno)
+{
+ uint16 ret;
+ sp_config_t config;
+ MEMCLEAR(&config, sizeof config);
+ ret = sp_read_config(pos, &config);
+ if(ret)
+ {
+ return ret;
+ }
+ config.deviceno = deviceno;
+ return sp_save_config(pos, &config);
+}
+uint16 sp_save_devphyid(sp_pos_t* pos, uint8 devphyid[4])
+{
+ uint16 ret;
+ sp_config_t config;
+ MEMCLEAR(&config, sizeof config);
+ ret = sp_read_config(pos, &config);
+ if(ret)
+ {
+ return ret;
+ }
+ MEMCPY(config.devphyid,devphyid,4);
+ return sp_save_config(pos, &config);
+}
+uint16 sp_save_login_info(sp_pos_t* pos, uint8 flag, uint8 unit, uint8 offline_maxhour)
+{
+ uint16 ret;
+ sp_config_t config;
+ MEMCLEAR(&config, sizeof config);
+ ret = sp_read_config(pos, &config);
+ if(ret)
+ {
+ return ret;
+ }
+ config.login_flag = flag;
+ config.flowsensor_unit = unit;
+ config.offline_work_hour = offline_maxhour;
+ return sp_save_config(pos, &config);
+}
+
+uint16 sp_save_heartbeat_info(sp_pos_t* pos, uint8 flag)
+{
+ uint16 ret;
+ sp_config_t config;
+ MEMCLEAR(&config, sizeof config);
+ ret = sp_read_config(pos, &config);
+ if(ret)
+ {
+ return ret;
+ }
+ config.login_flag = flag;
+ return sp_save_config(pos, &config);
+
+}
+
+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(pos,"É豸²ÎÊý³õʼ»¯", DELAY_TIME2s);
+ 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));
+ sp_flash_read(ADDR_CONFIG_PARA,(uint8*)&config,sizeof(config));
+ sp_protocol_crc((uint8*)&config,sizeof(sp_config_t)-2,crc);
+ if(memcmp(config.crc,crc,2) != 0)
+ {
+ return RC_CONFPARA_CRC_ERR;
+ }
+ ret = sp_flash_erase(ADDR_CONFIG_PARA);
+ return ret;
+}
diff --git a/supwisdom/sp_data.h b/supwisdom/sp_data.h
new file mode 100644
index 0000000..1ed4942
--- /dev/null
+++ b/supwisdom/sp_data.h
@@ -0,0 +1,30 @@
+#ifndef _SP_DATA_H_
+#define _SP_DATA_H_
+
+#include "sp_config.h"
+#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_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);
+uint16 sp_clear_transdtl(sp_pos_t* pos);
+uint16 sp_write_unconfirm_record(sp_pos_t* pos);
+
+//ϵͳ²ÎÊýÉèÖÃ
+void sp_reset_factory(sp_pos_t* pos);
+uint16 sp_load_config(sp_pos_t* pos);
+uint16 sp_save_config(sp_pos_t* pos, sp_config_t* config);
+uint16 sp_save_deviceno(sp_pos_t* pos, uint8 deviceno);
+uint16 sp_save_devphyid(sp_pos_t* pos, uint8 devphyid[4]);
+uint16 sp_config_init(sp_pos_t* pos);
+uint16 sp_save_login_info(sp_pos_t* pos, uint8 flag, uint8 unit, uint8 offline_maxhour);
+uint16 sp_save_heartbeat_info(sp_pos_t* pos, uint8 flag);
+
+//É豸ÊÖ¶¯²Ù×÷½Ó¿Ú
+uint8 sp_confirm_login(sp_protocol_response_t* resp, sp_pos_t* pos);
+
+#endif
+
diff --git a/supwisdom/sp_des.c b/supwisdom/sp_des.c
new file mode 100644
index 0000000..5d19916
--- /dev/null
+++ b/supwisdom/sp_des.c
@@ -0,0 +1,39 @@
+#include "string.h"
+#include "../icc_apdu_lib/des.h"
+
+#include "sp_des.h"
+
+static des_context desctx;
+static des3_context des3ctx;
+
+uint8 single_des_set_keys(uint8 key[8])
+{
+ return des_set_key(&desctx, key);
+}
+
+void single_des_encrypt(uint8 src[8], uint8 dest[8])
+{
+ des_encrypt(&desctx, src, dest);
+}
+
+void single_des_decrypt(uint8 src[8], uint8 dest[8])
+{
+ des_decrypt(&desctx, src, dest);
+}
+
+uint8 triple_des_set_keys(uint8 key[16])
+{
+ return des3_set_2keys(&des3ctx, key, key+8);
+}
+
+void triple_des_encrypt(uint8 src[8], uint8 dest[8])
+{
+ des3_encrypt(&des3ctx, src, dest);
+}
+
+void triple_des_decrypt(uint8 src[8], uint8 dest[8])
+{
+ des3_decrypt(&des3ctx, src, dest);
+}
+
+
diff --git a/supwisdom/sp_des.h b/supwisdom/sp_des.h
new file mode 100644
index 0000000..bc8a7c7
--- /dev/null
+++ b/supwisdom/sp_des.h
@@ -0,0 +1,27 @@
+#ifndef _SP_DES_H_
+#define _SP_DES_H_
+
+#include "../config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint8 single_des_set_keys(uint8 key[8]);
+
+void single_des_encrypt(uint8 src[8], uint8 dest[8]);
+
+void single_des_decrypt(uint8 src[8], uint8 dest[8]);
+
+uint8 triple_des_set_keys(uint8 key[16]);
+
+void triple_des_encrypt(uint8 src[8], uint8 dest[8]);
+
+void triple_des_decrypt(uint8 src[8], uint8 dest[8]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/supwisdom/sp_display.c b/supwisdom/sp_display.c
new file mode 100644
index 0000000..fb0417c
--- /dev/null
+++ b/supwisdom/sp_display.c
@@ -0,0 +1,356 @@
+#include "glcd.h"
+#include "../zk/gb2312_16.h"
+#include "../libqr/qrencode.h"
+#include "sp_util.h"
+#include "sp_constant.h"
+#include "sp_display.h"
+
+#define GLCD_TITLE_X 0
+#define GLCD_TITLE_Y 0
+#define GLCD_TITLE_LINE 8
+#define GLCD_CONTENT_Y_ONE 0x10
+#define GLCD_CONTENT_Y_TWO 0x20
+#define GLCD_CONTENT_Y_THREE 0x30
+#define GLCD_BUTTOM_Y 56
+#define GLCD_LINE_LENGTH 0x10
+
+static char line_buff[17];
+
+/********************************************************************************************************
+* º¯Êý(Name) : void Show_Money(uint32 money)
+* ¹¦ÄÜ(Function) : ÏÔʾ½ð¶î
+* ²ÎÊý(Parameter) : money--¿¨Óà¶î(µ¥Î»:Ôª)
+* ·µ»Ø(Return) : ÎÞ
+**********************************************************************************************************/
+void show_money(sp_pos_t* pos, uint32 money)
+{
+ char msg[32];
+ sprintf(msg," %.02f Ԫ",money/100.0f);
+ disp_hint_info_two(pos,"ÀÛ¼ÆË®·Ñ:",msg,0);
+}
+
+void glcd_tiny_init(void)
+{
+ uint8 retry;
+ glcd_tiny_set_font(Font5x7,5,7,32,127);
+ glcd_clear_buffer();
+ glcd_write();
+ for(retry=0; retry<3; retry++)
+ {
+ if(gb2312_16_verify() == 0)
+ {
+ break;
+ }
+ }
+ glcd_write();
+}
+static void show_title(void)
+{
+ uint8 ctime[7];
+ glcd_tiny_set_font(Font5x7,5,7,32,127);
+ glcd_clear_buffer();
+ sp_get_bcdtime(ctime);
+ sprintf(line_buff, "%02x-%02x-%02x %02x:%02x:%02x",
+ ctime[0],ctime[1],ctime[2],
+ ctime[3],ctime[4],ctime[5]);
+ glcd_draw_string_xy(0, 0, line_buff);
+ glcd_draw_line(0, GLCD_TITLE_LINE, 127, 8, BLACK);
+}
+
+static void show_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)
+{
+ uint8 i,j;
+ if(MEMCMP(qrcode_url,last_qrcode_url,(int)strlen(qrcode_url)) != 0)
+ {
+ sprintf(last_qrcode_url,"%s",qrcode_url);
+ //¶þάÂëÉú³ÉµãÕó
+ QRencode(last_qrcode_url, NULL);
+ }
+ //¶þάÂëµãÕóÏÔʾ
+ for(i=0; i<MAX_MODULESIZE*2; i++)
+ {
+ for(j=0; j<MAX_MODULESIZE*2; j++)
+ {
+ uint8_t pixel = m_byModuleData[i/2][j/2];
+
+ glcd_set_pixel(j+70, 12+i, pixel);
+ glcd_set_pixel(j+70, 12+i+1, pixel);
+ j ++;
+ glcd_set_pixel(j+70, 12+i, pixel);
+ glcd_set_pixel(j+70, 12+i+1, pixel);
+ }
+ i ++;
+ }
+ glcd_write();
+
+}
+static uint8 last_ctime[6];
+void show_home(sp_pos_t* pos)
+{
+ uint8 ctime[6];
+ sp_get_bcdtime(ctime);
+ if(MEMCMP(ctime,last_ctime,6) != 0)
+ {
+ MEMCPY(last_ctime,ctime,6);
+ disp_hint_info_two(pos,"F°æ±¾",PRO_VERSION,0);
+ /*
+ if(pos->sysconf.register_flag)
+ {
+ if(pos->dynamic.ws_client_stat)
+ {
+ show_home_qrcode(pos->dynamic.qrcode_url);
+ }
+ }
+ */
+ }
+}
+
+void show_set_devno(sp_pos_t* pos, uint8 devno)
+{
+ char msg[32];
+ sprintf(msg,"»úºÅ=%d",devno);
+ disp_hint_info_two(pos, "ÉèÖûúºÅ³É¹¦",msg,DELAY_TIME1s);
+}
+void show_set_devphyid(sp_pos_t* pos, uint8 devphyid[4])
+{
+ char msg[32];
+ sprintf(msg,"ID=%02x%02x%02x%02x",
+ devphyid[0],devphyid[1],devphyid[2],devphyid[3]);
+ disp_hint_info_two(pos,"ÉèÖÃÎïÀíID³É¹¦",msg,DELAY_TIME1s);
+}
+void show_set_dev_offline_maxhour(sp_pos_t* pos, uint16 maxhour)
+{
+ char msg[32];
+ sprintf(msg,"ÍÑ»ú¹¤×÷ʱ¼ä=%d",maxhour);
+ disp_hint_info_two(pos, "ÉèÖÃÍÑ»ú¹¤×÷ʱ¼ä³É¹¦",msg,DELAY_TIME1s);
+}
+
+void show_manage_passwd(sp_pos_t* pos, const char* hint,uint8 passwd[],uint8 len)
+{
+ char msg[32];
+ switch(len)
+ {
+ case 0:
+ sprintf(msg,"");
+ break;
+ case 1:
+ sprintf(msg,"%d",passwd[0]);
+ break;
+ case 2:
+ sprintf(msg,"%d%d",passwd[0],passwd[1]);
+ break;
+ case 3:
+ sprintf(msg,"%d%d%d",passwd[0],passwd[1],passwd[2]);
+ break;
+ case 4:
+ sprintf(msg,"%d%d%d%d",passwd[0],passwd[1],passwd[2],passwd[3]);
+ break;
+ case 5:
+ sprintf(msg,"%d%d%d%d%d",passwd[0],passwd[1],passwd[2],passwd[3],passwd[4]);
+ break;
+ case 6:
+ sprintf(msg,"%d%d%d%d%d%d",passwd[0],passwd[1],passwd[2],passwd[3],passwd[4],passwd[5]);
+ break;
+ default:
+ sprintf(msg,"");
+ }
+ disp_hint_info_two(pos,hint,msg,0);
+}
+
+void show_error(sp_pos_t* pos, const char* hint, uint16 errcode)
+{
+ char msg[32];
+ switch(errcode)
+ {
+ case RC_PSAM_ERR:
+ sprintf(msg,"%s", "SAM¸´Î»Ê§°Ü");
+ break;
+ case RC_CARD_LOGIN:
+ sprintf(msg,"%s", "ÑéÖ¤ÃØÔ¿Ê§°Ü");
+ break;
+ case RC_CARD_READ:
+ sprintf(msg,"%s", "¶Á¿¨Ê§°Ü");
+ break;
+ case RC_CARD_WRITE:
+ sprintf(msg,"%s", "д¿¨Ê§°Ü");
+ break;
+ case RC_FLASH_ERR:
+ sprintf(msg,"%s", "FLASHÒì³£");
+ break;
+ case RC_HARDWARE_ERR:
+ sprintf(msg,"%s", "¹Ì¼þÒì³£");
+ break;
+ case RC_FLASH_NO_RIGHT:
+ sprintf(msg,"%s", "FLASHÏÞÖÆ");
+ break;
+ case RC_CARD_NORIGHT:
+ sprintf(msg,"%s", "¿¨ÎÞȨÏÞ");
+ break;
+ case RC_CARD_EXPIRED:
+ sprintf(msg,"%s", "¿¨ÒѹýÆÚ");
+ break;
+ case RC_CARD_LOST:
+ sprintf(msg,"%s", "¿¨ÒÑËø¶¨");
+ break;
+ case RC_CARDNO_EXCEPT:
+ sprintf(msg,"%s", "¿¨Òì³£");
+ break;
+ case RC_CARD_TIMEOUT:
+ sprintf(msg,"%s", "ʹÓÃÌ«¾Ã");
+ break;
+ case RC_CARDBAL_EXCEPT:
+ sprintf(msg,"%s", "Óà¶îÒì³£");
+ break;
+ case RC_CARDBAL_LACK:
+ sprintf(msg,"%s", "ÇëÁª»úÏû·Ñ");
+ break;
+ case RC_DEVPHYID_NOTSET:
+ sprintf(msg,"%s", "δÉèÖûúºÅ");
+ break;
+ case RC_FEERATE_NOTSET:
+ sprintf(msg,"%s", "δÉèÖ÷ÑÂÊ");
+ break;
+ case RC_DEV_OFFLINE_ERROR:
+ sprintf(msg,"%s", "É豸ÍÑ»úÌ«¾Ã");
+ break;
+ case RC_TRANSDTL_FULL:
+ sprintf(msg,"%s", "Á÷Ë®ÒÑÂú");
+ break;
+ case RC_FILE09_CRC_ERR:
+ sprintf(msg,"%s", "09CRC´íÎó");
+ break;
+ case RC_FILE10_CRC_ERR:
+ sprintf(msg,"%s", "10CRC´íÎó");
+ break;
+ case RC_CARD_INVALID:
+ sprintf(msg,"%s", "ÎÞЧ¿¨");
+ break;
+ case RC_FEENUM_ERROR:
+ sprintf(msg,"%s", "·ÑÂʸöÊý´íÎó");
+ break;
+ case RC_NOTSUPPORT:
+ sprintf(msg,"%s", "²»Ö§³Ö");
+ break;
+ case RC_NOT_SAME_CARD:
+ sprintf(msg,"%s", "²»Í¬¿¨");
+ break;
+ case RC_MODE_NOT_SUPPORT:
+ sprintf(msg,"%s", "ģʽ²»Ö§³Ö");
+ break;
+ case RC_UPDPROG_ERR:
+ sprintf(msg,"%s", "Éý¼¶Ê§°Ü");
+ break;
+ case RC_CONFPARA_CRC_ERR:
+ sprintf(msg,"%s", "ÅäÖÃCRC´íÎó");
+ break;
+ case RC_TRANSDTL_NO_ERR:
+ sprintf(msg,"%s", "Á÷Ë®ºÅÒì³£");
+ break;
+ case RC_DEVICENO_OUT:
+ sprintf(msg,"%s", "»úºÅ¹ý´ó");
+ break;
+ case RC_QRCODE_FAILURE:
+ sprintf(msg,"%s", "¶þάÂë»ñȡʧ°Ü");
+ break;
+ case RC_QRCODE_TIMEOUT:
+ sprintf(msg,"%s", "¶þάÂ볬ʱ");
+ break;
+ case RC_QRCODE_QUERY_FAIL:
+ sprintf(msg,"%s", "¶þάÂëÈÏ֤ʧ°Ü");
+ break;
+ case RC_DEV_NOT_LOGIN:
+ sprintf(msg,"%s", "É豸δǩµ½");
+ break;
+ case RC_DEV_FAULT:
+ sprintf(msg,"%s", "É豸ÒÉËÆ¹ÊÕÏ");
+ break;
+ case RC_DEV_NOSET_FLOWSENSOR_UNIT:
+ sprintf(msg,"%s", "Á÷Á¿¼ÆË㵥λδÉèÖÃ");
+ break;
+ case RC_CARD_AUTHENTICATION:
+ 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)
+{
+ show_title();
+ show_bottom(pos);
+
+ snprintf(line_buff,sizeof line_buff,"%s ",msg1);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_ONE, line_buff);
+ snprintf(line_buff,sizeof line_buff,"%s ",msg2);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_TWO, line_buff);
+ snprintf(line_buff,sizeof line_buff,"%s ",msg3);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_THREE, line_buff);
+
+ glcd_write();
+ if(ms > 0)
+ {
+ Delay_ms(ms);
+ }
+}
+
+void disp_hint_info_two(sp_pos_t* pos,const char* msg1,const char* msg2,uint32 ms)
+{
+ show_title();
+ show_bottom(pos);
+
+ snprintf(line_buff,sizeof line_buff,"%s ",msg1);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_ONE, line_buff);
+ snprintf(line_buff,sizeof line_buff,"%s ",msg2);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_TWO, line_buff);
+
+ glcd_write();
+ if(ms > 0)
+ {
+ Delay_ms(ms);
+ }
+}
+void disp_hint_info(sp_pos_t* pos,const char* msg1,uint32 ms)
+{
+ show_title();
+ show_bottom(pos);
+
+ snprintf(line_buff,sizeof line_buff,"%s ",msg1);
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_ONE, line_buff);
+ snprintf(line_buff,sizeof line_buff," ");
+ gb2312_16_draw_str(0, GLCD_CONTENT_Y_TWO, line_buff);
+
+ glcd_write();
+ if(ms > 0)
+ {
+ Delay_ms(ms);
+ }
+}
+void disp_server_errmsg(sp_pos_t* pos,const char* hint,uint8 data[],uint16 len)
+{
+ uint8 strlen;
+ char errmsg[64];
+ strlen = data[0];
+ //command+canid+excmd+flag+retcode+len+crc
+ if((strlen +8) != len)
+ {
+ disp_hint_info_two(pos,hint,"ÇëÇó³¬Ê±",DELAY_TIME3s);
+ return;
+ }
+ if(strlen > 32)
+ {
+ strlen = 32;
+ }
+ snprintf(errmsg,strlen+1,"%s",data +1);
+ disp_hint_info_two(pos,hint,errmsg,DELAY_TIME3s);
+}
+
diff --git a/supwisdom/sp_display.h b/supwisdom/sp_display.h
new file mode 100644
index 0000000..3160248
--- /dev/null
+++ b/supwisdom/sp_display.h
@@ -0,0 +1,36 @@
+#ifndef _SP_DISPLAY_H_
+#define _SP_DISPLAY_H_
+
+#include "sp_config.h"
+
+/*******************************************************************************************************
+* º¯Êý(Name) : void Show_Error(uint32 errcode)
+* ¹¦ÄÜ(Function) : ÏÔʾ´íÎó´úÂë
+* ²ÎÊý(Parameter) : errcode -- ´íÎó´úºÅ
+* ·µ»Ø(Return) : ÎÞ
+********************************************************************************************************/
+void glcd_tiny_init(void);
+
+/*******************************************************************************************************
+* º¯Êý(Name) : void Show_Pass(void)
+* ¹¦ÄÜ(Function) : ÏÔʾPASS
+* ²ÎÊý(Parameter) : NULL
+* ·µ»Ø(Return) : ÎÞ
+********************************************************************************************************/
+ void show_set_devno(sp_pos_t* pos, uint8 devno);
+ void show_set_devphyid(sp_pos_t* pos, uint8 devphyid[4]);
+ void show_set_dev_offline_maxhour(sp_pos_t* pos, uint16 maxhour);
+ void show_error(sp_pos_t* pos, const char* hint,uint16 code);
+ 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 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);
+ void disp_hint_info_three(sp_pos_t* pos, const char* msg1,const char* msg2,
+ const char* msg3,uint32 ms);
+ void disp_server_errmsg(sp_pos_t* pos, const char* hint,uint8 data[],uint16 len);
+
+
+#endif
diff --git a/supwisdom/sp_flash.c b/supwisdom/sp_flash.c
new file mode 100644
index 0000000..0788aed
--- /dev/null
+++ b/supwisdom/sp_flash.c
@@ -0,0 +1,123 @@
+#include "sp_constant.h"
+#include "sp_util.h"
+
+#include "sp_flash.h"
+
+uint16 sp_flash_read(uint32 addr,uint8 buf[],uint32 len)
+{
+ return HW_Flash_Read(addr,len,buf);
+}
+uint16 sp_flash_write(uint32 addr,uint8 buf[],uint32 len)
+{
+ if(addr < DEF_IAP_BASE_ADDR)
+ {
+ return RC_FLASH_NO_RIGHT;
+ }
+ return HW_Flash_NotEraseWrite(addr,len,buf);
+}
+uint16 sp_flash_erase(uint32 addr)
+{
+ if(addr < DEF_IAP_BASE_ADDR)
+ {
+ return RC_FLASH_NO_RIGHT;
+ }
+ return HW_Flash_PageErase(addr / FLASH_PAGE_SIZE);
+}
+
+/**
+**¶ÁȡһҳÊý¾Ý,È«FF±íʾÎÞÊý¾Ý
+**@param len > 128 error
+**@return ·µ»Ø0±íʾ²éÕÒÊý¾Ý³É¹¦
+**@return ·µ»Ø·Ç0±íʾÎÞÓÐЧÊý¾Ý
+**/
+uint16 sp_flash_page_read(uint32 addr,uint8 buf[],uint32 len)
+{
+ uint32 i;
+ uint32 offset = 0;
+ uint8 temp[128];
+
+ if(len > sizeof(temp))
+ {
+ return 1;
+ }
+
+ while(1)
+ {
+ i = 0;
+ sp_flash_read(addr +offset,temp, len);
+ while(i < len)
+ {
+ if(0xFF == temp[i])
+ {
+ ++i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(len == i)
+ {
+ if(0 == offset)
+ {
+ //ÎÞÊý¾Ý
+ return 1;
+ }
+ else
+ {
+ sp_flash_read(addr +offset -len,buf, len);
+ return 0;
+ }
+ }
+ offset += len;
+ if(DEF_FLASH_PageSize < (offset +len)) // ³¬¹ýµ±Ò³Î´ÕÒµ½·µ»Ø1
+ {
+ return 1;
+ }
+ }
+}
+/**
+**дһҳÊý¾Ý
+**@param len > 32 error
+**@return ·µ»Ø0±íʾ¼Ç¼Êý¾Ý³É¹¦
+**@return ·µ»Ø·Ç0±íʾдFLASHʧ°Ü
+**/
+uint16 sp_flash_page_write(uint32 addr,uint8 buf[],uint32 len)
+{
+ uint32 i;
+ uint32 offset = 0;
+ uint8 temp[64];
+
+ if(len > 64)
+ {
+ return 1;
+ }
+ while(1)
+ {
+ i = 0;
+ sp_flash_read(addr +offset,temp, len);
+ while(i < len)
+ {
+ if(0xFF == temp[i])
+ {
+ ++i;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if(DEF_FLASH_PageSize < (offset +len)) // ³¬¹ýµ±Ò³±íʾÒÑдÂú,²Á³ýÖØÐ´
+ {
+ sp_flash_erase(addr);
+ return sp_flash_write(addr,buf, len);
+ }
+ if(len == i)
+ {
+ //ÎÞÊý¾Ý
+ return sp_flash_write(addr +offset,buf, len);
+ }
+ offset += len;
+ }
+}
+
diff --git a/supwisdom/sp_flash.h b/supwisdom/sp_flash.h
new file mode 100644
index 0000000..f01517d
--- /dev/null
+++ b/supwisdom/sp_flash.h
@@ -0,0 +1,63 @@
+#ifndef _SP_FLASH_H_
+#define _SP_FLASH_H_
+
+#include "../sys_hw/Prj_FlashCfg.H"
+#include "sp_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+///////////////////EEPROM ¿Õ¼ä/////////////////////////////
+///////////////////FLASH ¿Õ¼ä////////////////////////////////////////////////////
+
+#if 0
+#define ADDR_FLASH_BEGIN 0x17000 // base addr
+#define ADDR_CONFIG_PARA 0x17000 //ÅäÖòÎÊý
+
+#define ADDR_TRANSDTL_PTR 0x18000 //Á÷ˮָÕë
+#define ADDR_TRANSDTL_BEGIN 0x200000 //Á÷Ë®Æðʼ
+#define ADDR_TRANSDTL_END 0x350000 //Á÷Ë®½áÊø
+#define ADDR_MAX 0x400000
+#endif
+//###############################################################
+/*********Ô¶³ÌÉý¼¶Îļþ´æ´¢100Ò³*********************/
+/*********×¢ÒâÉý¼¶µØÖ·ÓëBOOTÉý¼¶µØÖ·±£³ÖÒ»ÖÂ**/
+#define DEF_IAP_BASE_ADDR (DEF_FLASH_IAP_AppCodeStartAdd)
+#define DEF_IapMarkAddr ( DEF_IAP_BASE_ADDR + 1 * DEF_FLASH_PageSize ) //IAPÉý¼¶±ê¼ÇµØÖ·
+#define DEF_EraMarkAddr ( DEF_IAP_BASE_ADDR + 2 * DEF_FLASH_PageSize ) //²Á³ýFLASH±ê¼Ç
+#define DEF_IapDataAddr ( DEF_IAP_BASE_ADDR + 3 * DEF_FLASH_PageSize ) //IAPÊý¾ÝÇøÆðʼµØÖ·
+
+#define DEF_FLASH_codeStartAdd (DEF_IapDataAddr)
+
+#define ADDR_UPGRADE_UPINFO (ADDR_FLASH_END + DEF_FLASH_PageSize *1)
+#define ADDR_KEY_PARA (ADDR_UPGRADE_UPINFO + DEF_FLASH_PageSize *1)
+
+#define ADDR_UPGRADE_BEGIN (DEF_FLASH_codeStartAdd)
+#define ADDR_UPGRADE_END (DEF_FLASH_IAP_AppCodeEndAdd -DEF_FLASH_PageSize)
+
+#define ADDR_APPLICATION_BASE 0x130000 //base addr
+#define ADDR_APP_VERSION (ADDR_APPLICATION_BASE) //°æ±¾±êʶ
+
+#define ADDR_CONFIG_PARA (ADDR_APP_VERSION +DEF_FLASH_PageSize *1)//ÅäÖòÎÊý
+
+#define ADDR_LAST_TRANSNO (ADDR_CONFIG_PARA +DEF_FLASH_PageSize *10)
+#define ADDR_UNCONFIRM_TRANSNO (ADDR_LAST_TRANSNO +DEF_FLASH_PageSize *1)
+#define ADDR_TRANSDTL_BEGIN (ADDR_UNCONFIRM_TRANSNO +DEF_FLASH_PageSize *1)
+#define ADDR_TRANSDTL_END (ADDR_TRANSDTL_BEGIN +DEF_FLASH_PageSize *100)
+#define ADDR_FLASH_END (ADDR_TRANSDTL_END)
+#define ADDR_MAX 0x400000
+
+//#########################################
+
+uint16 sp_flash_read(uint32 addr,uint8 buf[],uint32 len);
+uint16 sp_flash_write(uint32 addr,uint8 buf[],uint32 len);
+uint16 sp_flash_erase(uint32 addr);
+uint16 sp_flash_page_read(uint32 addr,uint8 buf[],uint32 len);
+uint16 sp_flash_page_write(uint32 addr,uint8 buf[],uint32 len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
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();
+ }
+ }
+}
diff --git a/supwisdom/sp_menu.h b/supwisdom/sp_menu.h
new file mode 100644
index 0000000..75f8f32
--- /dev/null
+++ b/supwisdom/sp_menu.h
@@ -0,0 +1,8 @@
+#ifdef _SP_MENU_H_
+#define _SP_MENU_H_
+
+#include "sp_config.h"
+
+void sp_menu_options(sp_pos_t* pos);
+
+#endif
diff --git a/supwisdom/sp_msgpack.c b/supwisdom/sp_msgpack.c
new file mode 100644
index 0000000..d1258a9
--- /dev/null
+++ b/supwisdom/sp_msgpack.c
@@ -0,0 +1,87 @@
+#include "string.h"
+#include "sp_msgpack.h"
+
+int32 sp_pack_init(cw_pack_context* pack,uint8* buf,uint16 len)
+{
+ memset(buf,0,len);
+ return cw_pack_context_init(pack,buf,len,0);
+}
+
+uint16 sp_pack_length(cw_pack_context* pack)
+{
+ if(pack->current != NULL && pack->start != NULL)
+ {
+ return (pack->current -pack->start);
+ }
+ return 256;
+}
+void sp_pack_put_str(cw_pack_context* pack,const char* parakey,const char* paraval)
+{
+ cw_pack_str(pack,parakey,strlen(parakey));
+ cw_pack_str(pack,paraval,strlen(paraval));
+}
+void sp_pack_put_int(cw_pack_context* pack,const char* parakey,const int paraval)
+{
+ cw_pack_str(pack,parakey,strlen(parakey));
+ cw_pack_signed(pack,paraval);
+}
+void sp_pack_put_bin(cw_pack_context* pack,const char* parakey,const uint8* paraval,
+ const uint16 len)
+{
+ cw_pack_str(pack,parakey,strlen(parakey));
+ cw_pack_bin(pack,paraval,len);
+}
+int32 sp_unpack_init(cw_unpack_context* unpack,uint8* buf,uint16 len)
+{
+ cw_unpack_context_init(unpack,buf,len,0);
+ return unpack->return_code;
+}
+
+uint8 sp_unpack_map_size(cw_unpack_context* unpack)
+{
+ cw_unpack_next(unpack);
+ if(unpack->item.type == CWP_ITEM_MAP)
+ {
+ return (uint8)unpack->item.as.map.size;
+ }
+ return 0;
+}
+
+uint8 sp_unpack_value(cw_unpack_context* unpack,unpack_field_t* field)
+{
+ cw_unpack_next(unpack);
+ if(unpack->item.type == CWP_ITEM_STR)
+ {
+ field->key = unpack->item.as.str.start;
+ cw_unpack_next(unpack);
+ if(unpack->item.type == CWP_ITEM_STR)
+ {
+ field->val.strval = unpack->item.as.str.start;
+ field->strlen = unpack->item.as.str.length;
+ return 0;
+ }
+ else if(unpack->item.type == CWP_ITEM_POSITIVE_INTEGER)
+ {
+ field->val.intval= (int32)unpack->item.as.i64;
+ field->strlen = 0;
+ return 0;
+ }
+ else if(unpack->item.type == CWP_ITEM_BIN)
+ {
+ field->val.binval = unpack->item.as.str.start;
+ field->strlen = unpack->item.as.str.length;
+ return 0;
+ }
+ else
+ {
+ field->strlen = 0;
+ field->val.intval = 0;
+ return 1;
+ }
+ }
+ return 1;
+}
+
+
+
+
diff --git a/supwisdom/sp_msgpack.h b/supwisdom/sp_msgpack.h
new file mode 100644
index 0000000..c07a021
--- /dev/null
+++ b/supwisdom/sp_msgpack.h
@@ -0,0 +1,40 @@
+#ifndef _SP_MSGPACK_H_
+#define _SP_MSGPACK_H_
+
+
+#include "../msgpack/cwpack.h"
+#include "sp_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ const char* key;
+ union
+ {
+ int32 intval;
+ const char* strval;
+ const uint8* binval;
+ } val;
+ int32 strlen;
+} unpack_field_t;
+
+int32 sp_pack_init(cw_pack_context* pack,uint8* buf,uint16 len);
+void sp_pack_put_str(cw_pack_context* pack,const char* parakey,const char* paraval);
+void sp_pack_put_int(cw_pack_context* pack,const char* parakey,const int paraval);
+void sp_pack_put_bin(cw_pack_context* pack,const char* parakey,const uint8* paraval,
+ const uint16 len);
+uint16 sp_pack_length(cw_pack_context* pack);
+
+int32 sp_unpack_init(cw_unpack_context* unpack,uint8* buf,uint16 len);
+uint8 sp_unpack_map_size(cw_unpack_context* unpack);
+uint8 sp_unpack_value(cw_unpack_context* unpack,unpack_field_t* field);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/supwisdom/sp_upgrade.c b/supwisdom/sp_upgrade.c
new file mode 100644
index 0000000..6f2fdb8
--- /dev/null
+++ b/supwisdom/sp_upgrade.c
@@ -0,0 +1,416 @@
+#include "sp_msgpack.h"
+#include "sp_flash.h"
+#include "sp_util.h"
+#include "sp_display.h"
+#include "sp_communicate.h"
+#include "sp_upgrade.h"
+
+extern uint16 crc_table[];
+
+#pragma pack(push)
+#pragma pack(1)
+typedef struct
+{
+ uint32 file_size;
+ uint8 file_crc[2];
+ uint8 file_md5[16];
+} sp_upgrade_info_t;
+#pragma pack(pop)
+
+/*
+**************************************************************************************************************
+* CRC У Ñé
+* Ãè Êö: УÑéÒ»´®charÊý¾ÝµÄCRC
+*
+* Êä Èë: CPU_CHAR *str - ҪУÑéÊý¾ÝµÄÖ¸Õë
+* CPU_INT16U size - ҪУÑéÊý¾ÝµÄ³¤¶È
+* CPU_INT08U mode - УÑéµÄģʽ
+* 1: Ϊ¸Ã´®Êý¾ÝÔö¼ÓCRCУÑé ͬʱ·µ»ØÐ£ÑéµÄCRCÖµ
+* 0: ¸Ã´®Êý¾ÝÊÇ·ñͨ¹ýУÑé ·µ»ØÐ£ÑéµÄCRCÖµ
+* ·µ »Ø:
+*
+* ×¢ Òâ:
+*
+**************************************************************************************************************
+*/
+//CRCʹÓÃ
+typedef struct
+{
+ uint8 L;
+ uint8 H;
+} INT_08BIT_2;
+
+typedef union
+{
+ uint16 Int16Bit;
+ INT_08BIT_2 Int08Bit;
+} INT_16BIT_08BIT;
+
+uint16 AH_CRC_Verify(uint8 str[], uint16 size, uint8 mode)
+{
+ uint32 i;
+ INT_16BIT_08BIT crc;
+ INT_16BIT_08BIT y;
+
+ crc.Int16Bit = 0;
+ for(i = 0 ; i < size ; i++)
+ {
+ y.Int16Bit = crc_table[ str[ i ] ^ crc.Int08Bit.H ];
+ y.Int08Bit.H ^= crc.Int08Bit.L;
+ crc.Int16Bit = y.Int16Bit;
+ }
+ if(mode == 1)
+ {
+ str[ i++ ] = y.Int08Bit.H ;
+ str[ i ] = y.Int08Bit.L ;
+ }
+ return(crc.Int16Bit);
+}
+
+static uint16 update_upgrade_mark(uint32 CheckSum, uint32 size)
+{
+ uint16 ret,i;
+ uint8 buff[18] = { 0x5a,0x4b,0x3c,0x2d,0x1e,0x0f } ;
+
+ //дÉý¼¶Êý¾Ý³É¹¦Ð´ÈëFLASH±ê¼Ç, ºÍУÑéÂë, ÓÐЧ´úÂ볤¶ÈдÈëÊý¾ÝFLASH
+ memcpy(buff+6, (unsigned char*)&(CheckSum), 4) ; //УÑéºÍ
+ memcpy(buff+10,(unsigned char*)&(size) ,4) ; //Êý¾Ý³¤¶È
+ AH_CRC_Verify(buff, 14, 1);
+
+ for(i = 0; i<5; i++)
+ {
+ ret = sp_flash_erase(DEF_IapMarkAddr);
+ if(ret)
+ {
+ continue;
+ }
+ ret = sp_flash_write(DEF_IapMarkAddr, buff, 16);
+ if(!ret)
+ {
+ break;
+ }
+ }
+ if(i >= 5)
+ {
+ return 1;
+ }
+ return 0;
+}
+/**********************************************************************************************
+º¯ÊýÃû³Æ: U32 APP_IapDataSumCheck( U32 staaddr, U32 len, U08 mode )
+º¯Êý×÷ÓÃ: ¶Á³öFLASHÖеÄÊý¾Ý£¬²¢ÐγÉУÑé
+º¯ÊýÊäÈë: staaddr - ¿ªÊ¼µØÖ·
+ len - Êý¾Ý³¤¶È
+ mode - УÑéģʽ 0 È¡·´ºÍУÑé 1 ÆÕͨºÍУÑé
+º¯ÊýÊä³ö: ÎÞ
+º¯Êý·µ»ØÖµ: 0 ³É¹¦ ÆäËûʧ°Ü
+**********************************************************************************************/
+uint32 do_APP_IapDataSumCheck(uint32 staaddr, uint32 len, uint8 mode)
+{
+ uint32 Sum;
+ uint32 app_len, checksize, size;
+ uint16 rcode, i;
+ uint8 buffer[1024];//IAP_MAXLEN
+
+ app_len = len;
+ checksize = 0;
+ Sum = 0;
+ while(checksize < app_len)
+ {
+ if(len < 1024)
+ {
+ size = len;
+ }
+ else
+ {
+ size = 1024;
+ }
+
+ for(i=0; i<5; i++)
+ {
+ rcode = sp_flash_read((staaddr + checksize), buffer, size);
+ if(!rcode)
+ {
+ break;
+ }
+ }
+
+ if(mode == 0)
+ {
+ for(i = 0; i < size; i++)
+ {
+ Sum += ((~buffer[i]) & 0xFF); //еÄÊÇÈ¡·´ºÍ
+ }
+ }
+ else
+ {
+ for(i = 0; i < size; i++)
+ {
+ Sum += buffer[i]; //ÀϵÄÊÇÖ±½ÓºÍ
+ }
+ }
+ checksize += size;
+ len -= size;
+ }
+
+ return (Sum);
+}
+static uint8 get_file_info(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
+{
+ uint8 ret;
+ uint8 size;
+ char temp[32];
+ sp_protocol_request_t req;
+ sp_protocol_response_t resp;
+ cw_pack_context pack;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ sp_flash_read(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
+
+ /*¶ÁÈ¡Îļþ³¤¶ÈºÍCRC*/
+ sp_protocol_req_init(&req,SP_CMD_UPGRADE);
+ sp_pack_init(&pack,req.data,sizeof(req.data));
+ cw_pack_map_size(&pack,5);
+
+ sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
+ sp_pack_put_int(&pack,PK_INT_SEQNO ,0xFFFF);
+ sp_pack_put_str(&pack,PK_STR_DEVTYPE, DEV_TYPE);
+ sp_pack_put_str(&pack,PK_STR_VERSION, PRO_VERSION);
+ sp_pack_put_bin(&pack,PK_BIN_SOFT_MD5,upgradeinfo->file_md5,16);
+
+ req.datalen += sp_pack_length(&pack);
+ ret = sp_comm_call(pos, &req, &resp, COMM_WAIT_TIME);
+ if(!ret)
+ {
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ //erase
+ sp_flash_erase(ADDR_UPGRADE_UPINFO);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ // 4 byte file_length,2 crc
+ if(IS_KEY(PK_INT_FILESIZE,field.key))
+ {
+ upgradeinfo->file_size = (uint32)field.val.intval;
+ }
+ else if(IS_KEY(PK_BIN_FILECRC,field.key))
+ {
+ if(field.strlen != 2)
+ {
+ sprintf(temp,"CRC³¤¶È=%d",field.strlen);
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
+ return 1;
+ }
+ MEMCPY(upgradeinfo->file_crc,field.val.binval,field.strlen);
+ }
+ else if(IS_KEY(PK_BIN_SOFT_MD5,field.key))
+ {
+ MEMCPY(upgradeinfo->file_md5,field.val.binval,field.strlen);
+ }
+ }
+ }
+ else
+ {
+ disp_server_errmsg(pos, "Éý¼¶Ê§°Ü",resp.data,resp.datalen);
+ }
+ return ret;
+}
+static uint8 download_file(sp_pos_t* pos)
+{
+ uint8 ret;
+ uint8 timeout_trycnt = 0;
+ uint8 sameseq_trycnt = 0;
+ uint8 data_len = 0;
+ uint16 seqno = 0;
+ uint16 resp_seqno = 0;
+ uint32 offset = 0;
+ uint8 endflag = 0;
+ uint8 size;
+ char temp[32];
+ uint8 buf[128];
+ sp_protocol_request_t req;
+ sp_protocol_response_t resp;
+ cw_pack_context pack;
+ cw_unpack_context unpack;
+ unpack_field_t field;
+
+ for(offset = ADDR_UPGRADE_BEGIN; offset < ADDR_UPGRADE_END; offset +=DEF_FLASH_PageSize)
+ {
+ sp_flash_erase(offset);
+ }
+ offset = 0;
+ while(1)
+ {
+ sp_feed_dog();
+ sp_protocol_req_init(&req,SP_CMD_UPGRADE);
+ sp_pack_init(&pack,req.data,sizeof(req.data));
+ cw_pack_map_size(&pack,2);
+
+ sp_pack_put_bin(&pack,PK_BIN_DEVPHYID, pos->devphyid, sizeof(pos->devphyid));
+ sp_pack_put_int(&pack,PK_INT_SEQNO,seqno);
+
+ req.datalen += sp_pack_length(&pack);
+ ret = sp_comm_call(pos, &req,&resp, COMM_WAIT_TIME);
+ if(!ret)
+ {
+ timeout_trycnt = 0;//success reset
+ sp_unpack_init(&unpack,resp.data,resp.datalen);
+ size = sp_unpack_map_size(&unpack);
+ while(size-- > 0)
+ {
+ sp_unpack_value(&unpack,&field);
+ if(IS_KEY(PK_INT_SEQNO,field.key))
+ {
+ resp_seqno = (uint32)field.val.intval;
+ }
+ else if(IS_KEY(PK_INT_FLAG,field.key))
+ {
+ if(0 == MEMCMP("end",field.val.strval,field.strlen))
+ {
+ // ÎļþÏÂÔØÍê³É
+ endflag = 1;
+ }
+ }
+ else if(IS_KEY(PK_BIN_FILEDATA,field.key))
+ {
+ data_len = field.strlen;
+ if(data_len > sizeof(buf))
+ {
+ sprintf(temp,"´íÎ󳤶È=%d",data_len);
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü",temp,DELAY_TIME3s);
+ return 1;
+ }
+ MEMCLEAR(buf,sizeof buf);
+ MEMCPY(buf,field.val.binval,data_len);
+ }
+ }
+
+ if(resp_seqno != seqno +1)
+ {
+ if(10 < sameseq_trycnt)
+ {
+ return 1;
+ }
+ ++sameseq_trycnt;
+ continue;
+ }
+ sameseq_trycnt = 0;
+
+ ++seqno;
+ snprintf(temp,sizeof temp,"seqno = %04d",seqno);
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶...",temp,0);
+
+ sp_flash_write(ADDR_UPGRADE_BEGIN+offset,buf,data_len);
+ if(endflag)
+ {
+ return 0;
+ }
+
+ offset += (uint32)data_len;
+ if(ADDR_UPGRADE_BEGIN + offset >= ADDR_UPGRADE_END)
+ {
+ disp_hint_info(pos, "ÏÂÔØÎļþ¹ý´ó",DELAY_TIME3s);
+ return 1;
+ }
+ }
+ else
+ {
+ if(3 < timeout_trycnt)
+ {
+ disp_hint_info(pos, "ÏÂÔØÎļþ³¬Ê±",DELAY_TIME3s);
+ return 1;
+ }
+ Delay_ms(DELAY_TIME1s);
+ ++timeout_trycnt;
+ }
+ }
+}
+static uint8 check_file_and_upgrade(sp_pos_t* pos, sp_upgrade_info_t* upgradeinfo)
+{
+ uint16 ret;
+ uint8 crc[2];
+ uint8 temp_crc[2];
+ uint8 buf[128];
+ uint32 sumcrc;
+
+ uint32 page_index = 0;
+ uint32 page_num = (upgradeinfo->file_size-1)/sizeof(buf) + 1;
+ while(1)
+ {
+ if(page_num == page_index +1)
+ {
+ sp_flash_read(ADDR_UPGRADE_BEGIN +page_index*sizeof(buf),buf,
+ sizeof buf);
+ memcpy(temp_crc,crc,2);
+ if(upgradeinfo->file_size%sizeof(buf) == 0)
+ {
+ sp_protocol_crc_init(buf,sizeof(buf),temp_crc,crc);
+ }
+ else
+ {
+ sp_protocol_crc_init(buf,upgradeinfo->file_size%sizeof(buf),temp_crc,crc);
+ }
+ if(0 == MEMCMP(upgradeinfo->file_crc,crc,2))
+ {
+ sp_flash_write(ADDR_UPGRADE_UPINFO,(uint8*)upgradeinfo,sizeof(sp_upgrade_info_t));
+
+ sumcrc = do_APP_IapDataSumCheck(ADDR_UPGRADE_BEGIN,upgradeinfo->file_size,0);
+ /*Éý¼¶ºó,boot »á²Á³ý¸ÃÒ³¼Ç¼ */
+ //¸üбê־λÖÃλ
+ ret = update_upgrade_mark(sumcrc,upgradeinfo->file_size);
+ if(ret)
+ {
+ disp_hint_info_two(pos, "Éý¼¶Ê§°Ü","¸üбê־ʧ°Ü",DELAY_TIME2s);
+ return 1;
+ }
+ else
+ {
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶","ÇëÎð¶Ïµç",DELAY_TIME2s);
+ sp_reset();
+ return 0;
+ }
+ }
+ else
+ {
+ disp_hint_info(pos, "ÎļþУÑé´íÎó",DELAY_TIME3s);
+ return 1;
+ }
+ }
+ else
+ {
+ sp_flash_read(ADDR_UPGRADE_BEGIN+page_index*sizeof(buf),buf,sizeof buf);
+ if(0 == page_index)
+ {
+ sp_protocol_crc(buf,sizeof buf,crc);
+ }
+ else
+ {
+ memcpy(temp_crc,crc,2);
+ sp_protocol_crc_init(buf,sizeof buf,temp_crc,crc);
+ }
+ ++page_index;
+ }
+ }
+}
+void sp_manual_upgrade(sp_pos_t* pos)
+{
+ uint8 ret;
+ sp_upgrade_info_t upgradeinfo;
+
+ disp_hint_info_two(pos, "ÕýÔÚÉý¼¶..","Îð¶Ïµç!!",0);
+ MEMCLEAR(&upgradeinfo,sizeof upgradeinfo);
+ ret = get_file_info(pos, &upgradeinfo);
+ if(ret)
+ {
+ return;
+ }
+ ret = download_file(pos);
+ if(ret)
+ {
+ return;
+ }
+ check_file_and_upgrade(pos, &upgradeinfo);
+}
+
diff --git a/supwisdom/sp_upgrade.h b/supwisdom/sp_upgrade.h
new file mode 100644
index 0000000..2cd8160
--- /dev/null
+++ b/supwisdom/sp_upgrade.h
@@ -0,0 +1,14 @@
+#ifndef _SP_UPGRADE_H_
+#define _SP_UPGRADE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sp_manual_upgrade(sp_pos_t* pos);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/supwisdom/sp_util.c b/supwisdom/sp_util.c
new file mode 100644
index 0000000..df70b13
--- /dev/null
+++ b/supwisdom/sp_util.c
@@ -0,0 +1,530 @@
+#include "../sys_hw/keypad.h"
+#include "../sys_hw/drv_adc.h"
+#include "sp_display.h"
+
+#include "sp_util.h"
+
+uint16 crc_table[] =
+{
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+
+void sp_protocol_crc(const uint8* buf, uint16 len, uint8 crc[2])
+{
+ //uint16 accnum = 0xc78c;
+ uint8 temp_crc[2];
+ temp_crc[0] = 0xc7;
+ temp_crc[1] = 0x8c;
+ sp_protocol_crc_init(buf,len,temp_crc,crc);
+}
+
+void sp_protocol_crc_init(const uint8* buf, uint16 len,uint8 init[2], uint8 crc[2])
+{
+ uint16 accnum = (uint16)init[0]<<8 |(uint16)init[1];
+ uint16 i;
+ for(i = 0; i < len; ++i)
+ {
+ accnum = (accnum << 8) ^ crc_table[((accnum >> 8)
+ ^ buf[i]) & 0xFF];
+ }
+ crc[0] = (uint8)((accnum >> 8) & 0xFF);
+ crc[1] = (uint8)(accnum & 0xFF);
+}
+
+void sp_key_calibrate(void)
+{
+ calibrate_key(0);
+}
+
+uint8 sp_key_init(void)
+{
+ adc_init();
+ return keypad_init();
+}
+uint8 sp_get_key(void)
+{
+ uint8 key = keypad_get_key();
+ switch(key)
+ {
+ case KEY_NONE:
+ return SP_KEY_NONE;
+ case KEY_DIG0:
+ return SP_KEY_0;
+ case KEY_DIG1:
+ return SP_KEY_1;
+ case KEY_DIG2:
+ return SP_KEY_2;
+ case KEY_DIG3:
+ return SP_KEY_3;
+ case KEY_DIG4:
+ return SP_KEY_4;
+ case KEY_DIG5:
+ return SP_KEY_5;
+ case KEY_DIG6:
+ return SP_KEY_6;
+ case KEY_DIG7:
+ return SP_KEY_7;
+ case KEY_DIG8:
+ return SP_KEY_8;
+ case KEY_DIG9:
+ return SP_KEY_9;
+ case KEY_ENTER:
+ return SP_KEY_ENTER;
+ case KEY_CANCEL:
+ return SP_KEY_CLEAR;
+ default:
+ return SP_KEY_NONE;
+ }
+}
+void sp_reset(void)
+{
+ while(1);
+}
+void sp_bcd_to_str(const uint8* bcd, uint8 bcd_len, char* str)
+{
+ uint8 i;
+ uint16 j;
+ for(i = 0; i < bcd_len; ++i)
+ {
+ j = i << 1;
+ str[j] = ((bcd[i] >> 4) & 0x0F) + 0x30;
+ str[j + 1] = (bcd[i] & 0x0F) + 0x30;
+ }
+ str[i << 1] = 0;
+}
+void sp_str_to_bcd(const char* str, uint8 str_len, uint8* bcd)
+{
+ uint8 i,j;
+ for(i = 0; i < str_len; i += 2)
+ {
+ j = i/2;
+ bcd[j] = (((str[i]-0x30) & 0x0F) <<4) | ((str[i+1]-0x30) & 0x0F);
+ }
+}
+static uint8 charTohex(char ch)
+{
+ if(ch >= '0' && ch <= '9')
+ {
+ return (ch -'0');
+ }
+ if(ch >= 'a' && ch <= 'f')
+ {
+ return (ch -'a' +10);
+ }
+ if(ch >= 'A' && ch <= 'F')
+ {
+ return (ch -'A' +10);
+ }
+ return 0;
+}
+void sp_str_to_hex(const char* str,const uint16 len,uint8* hex)
+{
+ uint8 t,temp;
+ uint16 i;
+ for(i = 0; i < len; i += 2)
+ {
+ temp = charTohex(str[i]);
+ t = temp << 4;
+ temp = charTohex(str[i+1]);
+ t += temp;
+ hex[i/2] = t;
+ }
+}
+
+static char hexToCharTable[]= {"0123456789ABCDEF"};
+void sp_hex_to_str(const uint8* hex,const uint8 len,char* str)
+{
+ uint8 i,j;
+ for(i = 0; i < len; i++)
+ {
+ j = i << 1;
+ str[j] = hexToCharTable[(hex[i] >> 4) &0x0F];
+ str[j +1] = hexToCharTable[hex[i] &0x0F];
+ }
+ str[i << 1] = 0;
+}
+
+void sp_get_bcdtime(uint8 ctime[6])
+{
+ _SystemTime time;
+ memset(&time,0,sizeof time);
+ rtc_get_time(&time); //bcd
+ ctime[0] = time.year;
+ ctime[1] = time.month;
+ ctime[2] = time.day;
+ ctime[3] = time.hour;
+ ctime[4] = time.minute;
+ ctime[5] = time.second;
+}
+void sp_set_bcdtime(uint8 ctime[6])
+{
+ _SystemTime time;
+ memset(&time,0,sizeof time);
+ time.year = ctime[0];
+ time.month = ctime[1];
+ time.day = ctime[2];
+ time.hour = ctime[3];
+ time.minute = ctime[4];
+ time.second = ctime[5];
+
+ rtc_set_time(&time);
+}
+uint8 sp_check_time_valid(uint8 ctime[6])
+{
+ if(BCD2Dec(ctime[0]) < 18)
+ return 1;
+ if(BCD2Dec(ctime[1]) > 12)
+ return 1;
+ if(BCD2Dec(ctime[2]) > 31)
+ return 1;
+ if(BCD2Dec(ctime[3]) > 23)
+ return 1;
+ if(BCD2Dec(ctime[4]) > 59)
+ return 1;
+ if(BCD2Dec(ctime[5]) > 59)
+ return 1;
+
+ return 0;
+}
+uint8 sp_crc_sum(uint8 buf[],uint8 len)
+{
+ uint8 i;
+ uint8 sum = 0;
+ //¼ÆËãУÑéºÍ
+ for(i = 0; i < len; i++)
+ {
+ sum = sum + buf[i];
+ }
+ return sum;
+}
+
+int8 isFF(uint8 buf[],uint16 len)
+{
+ uint16 i;
+ for(i = 0; i < len; i++)
+ {
+ if(0xFF != buf[i])
+ {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+//ms
+uint32 sp_get_ticker(void)
+{
+ return timer_get_ticker();
+}
+
+void Delay_ms(uint32 ms)
+{
+ uint32 t = sp_get_ticker();
+ while(sp_get_ticker() - t < ms);
+}
+void sp_valve_on(void)
+{
+ valve_sta_set(valve_state_on);
+ valve_ctrl();
+}
+void sp_valve_off(void)
+{
+ valve_sta_set(valve_state_off);
+ valve_ctrl();
+}
+uint8 sp_valve_state(void)
+{
+ return valve_sta_get();
+}
+
+int16 get_2byte_int(uint8 value_str[2])
+{
+ int32 r = 0, t = 0;
+ t = value_str[0];
+ r = t << 8;
+ r |= value_str[1];
+ return (int16)r;
+}
+int32 get_3byte_int(uint8 value_str[3])
+{
+ int32 r = 0, t = 0;
+ t = value_str[0];
+ r = t << 16;
+ t = value_str[1];
+ r |= t << 8;
+ r |= value_str[2];
+ return r;
+}
+int32 get_4byte_int(uint8 value_str[4])
+{
+ int32 r = 0, t = 0;
+ t = value_str[0];
+ r = t << 24;
+ t = value_str[1];
+ r |= t << 16;
+ t = value_str[2];
+ r |= t << 8;
+ r |= value_str[3];
+ return r;
+}
+void set_2byte_int(uint8 value_str[2], int num)
+{
+ value_str[0] = (num >> 8) & 0xFF;
+ value_str[1] = num & 0xFF;
+}
+void set_3byte_int(uint8 value_str[3], int num)
+{
+ value_str[0] = (num >> 16) & 0xFF;
+ value_str[1] = (num >> 8) & 0xFF;
+ value_str[2] = num & 0xFF;
+}
+void set_4byte_int(uint8 value_str[4], int num)
+{
+ value_str[0] = (num >> 24) & 0xFF;
+ value_str[1] = (num >> 16) & 0xFF;
+ value_str[2] = (num >> 8) & 0xFF;
+ value_str[3] = num & 0xFF;
+}
+
+//»ñµÃµ¥×Ö½ÚÖÐijһλµÄÖµ
+int32 Get1Bit(uint8 buf, int n)
+{
+ return (buf >> n) & 0x01;
+}
+
+int16 get_2byte_int_le(uint8 value_str[2])
+{
+ int32 r = 0, t = 0;
+ t = value_str[1];
+ r = t << 8;
+ r |= value_str[0];
+ return (int16)r;
+}
+//С×Ö½ÚÐò
+int32 get_3byte_int_le(uint8 value_str[3])
+{
+ int32 r = 0, t = 0;
+ t = value_str[2];
+ r = t << 16;
+ t = value_str[1];
+ r |= t << 8;
+ r |= value_str[0];
+ return r;
+}
+//С×Ö½ÚÐò
+int32 get_4byte_int_le(uint8 value_str[4])
+{
+ int32 r = 0, t = 0;
+ t = value_str[3];
+ r = t << 24;
+ t = value_str[2];
+ r |= t << 16;
+ t = value_str[1];
+ r |= t << 8;
+ r |= value_str[0];
+ return r;
+}
+
+void set_2byte_int_le(uint8 value_str[2], int num)
+{
+ value_str[1] = (num >> 8) & 0xFF;
+ value_str[0] = num & 0xFF;
+}
+
+void set_3byte_int_le(uint8 value_str[3], int num)
+{
+ value_str[2] = (num >> 16) & 0xFF;
+ value_str[1] = (num >> 8) & 0xFF;
+ value_str[0] = num & 0xFF;
+}
+
+/*¼ÆËã´Óbcd starttime µ½ÏÖÔÚµÄÃëÊý*/
+uint32 diff_time(uint8 starttime[6])
+{
+ uint8 ctime[6];
+ uint32 start_second;
+ uint32 end_second;
+
+ sp_get_bcdtime(ctime);
+ start_second = format_time_covert_secs(starttime);
+ end_second = format_time_covert_secs(ctime);
+ if(end_second < start_second)
+ {
+ return 0;
+ }
+ return (end_second - start_second);
+}
+
+void mycpy(void* dest, const void* src, uint32 len)
+{
+ char* tmp_dest = (char*)dest;
+ char* tmp_src = (char*)src;
+ while(len--)
+ {
+ *tmp_dest = *tmp_src++;
+ tmp_dest++;
+ }
+}
+
+void sp_bcd2asc(const uint8 bcdbuf[], uint8 bcdlen, uint8* ascstr)
+{
+ uint8 i;
+ uint8 lch, hch;
+ for(i = 0; i < bcdlen; i++)
+ {
+ hch = (bcdbuf[i] & 0x0F);
+ lch = (bcdbuf[i] & 0xF0);
+ lch = lch >> 4;
+ ascstr[2 * i] = lch + '0';
+ ascstr[2 * i + 1] = hch + '0';
+ }
+ ascstr[2*i] = 0;
+}
+int32 sp_atoi(const char* src)
+{
+ int i = 0;
+ while(*src != 0)
+ {
+ i = i * 10 + *src - '0';
+ src++;
+ }
+ return i;
+}
+/**
+**2000.0.0:0.0.0ʱ¼äΪ»ùÊý
+**/
+static int MINUTE_SECS = 60;
+static int HOUR_SECS = 3600;
+static int DAY_SECS = 24*3600;
+static int YEAR_SECS = 365*24*3600;
+static int FOURYEAR_SECS = (365*3+366)*24*3600;
+static int norMoth[] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+static int leapMoth[] = {0,31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+/*time: string(yyyyMMddHHmmss) to int */
+int format_time_covert_secs(uint8 ctime[6])
+{
+ int secs;
+ int i;
+ int remain;
+ int year = BCD2Dec(ctime[0]);
+ int month = BCD2Dec(ctime[1]);
+ int day = BCD2Dec(ctime[2]);
+ int hour = BCD2Dec(ctime[3]);
+ int minute = BCD2Dec(ctime[4]);
+ int second = BCD2Dec(ctime[5]);
+
+ secs = year/4 *FOURYEAR_SECS;
+ remain = year%4;
+ secs += remain*YEAR_SECS;
+
+ if(remain == 0)
+ {
+ for(i = 0; i < month; ++i)
+ {
+ secs += leapMoth[i] *DAY_SECS;
+ }
+ }
+ else
+ {
+ for(i = 0; i < month; ++i)
+ {
+ secs += norMoth[i] *DAY_SECS;
+ }
+ }
+ secs += day*DAY_SECS;
+ secs += hour *HOUR_SECS;
+ secs += minute*MINUTE_SECS;
+ secs += second;
+ return secs;
+}
+
+uint8 sp_check_passwd(sp_pos_t* pos,const char* hint,uint8 passwd[6])
+{
+ uint8 temp[6];
+ uint8 offset = 0;
+ uint8 kcode;
+ uint32 ticker = sp_get_ticker();
+
+ show_manage_passwd(pos,hint,temp,offset);
+ while(sp_get_ticker() -ticker < DELAY_TIME60s)
+ {
+ sp_feed_dog();
+ kcode = sp_get_key();
+ if(kcode != SP_KEY_NONE)
+ {
+ 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 < 6)
+ {
+ temp[offset++] = (uint8)(kcode-SP_KEY_0);
+ show_manage_passwd(pos,hint,temp,offset);
+ }
+ if(offset >= 6)
+ {
+ if(0 == MEMCMP(temp,passwd,6))
+ {
+ return 0;
+ }
+ else
+ {
+ disp_hint_info_two(pos,hint,"ÃÜÂë´íÎó",DELAY_TIME2s);
+ MEMCLEAR(temp, sizeof temp);
+ offset = 0;
+ }
+ }
+ break;
+ case SP_KEY_CLEAR:
+ if(offset == 0)
+ {
+ return 1;
+ }
+ --offset;
+ temp[offset] = 0;
+ show_manage_passwd(pos,hint,temp,offset);
+ break;
+ }
+ }
+ }
+ return 1;
+}
diff --git a/supwisdom/sp_util.h b/supwisdom/sp_util.h
new file mode 100644
index 0000000..d54b929
--- /dev/null
+++ b/supwisdom/sp_util.h
@@ -0,0 +1,70 @@
+#ifndef _SP_UTIL_H_
+#define _SP_UTIL_H_
+
+#include "string.h"
+#include "stdlib.h"
+#include "stdio.h"
+#include "sp_config.h"
+
+#define DELAY_TIME100ms 100
+#define DELAY_TIME200ms 200
+#define DELAY_TIME1s 1000
+#define DELAY_TIME2s 2000
+#define DELAY_TIME3s 3000
+#define DELAY_TIME15s 15000
+#define DELAY_TIME60s 60000
+#define COMM_WAIT_TIME 5000
+
+#define STR_COPY_N(x,y,z) do{snprintf(x,z+1,"%s",y);}while(0);
+#define MEMCLEAR(x,z) memset(x,0,z)
+#define MEMCMP(x,y,z) memcmp(x,y,z)
+#define MEMCPY(x,y,z) memcpy(x,y,z)
+#define IS_KEY(expect,val) (strncmp(expect,val,strlen(expect)) == 0)
+
+#define Dec2BCD(x) (((x) / 10) * 16 + (x) % 10)
+#define BCD2Dec(x) (((x) / 16) * 10 + (x) % 16)
+
+void sp_get_bcdtime(uint8 ctime[6]);
+void sp_set_bcdtime(uint8 ctime[6]);
+uint8 sp_check_time_valid(uint8 ctime[6]);
+uint8 sp_crc_sum(uint8 buf[],uint8 len);
+uint32 sp_get_ticker(void);
+void Delay_ms(uint32 ms);
+void sp_valve_on(void);
+void sp_valve_off(void);
+uint8 sp_valve_state(void);
+int16 get_2byte_int(uint8 value_str[2]);
+int32 get_3byte_int(uint8 value_str[3]);
+int32 get_4byte_int(uint8 value_str[4]);
+void set_2byte_int(uint8 value_str[2], int num);
+void set_3byte_int(uint8 value_str[3], int num);
+void set_4byte_int(uint8 value_str[4], int num);
+//»ñµÃµ¥×Ö½ÚÖÐijһλµÄÖµ
+int32 Get1Bit(uint8 buf, int n);
+int16 get_2byte_int_le(uint8 value_str[2]);
+//С×Ö½ÚÐò
+int32 get_3byte_int_le(uint8 value_str[3]);
+//С×Ö½ÚÐò
+int32 get_4byte_int_le(uint8 value_str[4]);
+void set_2byte_int_le(uint8 value_str[2], int num);
+void set_3byte_int_le(uint8 value_str[3], int num);
+/*¼ÆËã´Óstarttime µ½ÏÖÔÚµÄÃëÊý*/
+uint32 diff_time(uint8 starttime[6]);
+void mycpy(void* dest, const void* src, uint32 len);
+int32 sp_atoi(const char* src);
+void sp_bcd2asc(const uint8 bcdbuf[], uint8 bcdlen, uint8* ascstr);
+int format_time_covert_secs(uint8 ctime[6]);
+void sp_protocol_crc(const uint8* buf, uint16 len, uint8 crc[2]);
+void sp_protocol_crc_init(const uint8* buf, uint16 len,uint8 init[2], uint8 crc[2]);
+uint8 sp_get_key(void);
+uint8 sp_key_init(void);
+void sp_key_calibrate(void);
+void sp_reset(void);
+void sp_bcd_to_str(const uint8* bcd, uint8 bcd_len, char* str);
+void sp_str_to_bcd(const char* str, uint8 str_len, uint8* bcd);
+void sp_str_to_hex(const char* str,const uint16 len,uint8* hex);
+void sp_hex_to_str(const uint8* hex,const uint8 len,char* str);
+uint8 sp_check_passwd(sp_pos_t* pos,const char* hint,uint8 passwd[6]);
+int8 isFF(uint8 buf[],uint16 len);
+
+#endif