📄 cardmng.c
字号:
return CARD_ERR_NO;
}
/****************************************************************************/
/* FUNCTION: ConfigCard */
/* DESCRIPTION:config card for full speed transmit */
/* INPUTS */
/* OUTPUTS: CARD_ERR_NO config OK */
/* output from ReadCSD_CID */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* Victor 2004-07-29 create */
/****************************************************************************/
INT ConfigCard(void)
{
INT retVal;
// read CID
if((retVal = ReadCSD_CID((UINT8 *)ucpCmd10, (UINT8 *)(®CID), sizeof(regCID))) != CARD_ERR_NO){
return retVal;
}
// read CSD
if((retVal = ReadCSD_CID((UINT8 *)ucpCmd9, _regCSD, sizeof(_regCSD))) != CARD_ERR_NO){
return retVal;
}
// analyze CSD
regCSD.CSD_STRUCTURE = CSD_STRUCTURE(_regCSD);
regCSD.SPEC_VERS = SPEC_VERS(_regCSD);
regCSD.TAAC = TAAC(_regCSD);
regCSD.NSAC = NSAC(_regCSD);
regCSD.TRAN_SPEED = TRAN_SPEED(_regCSD);
regCSD.CCC = CCC(_regCSD);
regCSD.READ_BL_LEN = READ_BL_LEN(_regCSD);
regCSD.READ_BL_PARTIAL = READ_BL_PARTIAL(_regCSD);
regCSD.WRITE_BLK_MISALIGN = WRITE_BLK_MISALIGN(_regCSD);
regCSD.READ_BLK_MISALIGN = READ_BLK_MISALIGN(_regCSD);
regCSD.DSR_IMP = DSR_IMP(_regCSD);
regCSD.C_SIZE = C_SIZE(_regCSD);
regCSD.VDD_R_CURR_MIN = VDD_R_CURR_MIN(_regCSD);
regCSD.VDD_R_CURR_MAX = VDD_R_CURR_MAX(_regCSD);
regCSD.VDD_W_CURR_MIN = VDD_W_CURR_MIN(_regCSD);
regCSD.VDD_W_CURR_MAX = VDD_W_CURR_MAX(_regCSD);
regCSD.C_SIZE_MULT = C_SIZE_MULT(_regCSD);
regCSD.ERASE_GRP_SIZE = ERASE_GRP_SIZE(_regCSD);
regCSD.ERASE_GRP_MULT = ERASE_GRP_MULT(_regCSD);
regCSD.WP_GRP_SIZE = WP_GRP_SIZE(_regCSD);
regCSD.WP_GRP_ENABLE = WP_GRP_ENABLE(_regCSD);
regCSD.DEFAULT_ECC = DEFAULT_ECC(_regCSD);
regCSD.R2W_FACTOR = R2W_FACTOR(_regCSD);
regCSD.WRITE_BL_LEN = WRITE_BL_LEN(_regCSD);
regCSD.WRTIT_BL_PARTIAL = WRTIT_BL_PARTIAL(_regCSD);
regCSD.FILE_FORMAT_GRP = FILE_FORMAT_GRP(_regCSD);
regCSD.COPY = COPY(_regCSD);
regCSD.PERM_WRITE_PROTECT = PERM_WRITE_PROTECT(_regCSD);
regCSD.TMP_WRITE_PROTECT = TMP_WRITE_PROTECT(_regCSD);
regCSD.FILE_FORMAT = FILE_FORMAT(_regCSD);
regCSD.ECC = ECC(_regCSD);
regCSD.CRC = CRC(_regCSD);
/*
if(CheckCrc7(_regCSD, 16) == FALSE){
//if(CRC7(_regCSD, 15) != regCSD.CRC){
return CARD_ERR_CRC;
}
*/
// Set transfer clock(regCSD.TRAN_SPEED = 0x32 == 25Mbps): MCBR[2:0](D[6:4]) = 0, clock = 24MHz/4 = 6MHz
*((volatile UINT32 *)REG_SPI_CTL1) &= ~0x0070;
// Set NAC
//maxNAC = (regCSD.NSAC * 100 + timeUnit[regCSD.TAAC & 0x7] * timeValue[(regCSD.TAAC & 0x78)>>3] * 6)/8;
maxNAC = 1024 * 1024;
return CARD_ERR_NO;
}
/****************************************************************************/
/* FUNCTION: ReadBlock */
/* DESCRIPTION:read a block from card */
/* INPUTS offset address of data will be read */
/* len data length will be read */
/* buf store the data */
/* OUTPUTS: CARD_ERR_NO read OK */
/* CARD_ERR_TIMEOUT time out */
/* CARD_ERR_CMDILLEGAL command is illegal */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* Victor 2004-07-29 create */
/****************************************************************************/
INT ReadBlock(UINT32 offset, UINT len, UINT8 *buf)
{
UINT8 r1; // response format R1
UINT i;
UINT8 cmd17[6];
// set up cmd17 command
cmd17[0] = 0x51;
cmd17[1] = ((UINT8 *)(&offset))[3];
cmd17[2] = ((UINT8 *)(&offset))[2];
cmd17[3] = ((UINT8 *)(&offset))[1];
cmd17[4] = ((UINT8 *)(&offset))[0];
cmd17[5] = 0xff;
reSend:
//send CMD17
if(SendCommand(cmd17, RDATA_FORMAT, &r1) == FALSE){
return CARD_ERR_TIMEOUT; // time out
}
if(r1 != 0x00){
DisableCard(); //SET CS = 'H'
if(CardInitial() == CARD_ERR_NO){
goto reSend;
}
return CARD_ERR_CMDILLEGAL; // command is illegal
}
/*
for(i = 0; i < MIN_NCX; i++){ //wait NCX(min)
SendBytes(DUMMY, 1);
}
*/
//check the response data token
for(i = 0; i < maxNAC; i++){ //wait NAC(max)
ReceiveBytes(&r1, 1);
if(r1 == SINGLE_READ_START){
break; // data token: data begin to be transmitted
}
}
if(i == maxNAC){
return CARD_ERR_TIMEOUT; // time out
}
ReceiveBytes(buf, len); // receive data
ReceiveBytes(&r1, 1); // receive 2 bytes CRC
ReceiveBytes(&r1, 1);
DisableCard(); //SET CS = 'H'
return CARD_ERR_NO;
}
INT GetStatusReg(UINT16 *pStatusReg)
{
//send CMD13
if(SendCommand((UINT8 *)ucpCmd13, R2_FORMAT, (UINT8 *)pStatusReg) == FALSE){
return CARD_ERR_TIMEOUT; // time out
}
if(((*pStatusReg) & 0x00ff) != 0x00){
return CARD_ERR_CMDILLEGAL; // command is illegal
}
return CARD_ERR_NO;
}
INT SetBlockLen(UINT len)
{
UINT8 r1; // response format R1
UINT8 cmd16[6];
// set up cmd16 command
cmd16[0] = 0x50;
cmd16[1] = ((UINT8 *)(&len))[3];
cmd16[2] = ((UINT8 *)(&len))[2];
cmd16[3] = ((UINT8 *)(&len))[1];
cmd16[4] = ((UINT8 *)(&len))[0];
cmd16[5] = 0xff;
//send CMD16
if(SendCommand(cmd16, R1_FORMAT, &r1) == FALSE){
return CARD_ERR_TIMEOUT; // time out
}
if(r1 != 0x00){
return CARD_ERR_CMDILLEGAL; // command is illegal
}
return CARD_ERR_NO;
}
#define MAX_PASSWORD_LEN 8
#define LOCK_SET_PASSWORD 0x05 // set & lock 00000101b
#define LOCK_CLEAR_PASSWORD 0x02 // clear 00000010b
#define LOCK_LOCK_PASSWORD 0x04 // lock 00000100b
#define LOCK_UNLOCK_PASSWORD 0x00 // unlock 00000000b
INT LockOperate(UINT8 *password, UINT len, UINT8 operate)
{
UINT8 r1; // response format R1
UINT i;
UINT8 lockData[MAX_PASSWORD_LEN + 2];
// setup lock data
if(len > MAX_PASSWORD_LEN){
return CARD_ERR_LOCK;
}
lockData[0] = operate; // set/clear/lock/unlock
lockData[1] = (UINT8)len;
memcpy(&lockData[2], password, len);
//send CMD42
if(SendCommand((UINT8 *)ucpACmd42, RDATA_FORMAT, &r1) == FALSE){
return CARD_ERR_TIMEOUT; // time out
}
if(r1 != 0x00){
DisableCard(); //SET CS = 'H'
return CARD_ERR_CMDILLEGAL; // command is illegal
}
for(i = 0; i < MIN_NWR; i++){ //wait NWR(min)
SendBytes(DUMMY, 1);
}
SendBytes(DATA_TOKEN, 1); // send data token
SendBytes(lockData, len + 2); // send data
SendBytes(DUMMY, 1); // 2 bytes CRC
SendBytes(DUMMY, 1);
//check the data response
for(i = 0; i < 8; i++){ //should be at once
ReceiveBytes(&r1, 1);
r1 &= 0x1f;
if(r1 == 0x05){
break; // data accepted
}
if(r1 == 0x0b || r1 == 0x0d){
DisableCard(); //SET CS = 'H'
return CARD_ERR_WRITE; // data rejected due to CRC error or Write error
}
}
if(i == 8){
DisableCard(); //SET CS = 'H'
return CARD_ERR_TIMEOUT; // time out
}
// waiting for ready
while(1){
ReceiveBytes(&r1, 1);
if(r1 == 0xff){
break;
}
}
DisableCard(); //SET CS = 'H'
return CARD_ERR_NO;
}
/****************************************************************************/
/* FUNCTION: WriteBlock */
/* DESCRIPTION:write a block to card */
/* INPUTS offset address of data will be write */
/* len data length will be write */
/* buf data will be write */
/* OUTPUTS: CARD_ERR_NO write OK */
/* CARD_ERR_LOCKED card be locked */
/* CARD_ERR_TIMEOUT time out */
/* CARD_ERR_WRITE error due to CRC or write error */
/* CARD_ERR_CMDILLEGAL command is illegal */
/****************************************************************************/
/* NAME DATE REMARKS */
/* ========== ============ ==============================================*/
/* Victor 2004-07-29 create */
/****************************************************************************/
INT WriteBlock(UINT32 offset, UINT len, UINT8 *buf)
{
UINT8 r1; // response format R1
UINT i;
UINT8 cmd24[6];
if(IsCardLocked() == TRUE){
return CARD_ERR_LOCKED; // card locked
}
// set up cmd24 command
cmd24[0] = 0x58;
cmd24[1] = ((UINT8 *)(&offset))[3];
cmd24[2] = ((UINT8 *)(&offset))[2];
cmd24[3] = ((UINT8 *)(&offset))[1];
cmd24[4] = ((UINT8 *)(&offset))[0];
cmd24[5] = 0xff;
reSend_w:
//send CMD24
if(SendCommand(cmd24, RDATA_FORMAT, &r1) == FALSE){
return CARD_ERR_TIMEOUT; // time out
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -