📄 mmc_protocol.c
字号:
/*
DaVinci ARM Evaluation Software
(c)Texas Instruments 2004
*/
/**
\file mmc_protocol.c
\brief MMC Related APIs, which are protocol specific
*/
#include <cslr_mmcsd.h>
#include <memcd_rettypes.h>
#include <mmcsd_evm.h>
#include <mmcsd_protocol.h>
#include <mmc_protocol.h>
extern MMCSD_ResponseData mmcsdResponse;
extern MMCSD_csdRegInfo mmcsdCSDRegInfo;
/**
\brief Send command to check if the Operating Voltage Conditions of the MMC, match that of the host
\param voltageWindow voltage window supported by the host
\param opTimeOut timeout value to check if the card is powered-up, after sending the command
\return if success, \c E_PASS, else error code
*/
STATUS MMC_sendOpCond( Uint32 voltageWindow, Uint32 opTimeOut )
{
STATUS status;
do {
/* Format and send cmd: Volt. window is usually 0x00300000 (3.4-3.2v)*/
status = MMCSD_sendCmd( MMC_SEND_OP_COND, voltageWindow, (Bool)1, MMCSD_STAT0_RSPDNE);
if ( MMCSD_GET_OCR_POWERON_STATUS() ) {
return( E_PASS );
}
opTimeOut--;
} while ( opTimeOut > 0 );
/* Time-out occurred : reset the card */
return( E_DEVICE );
}
/**
\brief Send command to set the Relative Card Address (RCA) of the MMC
\param rca Relative Card Address assigned to the card
\param cardStatus Status of the card is received in this structure
\return if success, \c E_PASS, else error code
*/
STATUS MMC_setRCA( Uint32 rca, MMCSD_cardStatusReg *cardStatus )
{
STATUS status;
/* rca is given a value >= 2, as 0 or 1(in case of SanDisk cards) is
the default value for all cards. Also, the rca value is sent as
the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMC_SET_RELATIVE_ADDR, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
/* Response expected: R1 */
MMCSD_getCardStatus( &mmcsdResponse, cardStatus );
return ( E_PASS );
}
return ( status );
}
/**
\brief Send command to set the number of blocks of data to be transferred to/from the MMC
\param numBlks Block count of data to be transferred to/from MMC
\return if success, \c E_PASS, else error code
*/
STATUS MMC_setBlkCount( Uint32 numBlks )
{
STATUS status;
status = MMCSD_sendCmd( MMC_SET_BLOCKCOUNT, numBlks, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
return ( E_PASS );
}
return ( status );
}
/**
\brief Send command to erase a range of blocks on the MMC
\param startAddr Start address of blocks selected to be erased
\param endAddr End address of blocks selected to be erased
\param untag Number of blocks to untag in the selected blocks
\param untagAddr Addresses of blocks to be untagged
\param groupFlag Whether a tag erase group exists 0: does not exist 1: exists
\return if success, \c E_PASS, else error code
*/
STATUS MMC_erase( Uint32 startAddr, Uint32 endAddr, Uint16 untag, Uint32 *untagAddr, Uint16 groupFlag)
{
STATUS status;
if(groupFlag) {
status = MMCSD_sendCmd( MMC_TAG_ERASE_GROUP_START, startAddr, (Bool)1, MMCSD_STAT0_RSPDNE);
} else {
status = MMCSD_sendCmd( MMC_TAG_SECTOR_START, startAddr, (Bool)1, MMCSD_STAT0_RSPDNE);
}
if( status == E_PASS ) {
if(groupFlag) {
status = MMCSD_sendCmd( MMC_TAG_ERASE_GROUP_END, endAddr, (Bool)1, MMCSD_STAT0_RSPDNE);
} else {
status = MMCSD_sendCmd( MMC_TAG_SECTOR_END, endAddr, (Bool)1, MMCSD_STAT0_RSPDNE);
}
if ( status == E_PASS ){
if ( untag ) {
if ( untag > 16 ) untag = 16;
if(groupFlag) {
do {
/* Format and send UNTAG sector command */
if( MMCSD_sendCmd( MMC_UNTAG_ERASE_GROUP, *untagAddr, (Bool)1, MMCSD_STAT0_RSPDNE) != E_PASS ){
return ( E_DEVICE );
}
untagAddr++;
} while ( --untag );
} else {
do {
/* Format and send UNTAG sector command */
if( MMCSD_sendCmd( MMC_UNTAG_ERASE_GROUP, *untagAddr, (Bool)1, MMCSD_STAT0_RSPDNE) != E_PASS ){
return ( E_DEVICE );
}
untagAddr++;
} while ( --untag );
}
}
status = MMCSD_sendCmd( MMC_ERASE, MMCSD_STUFF_BITS, (Bool)1, (MMCSD_STAT0_RSPDNE | MMCSD_STAT0_DATDNE | MMCSD_STAT0_BSYDNE));
}
}
return ( status );
}
/**
\brief Send command to move the MMC to IRQ state
\param rcaRcvd RCA received on Interrupt Request - of winning card or of the host (rca =0)
\return if success, \c E_PASS, else error code
*/
STATUS MMC_goIRQState( Uint16 *rcaRcvd )
{
STATUS status;
status = MMCSD_sendCmd( MMC_GO_IRQ_STATE, MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE );
if( status == E_PASS ) {
*rcaRcvd = MMCSD_RCA_RCVD();
}
return ( status );
}
/**
\brief Send command to set a password or replace the existing password on the MMC
\param oldPasswordSize Size in bytes of the existing password
\param newPasswordSize Size in bytes of the new password to be set
\param oldPassword Existing password
\param newPassword New password
\return if success, \c E_PASS, else error code
*/
STATUS MMC_setPassword( Uint8 oldPasswordSize, Uint8 newPasswordSize, Uint8 *oldPassword, Uint8 *newPassword,Uint32 cardMemAddr )
{
STATUS status;
Uint8 lockCardDataStructure[18];
int i=0;
Uint32 numWords = 0;
if( oldPasswordSize != 0 ) {
numWords = 2+newPasswordSize+oldPasswordSize;
} else {
numWords = 2+newPasswordSize;
}
status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, numWords, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
//< Set the lockCardDataStructure elements
lockCardDataStructure[0] = (Uint8)MMCSD_SET_PASSWD;
if( oldPasswordSize != 0 ) {
lockCardDataStructure[1] = newPasswordSize+oldPasswordSize;
for ( i=0; i<oldPasswordSize; i++)
{
lockCardDataStructure[i+2]= oldPassword[i];
}
for ( i=0; i<newPasswordSize; i++)
{
lockCardDataStructure[i+2+oldPasswordSize]= newPassword[i];
}
} else {
lockCardDataStructure[1] = newPasswordSize;
for ( i=0; i<newPasswordSize; i++)
{
lockCardDataStructure[i+2]= newPassword[i];
}
}
status = MMCSD_sendCmd( (0xB900 | MMC_LOCK_UNLOCK), MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE );
if( status == E_PASS ) {
//status = MMCSD_writeNWords( (Uint16*)lockCardDataStructure, numWords );
status = MMCSD_writeNWords( (Uint32*)lockCardDataStructure, numWords,cardMemAddr,DM_FALSE );
if( status == E_PASS )
status = MMCSD_checkStatus( (MMCSD_STAT0_DATDNE | MMCSD_STAT0_BSYDNE), 0, 0 );
if( status == E_PASS )
status = MMCSD_LOCK_UNLOCK_FAIL_CHK(); //< If fail, old password does not change
}
}
return ( status );
}
/**
\brief Send command to reset the existing password on the MMC
\param currentPasswordSize Size in bytes of the existing password
\param currentPassword Existing password
\return if success, \c E_PASS, else error code
*/
STATUS MMC_resetPassword( Uint8 currentPasswordSize, Uint8 *currentPassword,Uint32 cardMemAddr )
{
STATUS status;
Uint8 lockCardDataStructure[18];
int i=0;
status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, 2+currentPasswordSize, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
//< Set the lockCardDataStructure elements
lockCardDataStructure[0] = (Uint8)MMCSD_CLR_PASSWD;
lockCardDataStructure[1] = currentPasswordSize;
for ( i=0; i<currentPasswordSize; i++)
{
lockCardDataStructure[i+2]= currentPassword[i];
}
status = MMCSD_sendCmd( (0xB900 | MMC_LOCK_UNLOCK), MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE );
if( status == E_PASS ) {
status = MMCSD_writeNWords( (Uint32*)lockCardDataStructure, 2+currentPasswordSize,cardMemAddr,FALSE );
if( status == E_PASS )
status = MMCSD_checkStatus( (MMCSD_STAT0_DATDNE | MMCSD_STAT0_BSYDNE), 0, 0 );
if( status == E_PASS )
status = MMCSD_LOCK_UNLOCK_FAIL_CHK(); //< If fail, old password does not change
}
}
return ( status );
}
/**
\brief Send command to lock the MMC and/or set a password or replace the existing password on the MMC
\param cardLockMode Card lock mode - 1: set passwd, 2: clr passwd, 4: lock; 8: forced erase
\param oldPasswordSize Size in bytes of the existing password
\param newPasswordSize Size in bytes of the new password to be set
\param oldPassword Existing password
\param newPassword New password
\return if success, \c E_PASS or \c CardLock and Passwd Set status, else error code
*/
Uint8 MMC_cardLock( Uint8 cardLockMode, Uint8 oldPasswordSize, Uint8 newPasswordSize, Uint8 *oldPassword, Uint8 *newPassword,Uint32 cardMemAddr )
{
STATUS status;
Uint8 lockCardDataStructure[18];
int i=0;
Uint32 numWords = 0;
if( (oldPasswordSize != 0) && (newPasswordSize != 0) ) {
numWords = 2+newPasswordSize+oldPasswordSize;
} else if( oldPasswordSize == 0 ) {
numWords = 2+newPasswordSize;
} else if( newPasswordSize == 0 ) {
numWords = 2+oldPasswordSize;
}
status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, numWords, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
//< Set the lockCardDataStructure elements
lockCardDataStructure[0] = cardLockMode;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -