/*
DaVinci ARM Evaluation Software
(c)Texas Instruments 2004
*/
/**
\file mmcsd_protocol.c
\brief Contains APIs common to MMC and SD, which are protocol specific
*/
#include <cslr_mmcsd.h>
#include <memcd_rettypes.h>
#include <mmcsd_protocol.h>
#include <mmc_protocol.h>
#include <mmcsd_evm.h>
#include <csl_edma.h>
//#include <davinci64plus.h>
#define CSL_EDMA_0 0
extern MMCSD_ResponseData mmcsdResponse;
extern MMCSD_csdRegInfo mmcsdCSDRegInfo;
Uint32 relCardAdress;
/**
\brief Send command to set all the MMC/SD cards to Idle State
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_goIdleState()
{
STATUS status;
status = MMCSD_sendCmd( (0x4000 | MMCSD_GO_IDLE_STATE), MMCSD_STUFF_BITS, (Bool)0, MMCSD_STAT0_RSPDNE);
return ( status );
}
/**
\brief Send command to read the contents of the Card Identification (CID) register, on the MMC/SD
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_allSendCID( void )
{
volatile Uint16 stat;
STATUS status;
status = MMCSD_sendCmd( MMCSD_ALL_SEND_CID, MMCSD_STUFF_BITS, (Bool)1, MMCSD_STAT0_RSPDNE);
return ( status );
}
/**
\brief Send command to set the Driver Stage Register (DSR) on the MMC/SD
\param dsr The DSR value to be programmed into the card (default value of DSR = 0x04040000, where last 6bits are stuff bits)
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_setDSR( Uint32 dsr )
{
STATUS status;
if( mmcsdCSDRegInfo.dsrImp != 1 )
return E_DEVICE;
status = MMCSD_sendCmd( MMCSD_SET_DSR, dsr, (Bool)1, MMCSD_STAT0_RSPDNE);
return ( status );
}
/**
\brief Send command to read the status of the MMC/SD
\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 MMCSD_sendStatus( Uint32 rca, MMCSD_cardStatusReg *cardStatus )
{
STATUS status;
/* the rca value is sent as the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMCSD_SEND_STATUS, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
/* Response expected: R1 in native mode and R2 in SPI mode*/
MMCSD_getCardStatus( &mmcsdResponse, cardStatus );
return ( E_PASS );
}
return ( status );
}
/**
\brief Send command to select a particular MMC/SD, using it's assigned RCA
\param rca Relative Card Address assigned to the card
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_selectCard( Uint32 rca )
{
STATUS status;
MMCSD_cardStatusReg cardStatus;
/* the rca value is sent as the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMCSD_SELECT_CARD, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE );
if( status == E_PASS ) {
/* no timeout */
if ( rca > 0 ) {
if( (MMCSD_sendStatus( rca, &cardStatus ) == E_PASS) ) {
if( (cardStatus.currentState == MMCSD_STATE_TRAN) || (cardStatus.currentState == MMCSD_STATE_PRG ) ) {
return ( E_PASS );
}
}
}
}
return ( status );
}
/**
\brief Send command to deselect all MMCs / SDs (rca=0) or only the currently selected MMC/SD (rca != current MMCs/SDs rca)
\param newRCA a new RCA value, used for deselecting only the currently selected MMC/SD
\param oldRCA the currently selected MMCs/SDs RCA value, used for checking if that MMC/SD is deselected
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_deSelectCard( Uint16 newRCA, Uint16 oldRCA )
{
STATUS status;
MMCSD_cardStatusReg cardStatus;
int i=0;
/* Deselect the card then check status to see if
we are in the proper state. Because we are
using rca = 0 to deselect there will not be
the typical R1 response. : This is true if u want to deselect
all cards with 1 cmd - Rati
*/
if( newRCA == oldRCA ){
status = MMCSD_sendCmd( MMCSD_DESELECT_CARD, 0, (Bool)0, MMCSD_STAT0_RSPDNE );
} else {
status = MMCSD_sendCmd( MMCSD_DESELECT_CARD, newRCA, (Bool)0, MMCSD_STAT0_RSPDNE );
}
/* delay reqd. */
for( i=0; i<1000; i++ );
/* Check if card is de-selected */
if( status == E_PASS ) {
status = MMCSD_sendStatus( oldRCA, &cardStatus );
if( status == E_PASS )
if( (cardStatus.currentState == MMCSD_STATE_STBY) || (cardStatus.currentState == MMCSD_STATE_DIS ) ) {
return ( E_PASS );
}
}
return ( E_DEVICE );
}
/**
\brief Send command to read the contents of the Card Specific Data (CSD) register, on the MMC/SD
\param rca Relative Card Address assigned to the card
\param cardCSD CSD of the card is received in this structure
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_sendCSD( Uint32 rca, Uint16 *cardCSD )
{
STATUS status;
/* the rca value is sent as the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMCSD_SEND_CSD, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
MMCSD_getCardCSD( &mmcsdResponse, cardCSD, &mmcsdCSDRegInfo );
return ( E_PASS );
}
return ( status );
}
/**
\brief Send command to read the contents of the Card Identification (CID) register, on the MMC/SD
\param rca Relative Card Address assigned to the card
\param cardCID CID of the card is received in this structure
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_sendCID( Uint32 rca, Uint16 *cardCID )
{
STATUS status;
/* the rca value is sent as the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMCSD_SEND_CID, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
if( status == E_PASS ) {
MMCSD_getCardCID( &mmcsdResponse, cardCID );
return ( E_PASS );
}
return ( status );
}
/**
\brief Send command to send the specified MMC/SD (selected using RCA) into Inactive State
\param rca Relative Card Address assigned to the card
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_goInactiveState( Uint32 rca )
{
STATUS status;
/* the rca value is sent as the upper 16 bits of the command argument */
status = MMCSD_sendCmd( MMCSD_GO_INACTIVE_STATE, rca<<16, (Bool)1, MMCSD_STAT0_RSPDNE);
return ( status );
}
/**
\brief Send command to set the block length of data to be transferred to/from the MMC/SD
\param blkLength Block length, in bytes, of data to be transferred to/from MMC/SD
\param write 0: read data from MMC/SD, 1: write data to MMC/SD
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_setBlkLen( Uint32 blkLength, Bool write )
{
STATUS status;
if( blkLength%512 )
if( write == 1 ){
if( mmcsdCSDRegInfo.writeBlkPartial != 1 ){
return E_FAIL; /* Command not supported */
}
}else {
if( mmcsdCSDRegInfo.readBlkPartial != 1 ){
return E_FAIL; /* Command not supported */
}
}
status = MMCSD_sendCmd( MMCSD_SET_BLOCKLEN, blkLength, (Bool)1, MMCSD_STAT0_RSPDNE);
return ( status );
}
/**
\brief Send command to program the programmable fields of the CSD register of MMC/SD
\param rca Relative Card Address assigned to the card
\param numBlks
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_programCSD( Uint32 rca, MMCSD_cardStatusReg *cardStatus, DM_BOOL writeProtect,Uint32 cardMemAddr )
{
STATUS status;
Uint16 cardCSD[8];
Uint32
评论0