Memery Card
>w## Notice
> * please include the header file "bwsdk_api.h" when you need to use Memery Card
`#include "bwsdk_api.h"`
>i## data structure
```
#define MEMIC_ZONE_NONE 0xFF ///< No zone indicated(Absolute address used) or card with no mutil zone
/*
* @brief Zone length define of AT88SC101
*/
#define AT88SC101_FZ_LEN 2 ///<
#define AT88SC101_IZ_LEN 8 ///<
#define AT88SC101_SC_LEN 2 ///<
#define AT88SC101_SCAC_LEN 2 ///<
#define AT88SC101_CPZ_LEN 8 ///<
#define AT88SC101_AZ1_LEN 128 ///<
#define AT88SC101_EZ1_LEN 4 ///<
#define AT88SC101_EC_LEN 16 ///<
#define AT88SC101_MTZ_LEN 2 ///<
/*
* @brief Zone length define of AT88SC102
*/
#define AT88SC102_FZ_LEN 2 ///<
#define AT88SC102_IZ_LEN 8 ///<
#define AT88SC102_SC_LEN 2 ///<
#define AT88SC102_SCAC_LEN 2 ///<
#define AT88SC102_CPZ_LEN 8 ///<
#define AT88SC102_AZ1_LEN 64 ///<
#define AT88SC102_EZ1_LEN 6 ///<
#define AT88SC102_AZ2_LEN 64 ///<
#define AT88SC102_EZ2_LEN 4 ///<
#define AT88SC102_EC_LEN 16 ///<
#define AT88SC102_MTZ_LEN 2 ///<
/*
* @brief Zone length define of AT88SC1604
*/
#define AT88SC1604_FZ_LEN 2 ///<
#define AT88SC1604_IZ_LEN 8 ///<
#define AT88SC1604_SC_LEN 2 ///<
#define AT88SC1604_SCAC_LEN 1 ///<
#define AT88SC1604_CPZ_LEN 8 ///<
#define AT88SC1604_SC1_LEN 2 ///<
#define AT88SC1604_S1AC_LEN 1 ///<
#define AT88SC1604_EZ1_LEN 2 ///<
#define AT88SC1604_E1AC_LEN 1 ///<
#define AT88SC1604_AZ1_LEN 1195 ///<
#define AT88SC1604_SC2_LEN 2 ///<
#define AT88SC1604_EZ2_LEN 2 ///<
#define AT88SC1604_E2AC_LEN 1 ///<
#define AT88SC1604_AZ2_LEN 256 ///<
#define AT88SC1604_SC3_LEN 2 ///<
#define AT88SC1604_SC3_LEN 2 ///<
#define AT88SC1604_EZ3_LEN 2 ///<
#define AT88SC1604_E3AC_LEN 1 ///<
#define AT88SC1604_AZ3_LEN 256 ///<
#define AT88SC1604_SC4_LEN 2 ///<
#define AT88SC1604_EZ4_LEN 2 ///<
#define AT88SC1604_E4AC_LEN 1 ///<
#define AT88SC1604_AZ4_LEN 256 ///<
#define AT88SC1604_MTZ_LEN 2 ///<
#define AT88SC1604_SCEZ_LEN 2 ///<
/**
* @brief Zone of AT88SC101. Not support yet.
* @note Refer to AT88SC1014 datasheet
*/
typedef enum {
AT88SC101_FZ = 0, ///< Producer code area, 2Byte
AT88SC101_IZ, ///< Card issuer code area, 8Byte
AT88SC101_SC, ///< card password area , 2Byte
AT88SC101_SCAC, ///< Card password error counting area, 2Byte
AT88SC101_CPZ, ///< code password protection zone, 8Byte
AT88SC101_AZ1, ///< application zone one, 128Byte
AT88SC101_EZ1, ///< are of erase the protect key for application zone one, 4Byte
AT88SC101_EC, ///< area of delete counting, 16Byte
AT88SC101_MTZ, ///< test area, 2Byte
} at88sc101_zone_t;
/**
* @brief Zone of AT88SC102
* @note Refer to AT88SC102 datasheet
*/
typedef enum {
AT88SC102_FZ = 0, ///< Producer code area, 2Byte
AT88SC102_IZ, ///< Card issuer code area, 8Byte
AT88SC102_SC, ///< card password area, 2Byte
AT88SC102_SCAC, ///< Card password error counting area, 2Byte
AT88SC102_CPZ, ///< code password protection zone, 8Byte
AT88SC102_AZ1, ///< application zone one, 64Byte
AT88SC102_EZ1, ///< are of erase the protect key for application zone one, 6Byte
AT88SC102_AZ2, ///< application zone two, 64Byte
AT88SC102_EZ2, ///< are of erase the protect key for application zone two, 4Byte
AT88SC102_EC, ///< area of delete counting for zone two, 16Byte
AT88SC102_MTZ, ///< test area, 2Byte
} at88sc102_zone_t;
/**
* @brief Zone of AT88SC1604
* @note Refer to AT88SC1604 datasheet
*/
typedef enum {
AT88SC1604_FZ = 0, ///< Producer code area, 2B
AT88SC1604_IZ, ///< Card issuer code area, 8B
AT88SC1604_SC, ///< card password area, 2B
AT88SC1604_SCAC, ///< Card password error counting area, 1B
AT88SC1604_CPZ, ///< code password protection zone, 8B
AT88SC1604_SC1, ///< password for zone one, 2B
AT88SC1604_S1AC, ///< password error counting for zone one, 1B
AT88SC1604_EZ1, ///< are of erase the protect key for application zone one, 2B
AT88SC1604_E1AC, ///< counting area for erase the protect key of zone one, 1B
AT88SC1604_AZ1, ///< application zone one
AT88SC1604_SC2, ///< password for application zone two, 2B
AT88SC1604_EZ2, ///< area of erase the protect key for application zone two, 2B
AT88SC1604_E2AC, ///< area of counting which error erase the protect key of zone two, 1B
AT88SC1604_AZ2, ///< application zone two
AT88SC1604_SC3, ///< password for application zone three, 2B
AT88SC1604_EZ3, ///< area of erase the protect key for application zone three, 2B
AT88SC1604_E3AC, ///< area of counting which error erase the protect key of zone three, 1B
AT88SC1604_AZ3, ///< application zone three
AT88SC1604_SC4, ///< password for application zone four, 2B
AT88SC1604_EZ4, ///< area of erase the protect key for application zone four, 2B
AT88SC1604_E4AC, ///< area of counting which error erase the protect key of zone four, 1B
AT88SC1604_AZ4, ///< application zone four
AT88SC1604_MTZ, ///< test area
} at88sc1604_zone_t;
/**
* @brief Security level of AT88SC101, AT88SC102, AT88SC1604
*/
typedef enum {
SEC_LEVEL_1 = 0,
SEC_LEVEL_2,
} sec_level_t;
#define SLE4428_ATR_LEN 4 ///<
#define SLE4428_SM_LEN 3 ///<
#define SLE4428_EC_LEN 1 ///<
#define SLE4428_INIT_EC 8 ///<
#define SLE4428_EC_MASK 0xFF ///<
#define SLE4428_EC_REC 0xFF ///<
#define SLE4428_SC_LEN 2 ///<
#define SLE4428_MM_LEN 1021 ///< EC, PSC1 and PSC2 at 0x03FD~03FF, so not 1024 here
#define SLE4442_ATR_LEN 4 ///<
#define SLE4442_SM_LEN 4 ///<
#define SLE4442_EC_LEN 1 ///<
#define SLE4442_INIT_EC 3 ///<
#define SLE4442_EC_MASK 0x07 ///<
#define SLE4442_EC_REC 0xFF ///<
#define SLE4442_SC_LEN 3 ///<
#define SLE4442_MM_LEN 256 ///<
#define SLE4442_PM_LEN 4 ///<
#define AT88_ATR_LEN 4 ///<
#define AT88_PWD_LEN 3 ///<
#define AT88_PAC_LEN 1 ///<
#define AT88SC1608_CZ_SIZE 128 ///<
#define AT88SC1608_UZ_SIZE 256 ///<
#define AT88SC153_CUZ_SIZE 64 ///<
/**
* @brief Bitmask of operation with or without protect bit
* @warning When read SLE4428 with protect bit, length should be MEMIC_BUF_SIZE/2 maximum.
*/
typedef enum {
SLE4428_FLAG_WITHOUT_PB = (1<<0), ///< operation without protect bit
SLE4428_FLAG_WITH_PB = (1<<1), ///< operation with protect bit
} sle4428_flag_t;
/**
* @brief Zone of SLE4442
*
* Main Memory: 32 bytes Protectable Data Memory(0-31, 32 Bytes), 224 bytes Unprotected Data Memory (32-255, 224Bytes)
*
* Protection Memory: (0-31 bit, totally 4 Bytes)
*
* Security Memory: Error counter(EC, 1 Byte), Protect security code(PSC, 3Bytes)
* EC: Only the least 3 bits use for counter, most 5 bits is always 0.
* PSC: Generally, PSC is FFFFFF default.
*
*/
typedef enum {
SLE4442_MM = 0, ///< Main Memory
SLE4442_PM, ///< Protection Memory
SLE4442_SM, ///< Security Memory
} sle4442_zone_t;
/**
* @brief Zone of AT88SC153. Not support yet.
*
*/
typedef enum {
AT88SC153UZONE0 = 0, ///<
AT88SC153UZONE1, ///<
AT88SC153UZONE2, ///<
AT88SC153CZONE, ///<
AT88SC153AZONE, ///< AAC
AT88SC153FZONE, ///< Fuse
} at88sc153_zone_t;
/**
* @brief Zone of AT88SC608
*
*/
typedef enum {
AT88SC1608UZONE0 = 0, ///<
AT88SC1608UZONE1, ///<
AT88SC1608UZONE2, ///<
AT88SC1608UZONE3, ///<
AT88SC1608UZONE4, ///<
AT88SC1608UZONE5, ///<
AT88SC1608UZONE6, ///<
AT88SC1608UZONE7, ///<
AT88SC1608CZONE, ///<
AT88SC1608AZONE, ///< AAC
AT88SC1608FZONE, ///< Fuse
} at88sc1608_zone_t;
/**
* @brief Password for read or write
*
*/
typedef enum {
TYPE_WRITE = 0, ///< Password for write
TYPE_READ, ///< Password for read
} pwd_rw_t;
/**
* @brief Three part authenticate step. Not support yet.
*
*/
typedef enum {
AUTH_STEP_INITIALIZE = 0, ///<
AUTH_STEP_VERIFY, ///<
} auth_step_t;
/**
* @brief Memory card type
*
*/
typedef enum {
MEMIC_TYPE_UNKNOW = 0, ///<
MEMIC_TYPE_AT88SC101, ///<
MEMIC_TYPE_AT88SC102, ///<
MEMIC_TYPE_AT88SC1604, ///<
MEMIC_TYPE_AT88SC153, ///<
MEMIC_TYPE_AT88SC1608, ///<
MEMIC_TYPE_SLE4428, ///<
MEMIC_TYPE_SLE4442, ///<
MEMIC_TYPE_AT24C01 = 0x10, ///<
MEMIC_TYPE_AT24C02, ///<
MEMIC_TYPE_AT24C04, ///<
MEMIC_TYPE_AT24C08, ///<
MEMIC_TYPE_AT24C16, ///<
MEMIC_TYPE_AT24C32, ///<
MEMIC_TYPE_AT24C64, ///<
MEMIC_TYPE_AT24C128, ///<
MEMIC_TYPE_AT24C256, ///<
MEMIC_TYPE_AT24C512, ///<
} memic_type_t;
/**
* @brief Memory card command
*
*/
typedef enum {
MEMIC_CMD_CLOSE = 0, ///< Close/Poweroff
MEMIC_CMD_OPEN, ///< Open/Poweron
MEMIC_CMD_READ, ///< Read
MEMIC_CMD_WRITE, ///< Write
MEMIC_CMD_VERIFY, ///< PWD/SC/PSC Verify
MEMIC_CMD_UPDATE, ///< PWD/SC/PSC Update
MEMIC_CMD_PAC, ///< Get password attempts counter
MEMIC_CMD_AUTH, ///< Authenticate
MEMIC_CMD_CONFIG, ///< Config
MEMIC_CMD_STA, ///< State. For checking card exist or not.
} memic_cmd_t;
#define AT88SC102_FZ_DEF "\x0F\x0F" ///<(MSB: 0F0F; LSB: F0F0)
#define AT88SC1604_FZ_DEF "\x31\x3A" ///<(MSB: 313A; LSB: 8C5C)
#define SLE4428_ATR_DEF "\x92\x23\x10\x91" ///<
#define SLE4442_ATR_DEF "\xA2\x13\x10\x91" ///<
#define AT88SC1608_ATR_DEF "\x2C\xAA\x55\xA0" ///<
#define MEMIC_BUF_SIZE 256 ///< Memory card operation buffer size
/**
* @brief structure for memory card operation
* @note
* DETSTA
* PWRON CTYPE RFU
* PWROFF CTYPE RFU
* RESET CTYPE RFU FLAG
* READ CTYPE RFU FLAG ZONE ADDR LEN
* WRITE CTYPE RFU FLAG ZONE ADDR LEN DATA
* PAC CTYPE RFU FLAG ZONE ADDR LEN
* CHECK CTYPE RFU FLAG ZONE ADDR LEN DATA
* VERIFY CTYPE RFU FLAG ZONE ADDR LEN DATA
* AUTHEN CTYPE RFU FLAG ZONE ADDR LEN DATA
* CONFIG CTYPE RFU FLAG ZONE ADDR LEN DATA
*
* @warning All RFU shold be 00
*/
typedef struct MEMIC_OPT_ST {
unsigned char ucType; ///< Card type
unsigned char ucCmd; ///< Card command
unsigned char ucZone; ///< Operation zone
unsigned char ucFlag; ///< Operation flag
unsigned char ucSpec; ///< Operation spec
unsigned short usAddr; ///< Operation address
unsigned short usLength; ///< Operation or response data length
unsigned char aucBuf[MEMIC_BUF_SIZE]; ///< Operation or response data buffer
} MemicOptType;
```
>i## MemoryCardOperate
### Prototype
`int MemoryCardOperate(MemicOptType *pstMemicOpt);`
### Function
* Memory card operate interface
### Parameter
|Name|Type|description|
|-|-|-|
|pstMemicOpt|MemicOptType *|[in] Command for card operation, [out] Response data of card operation|
### Retval
|Value|Type|Description|
|-|-|-|
|=0|int|success|
|<0|int|fail|
>s## Example
```
void bwui_smt_test_sle4442_fun(char *result, char *judge_style)
{
int i;
int j;
int iRet = 0;
T_SOFTTIMER tm;
MemicOptType stMemicOpt;
unsigned char aucReadBuf[8];
unsigned char aucWriteBuf[8];
i = 0;
s_TimerSet(&tm, 5000);
KbFlush();
while (s_TimerCheck(&tm)) {
stMemicOpt.ucCmd = MEMIC_CMD_STA;
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet == 0) {
break;
}
if (KEY_CANCEL == KbWaitKey(300)) {
iRet = -1;
break;
}
}
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "find MemoryCard card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
}
//memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_OPEN;
iRet = MemoryCardOperate(&stMemicOpt);
if ((iRet != 0) || (memcmp(stMemicOpt.aucBuf, SLE4442_ATR_DEF, SLE4442_ATR_LEN) != 0)) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "power on SLE4442 card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
} else {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "ATR: %02X%02X%02X%02X\n", stMemicOpt.aucBuf[0], stMemicOpt.aucBuf[1], stMemicOpt.aucBuf[2], stMemicOpt.aucBuf[3]);
}
//memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_READ;
stMemicOpt.ucZone = SLE4442_MM;
stMemicOpt.usAddr = 0x20;
stMemicOpt.usLength = sizeof(aucReadBuf);
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "read SLE4442 card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
} else {
memcpy(aucReadBuf, stMemicOpt.aucBuf, sizeof(aucReadBuf));
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "1R: %02X%02X%02X%02X%02X%02X%02X%02X\n",
stMemicOpt.aucBuf[0], stMemicOpt.aucBuf[1], stMemicOpt.aucBuf[2], stMemicOpt.aucBuf[3],
stMemicOpt.aucBuf[4], stMemicOpt.aucBuf[5], stMemicOpt.aucBuf[6], stMemicOpt.aucBuf[7]);
}
memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_VERIFY;
stMemicOpt.ucZone = SLE4442_SM;
stMemicOpt.usLength = 0x03;
memcpy(stMemicOpt.aucBuf, "\xFF\xFF\xFF", 0x03);
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "verify SLE4442 card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
}
for (j=0; j<sizeof(aucReadBuf); j++) {
aucWriteBuf[j] = (aucReadBuf[j] ^ 0xFF);
}
memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_WRITE;
stMemicOpt.ucZone = SLE4442_MM;
stMemicOpt.usAddr = 0x20;
stMemicOpt.usLength = sizeof(aucWriteBuf);
memcpy(stMemicOpt.aucBuf, aucWriteBuf, sizeof(aucWriteBuf));
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "write SLE4442 card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
}
memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_READ;
stMemicOpt.ucZone = SLE4442_MM;
stMemicOpt.usAddr = 0x20;
stMemicOpt.usLength = sizeof(aucReadBuf);
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "read SLE4442 card fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
} else {
memcpy(aucReadBuf, stMemicOpt.aucBuf, sizeof(aucReadBuf));
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "2R: %02X%02X%02X%02X%02X%02X%02X%02X\n",
stMemicOpt.aucBuf[0], stMemicOpt.aucBuf[1], stMemicOpt.aucBuf[2], stMemicOpt.aucBuf[3],
stMemicOpt.aucBuf[4], stMemicOpt.aucBuf[5], stMemicOpt.aucBuf[6], stMemicOpt.aucBuf[7]);
}
if (memcmp(stMemicOpt.aucBuf, aucWriteBuf, sizeof(aucWriteBuf)) != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "read data inconsistency\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
}
memset(&stMemicOpt, 0x0, sizeof(MemicOptType));
stMemicOpt.ucType = MEMIC_TYPE_SLE4442;
stMemicOpt.ucCmd = MEMIC_CMD_CLOSE;
iRet = MemoryCardOperate(&stMemicOpt);
if (iRet != 0) {
i += snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "SLE4442 poweroff fail\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_ESC_FAIL_ENTER_RETRY;
return;
}
AudioDtmfPlay_OEM1(DTMF_letterD, 2, 1);
snprintf(&result[i], (MAX_RESULT_STR_LEN-i), "read card success\n");
*judge_style = BWUI_SMT_JUDGE_STYLE_PASS_ENTER;
}
```