大理水控初始版本
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;
+ }
+}