📄 mmcsd_evm.c
字号:
/*
DaVinci ARM Evaluation Software
(c)Texas Instruments 2004
*/
/**
\file mmcsd_evm.c
\brief MMC/SD DaVinci EVM Related APIs*/
#include <cslr_mmcsd.h>
#include <memcd_rettypes.h>
#include <mmcsd_evm.h>
#include <mmcsd_protocol.h>
#include <mmc_protocol.h>
#include <csl_edma.h>
//#include <davinci64plus.h>
#include <davinci.h>
//#include <cslr_tmr_001.h>
#define CSL_EDMA_0 0
extern Uint32 relCardAdress;
/**
\brief Set MMC/SD Controller configuration
\param mmcsdConfig MMC/SD Controller configuration paramters
\return if success, \c E_PASS, else error code
\see MMCSD_ConfigData
*/
STATUS MMCSD_setConfig(MMCSD_ConfigData * mmcsdConfig) {
Uint16 modebits, modemask;
modebits = CSL_FMK(MMCSD_MMCCTL_PERMDX, mmcsdConfig->writeEndian) |
CSL_FMK(MMCSD_MMCCTL_PERMDR, mmcsdConfig->readEndian ) |
CSL_FMK(MMCSD_MMCCTL_DATEG, mmcsdConfig->dat3Detect ) |
CSL_FMK(MMCSD_MMCCTL_WIDTH, mmcsdConfig->busWidth );
/* Create a bit mask for the selected fields */
modemask = CSL_FMK(MMCSD_MMCCTL_PERMDX, 0xFFFF) |
CSL_FMK(MMCSD_MMCCTL_PERMDR, 0xFFFF) |
CSL_FMK(MMCSD_MMCCTL_DATEG, 0xFFFF) |
CSL_FMK(MMCSD_MMCCTL_WIDTH, 0xFFFF) ;
CSL_MMCSD_0_REGS->MMCCTL= (Uint16) (modebits & modemask);
CSL_FINS(CSL_MMCSD_0_REGS->MMCTOR,MMCSD_MMCTOR_TOR, mmcsdConfig->timeoutResponse);
CSL_MMCSD_0_REGS->MMCTOD= (Uint16)(mmcsdConfig->timeoutRead);
return E_PASS;
}
/**
\brief Set MMC/SD interrupt mask
\param mmcsdInt Interrupt mask for MMC/SD controller. Interrupt will be generated for all the interrupts that are enabled
\return if success, \c E_PASS, else error code
\see MMCSD_IntMode
*/
STATUS MMCSD_setIntMode(MMCSD_IntMode * mmcsdInt) {
Uint16 intMask = 0x0;
if(mmcsdInt->datedIntEnable == TRUE)
intMask |= 0x0800;
if(mmcsdInt->drRdyIntEnable == TRUE)
intMask |= 0x0400;
if(mmcsdInt->dxRdyIntEnable == TRUE)
intMask |= 0x0200;
if(mmcsdInt->spiErrIntEnable == TRUE)
intMask |= 0x0100;
if(mmcsdInt->crcErrReadIntEnable == TRUE)
intMask |= 0x0080;
if(mmcsdInt->crcErrResponseIntEnable == TRUE)
intMask |= 0x0040;
if(mmcsdInt->crcErrWriteIntEnable == TRUE)
intMask |= 0x0020;
if(mmcsdInt->timeoutResponseIntEnable == TRUE)
intMask |= 0x0010;
if(mmcsdInt->timeoutReadIntEnable == TRUE)
intMask |= 0x0008;
if(mmcsdInt->rspDneIntEnable == TRUE)
intMask |= 0x0004;
if(mmcsdInt->bsyDneIntEnable == TRUE)
intMask |= 0x0002;
if(mmcsdInt->datDneIntEnable == TRUE)
intMask |= 0x0001;
CSL_MMCSD_0_REGS->MMCIM = intMask;
return E_PASS;
}
/**
\brief Send Command to MMC/ SD
\param command Command to be sent to MMC/ SD
\param argument Arguments to be sent with the command
\param checkStatus 0: no status check, 1: status check
\param statusBits status bits to be checked in MMCST0 register, if 'checkStatus' = 1
\return \c E_PASS, on completion
*/
STATUS MMCSD_sendCmd(Uint32 command, Uint32 argument, Bool checkStatus, Uint16 statusBits) {
Uint16 statusRegBits=0x0,status=0x0,i=0;
// Clear Status
status=CSL_MMCSD_0_REGS->MMCST0;
/* Clear Response Registers*/
MMCSD_clearResponse();
//Setup the Argument Register and send CMD */
CSL_FINS(CSL_MMCSD_0_REGS->MMCARGHL,MMCSD_MMCARGHL_ARGL,(argument & 0xFFFF));
CSL_FINS(CSL_MMCSD_0_REGS->MMCARGHL,MMCSD_MMCARGHL_ARGH,((argument >>16) & 0xFFFF));
CSL_MMCSD_0_REGS->MMCCMD=(Uint16)command;
/*Delay loop allowing cards to respond */
for(i=0;i<20;i++);
if( checkStatus )
{
//Wait for RspDne; exit on RspTimeOut or RspCRCErr
while((statusRegBits & (0x00F8|statusBits)) == 0 )
{
statusRegBits=CSL_MMCSD_0_REGS->MMCST0;
}
return( ((statusRegBits & statusBits) == statusBits) ? E_PASS : E_DEVICE );
}
return E_PASS;
}
/**
\brief Get Response from MMC/SD controller and Clear Response
\param mmcsdResponse Command Response is received in this parameter
\return if success, \c E_PASS, else error code
\see MMCSD_ResponseData
*/
STATUS MMCSD_getResponse(MMCSD_ResponseData * mmcsdResponse) {
mmcsdResponse->response[0] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP01,MMCSD_MMCRSP01_MMCRSP0);
mmcsdResponse->response[1] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP01,MMCSD_MMCRSP01_MMCRSP1);
mmcsdResponse->response[2] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP23,MMCSD_MMCRSP23_MMCRSP2);
mmcsdResponse->response[3] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP23,MMCSD_MMCRSP23_MMCRSP3);
mmcsdResponse->response[4] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP45,MMCSD_MMCRSP45_MMCRSP4);
mmcsdResponse->response[5] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP45,MMCSD_MMCRSP45_MMCRSP5);
mmcsdResponse->response[6] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP67,MMCSD_MMCRSP67_MMCRSP6);
mmcsdResponse->response[7] =CSL_FEXT(CSL_MMCSD_0_REGS->MMCRSP67,MMCSD_MMCRSP67_MMCRSP7);
mmcsdResponse->commandIdk =CSL_FEXT(CSL_MMCSD_0_REGS->MMCCIDX,MMCSD_MMCCIDX_CIDX);
MMCSD_clearResponse();
return E_PASS;
}
/**
\brief Parse the Card Status value, sent to the MMC/SD card, in response to a command
\param mmcsdResponse Command Response is received in this parameter
\param cardStatus Card Status is parsed and stored in this parameter
\return if success, \c E_PASS
\see MMCSD_ResponseData, MMCSD_cardStatusReg
*/
STATUS MMCSD_getCardStatus( MMCSD_ResponseData * mmcsdResponse, MMCSD_cardStatusReg *cardStatus ) {
Uint16 response;
Uint16 mode=0;
/* Extract the mode of the device - SPI or native */
MMCSD_getResponse( mmcsdResponse );
if(mode == 0) { /* Native MMC/SD mode */
response = mmcsdResponse->response[6];
cardStatus->appSpecific = ( response&0xff );
cardStatus->ready = ( (response>> 8) & 1 );
cardStatus->currentState = (MMCSD_CARD_STATE) ( (response >> 9) & 0xf );
cardStatus->eraseReset = ( (response >> 13) & 1 );
cardStatus->eccDisabled = ( (response >> 14) & 1 );
cardStatus->wpEraseSkip = ( (response >> 15) & 1 );
cardStatus->errorFlags = mmcsdResponse->response[7];
}
return ( E_PASS );
}
/**
\brief Read the CID information from the Response Registers of MMC/SD controller
\param mmcsdResponse Command Response is received in this parameter
\param cardCID card CID is filled into this buffer which must be an array of 8 (total - 128 bits)
\return if success, \c E_PASS, else error code
\see MMCSD_ResponseData
*/
STATUS MMCSD_getCardCID( MMCSD_ResponseData *mmcsdResponse, Uint16 *cardCID )
{
int i=0;
Uint16 mode=0;
/* Check whether the mode of operation is native MMC/SD or SPI */
// mode = MMCSD_FGET(MMCCTL, SPIEN);
MMCSD_getResponse( mmcsdResponse );
if(mode == 0) { /* Native mode */
/* Read response from the response register -- R2 response */
for( i=0; i<8; i++ ){
cardCID[i] = mmcsdResponse->response[i];
}
}else{
/* Read CID from the data lines -- just as in block read */
for(i=0; i<8; i++ ){
cardCID[i] =(Uint16) CSL_MMCSD_0_REGS->MMCDRR;
}
}
return ( E_PASS );
}
/**
\brief Read the CSD information from the Response Registers of MMC/SD controller
\param mmcsdResponse Command Response is received in this parameter
\param cardCSD card CSD is filled into this buffer which must be an array of 8 (total - 128 bits)
\param localCSDInfo CSD info, required by the driver, is received in this parameter
\return if success, \c E_PASS, else error code
\see MMCSD_ResponseData
*/
STATUS MMCSD_getCardCSD( MMCSD_ResponseData *mmcsdResponse, Uint16 *cardCSD, MMCSD_csdRegInfo *localCSDInfo )
{
int i=0;
Uint16 mode=0;
/* Check whether the mode of operation is native MMC/SD or SPI */
MMCSD_getResponse( mmcsdResponse );
if(mode == 0) { /* Native mode */
/* Read CSD from response R2 */
for( i=0; i<8; i++ ){
cardCSD[i] = mmcsdResponse->response[i];
}
}else{ /* SPI mode */
/* Read CSD from data receive register -- just as in a Block read */
for(i=0; i<8; i++ ){
//cardCSD[i] = MMCSD_RGET(MMCDRR);
cardCSD[i] =(Uint16) CSL_MMCSD_0_REGS->MMCDRR;
}
}
///< Fill the local structure with information required for other commands used in the driver
localCSDInfo->permWriteProtect = (cardCSD[0]>>13) & 0x1;
localCSDInfo->tmpWriteProtect = (cardCSD[0]>>12) & 0x1;
localCSDInfo->writeBlkPartial = (cardCSD[1]>>5) & 0x1;
localCSDInfo->writeBlkLenBytes = 1<<((cardCSD[1]>>6) & 0xF);
localCSDInfo->wpGrpEnable = (cardCSD[1]>>15) & 0x1;
localCSDInfo->wpGrpSize = (cardCSD[2] & 0x7F) + 1; ///> Extracting 7 bits: For MMC - 5 bits reqd; For SD - 7 bits reqd. (have to be taken care by user)
localCSDInfo->dsrImp = (cardCSD[4]>>12) &0x1;
localCSDInfo->readBlkMisalign = (cardCSD[4]>>13) &0x1;
localCSDInfo->writeBlkMisalign = (cardCSD[4]>>14) &0x1;
localCSDInfo->readBlkPartial = (cardCSD[4]>>15) & 0x1;
localCSDInfo->readBlkLenBytes = 1<<(cardCSD[5] & 0xF);
localCSDInfo->sysSpecVersion = (cardCSD[7]>>10) & 0xF; ///> These bits are reserved in the case of SD card
return ( E_PASS );
}
/**
\brief Read N words from the MMC Controller Register
\param data Buffer for storing read data from the MMC
\param numWords Number of words to be read from the MMC
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_readNWords( Uint32 *data, Uint32 numofBytes,Uint32 cardMemAddr,Bool dmaEnable )
{
register volatile Uint16 stat;
Uint16 error,ii=0,jj=0,status=0,fifoDxrRdCnt=0;
Uint32 fifoReadItrCount=0,extraBytes=0; /* Word counter */
Uint8 fifoBuff[32]={0};
Uint8 *fifoBuffPtr=(Uint8*)fifoBuff;
Uint16 fifoThrlevel =0;
/*Check the FIFO level to used. This is set in MMCSD_init */
fifoThrlevel = CSL_FEXT(CSL_MMCSD_0_REGS->MMCFIFOCTL,MMCSD_MMCFIFOCTL_FIFOLEV);
/* Check if the FIFO Threshold Level is default(16bytes),otherwise set it to 32Bytes*/
if(fifoThrlevel)
{
MMCSD_FIFOThreshold(MMCSD_FIFOLEVEL_32BYTES);
fifoReadItrCount=numofBytes/32;
extraBytes=numofBytes%32;
fifoDxrRdCnt=8;
if(extraBytes)
fifoReadItrCount=(numofBytes/32)+1;
else
fifoReadItrCount= numofBytes/32;
}
else
{
fifoReadItrCount=numofBytes/16;
extraBytes=numofBytes%16;
fifoDxrRdCnt=4;
if(extraBytes){
fifoReadItrCount=(numofBytes/16)+1;
}
else
fifoReadItrCount= numofBytes/16;
}
if(!dmaEnable) /*CPU USED FOR DATA TRANSFER */
{
#ifdef THROUGHPUT
/*Start the Timer */
// CSL_FINST(CSL_TMR_0_REGS->TCR, TMR_TCR_ENAMODE12, CONTINUOUS);
// CSL_FINST(CSL_TMR_0_REGS->TCR, TMR_TCR_ENAMODE34, CONTINUOUS);
#endif
for(ii=0; ii < fifoReadItrCount;ii++)
{
// while(MMCSD_CheckFIFOIsFull());
if(fifoThrlevel)
{
if(ii !=(fifoReadItrCount -1))
{
while(!(CSL_FEXT(CSL_MMCSD_0_REGS->MMCST0,MMCSD_MMCST0_DRRDY)));
}
}
else
{
if(ii < (fifoReadItrCount -2))
{
while(!(CSL_FEXT(CSL_MMCSD_0_REGS->MMCST0,MMCSD_MMCST0_DRRDY)));
}
}
for(jj=0;jj < fifoDxrRdCnt; jj++)
{
*data++ = CSL_MMCSD_0_REGS->MMCDRR;
}
if(extraBytes)
{
if(ii==(fifoReadItrCount-1))
{
for(jj=0;jj < fifoDxrRdCnt; jj++)
{
*fifoBuffPtr++ = CSL_MMCSD_0_REGS->MMCDRR;
}
}
memcpy((Uint8*)data,(Uint8*)fifoBuffPtr,extraBytes);
}
}
#ifdef THROUGHPUT
// CSL_FINST(CSL_TMR_0_REGS->TCR, TMR_TCR_ENAMODE12, DISABLED);
// CSL_FINST(CSL_TMR_0_REGS->TCR, TMR_TCR_ENAMODE34, DISABLED);
// rd_ticksA = (CSL_FEXTR(CSL_TMR_0_REGS->TIM12, 31,16) << 16) | CSL_FEXTR(CSL_TMR_0_REGS->TIM12, 15,0) ;
// rd_ticksB = (CSL_FEXTR(CSL_TMR_0_REGS->TIM34, 31,16) << 16) | CSL_FEXTR(CSL_TMR_0_REGS->TIM34, 15,0) ;
// *RD_TICKS= rd_ticksA;
// CSL_FINST(CSL_TMR_0_REGS->TGCR, TMR_TGCR_TIM12RS, IN_RESET);
// CSL_FINST(CSL_TMR_0_REGS->TGCR, TMR_TGCR_TIM34RS, IN_RESET);
#endif
}
return ( E_PASS );
}
/**
\brief Write N words to the MMC Controller Register
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -