📄 mmcsd270.c
字号:
/*
DM270 ARM Evaluation Software
(c)Texas Instruments 2003
*/
/**
\file mmcsd270.c
\brief MMC/SD Related APIs
*/
#include <mmcsd270.h>
/**
\brief Set MMCSD Controller configuration
\param mmcsdConfig MMCSD Controller configuration paramters
\return if success, \c E_PASS, else error code
\see MMCSD_ConfigData
*/
STATUS MMCSD_setConfig(MMCSD_ConfigData * mmcsdConfig) {
Uint16 modebits, modemask;
/* Create a bit map of the values in the fields */
modebits = MMCSD_FMK(MMCCTL, PERMDX, mmcsdConfig->writeEndian) |
MMCSD_FMK(MMCCTL, PERMDR, mmcsdConfig->readEndian ) |
MMCSD_FMK(MMCCTL, DATED, mmcsdConfig->dat3Detect ) |
MMCSD_FMK(MMCCTL, WIDTH, mmcsdConfig->busWidth );
if(mmcsdConfig->spiModeEnable == TRUE)
modebits |= MMCSD_FMK(MMCCTL, SPIEN, 1);
else
modebits |= MMCSD_FMK(MMCCTL, SPIEN, 0);
if(mmcsdConfig->csEnable == TRUE)
modebits |= MMCSD_FMK(MMCCTL, CSEN, 1);
else
modebits |= MMCSD_FMK(MMCCTL, CSEN, 0);
if(mmcsdConfig->spiCrcErrCheckEnable == TRUE)
modebits |= MMCSD_FMK(MMCCTL, SPICRC, 1);
else
modebits |= MMCSD_FMK(MMCCTL, SPICRC, 0);
/* Create a bit mask for the selected fields */
modemask = MMCSD_FMK(MMCCTL, PERMDX, 0xFFFF) |
MMCSD_FMK(MMCCTL, PERMDR, 0xFFFF) |
MMCSD_FMK(MMCCTL, DATED, 0xFFFF) |
MMCSD_FMK(MMCCTL, WIDTH, 0xFFFF) |
MMCSD_FMK(MMCCTL, SPIEN, 0xFFFF) |
MMCSD_FMK(MMCCTL, CSEN, 0xFFFF) |
MMCSD_FMK(MMCCTL, SPICRC, 0xFFFF);
MMCSD_RAOI( MMCCTL, ~modemask, modebits, 0 );
MMCSD_FSET(MMCTOR, TOR, mmcsdConfig->timeoutResponse);
MMCSD_RSET(MMCTOD,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;
MMCSD_RSET(MMCIE,intMask);
return E_PASS;
}
/**
\brief Set Data size for MMC SD
\param numBlks Number of blocks for transfer, 0 for infinite number of blocks
\param blockSize Block size for MMC SD, value of 0 is not allowed
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_setDataSize(Uint16 numBlks, Uint16 blockSize) {
if(blockSize == 0)
return E_INVALID_INPUT;
MMCSD_FSET(MMCBLEN,BLEN,blockSize);
MMCSD_RSET(MMCNBLK,numBlks);
return E_PASS;
}
/**
\brief Set and Enable clock for MMCSD card
\param enable TRUE:Enable clock FALSE:Disable Clock
\param clockRate MMCSD Divisor for the function clock, MMC Clock = Function Clock/clockRate. \n MMCSD Function clock is set using CLKC_setMMCClockDivValue(), range: 2..512, must be even number
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_setClock(BOOL enable, Uint16 clockRate) {
MMCSD_FSET(MMCCLK, CLKRT, clockRate/2 - 1);
if(enable == TRUE)
MMCSD_FSET(MMCCLK, CLEN, 1);
else
MMCSD_FSET(MMCCLK, CLEN, 0);
return E_PASS;
}
/**
\brief Get Status of the MMCSD controller
Reads the values of the status registers into the parameters passed
\param status0 Contents of MMCST0 received is in this parameter
\param status1 Contents of MMCST1 received is in this parameter
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_getStatus(Uint16 * status0, Uint16* status1) {
*status0 = MMCSD_RGET(MMCST0);
*status1 = MMCSD_RGET(MMCST1);
return E_PASS;
}
/**
\brief Get Response from MMC SD controller
\param mmcsdResponse Response data 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] = MMCSD_RGET(MMCRSP0);
mmcsdResponse->response[1] = MMCSD_RGET(MMCRSP1);
mmcsdResponse->response[2] = MMCSD_RGET(MMCRSP2);
mmcsdResponse->response[3] = MMCSD_RGET(MMCRSP3);
mmcsdResponse->response[4] = MMCSD_RGET(MMCRSP4);
mmcsdResponse->response[5] = MMCSD_RGET(MMCRSP5);
mmcsdResponse->response[6] = MMCSD_RGET(MMCRSP6);
mmcsdResponse->response[7] = MMCSD_RGET(MMCRSP7);
mmcsdResponse->dataResponse = MMCSD_FGET(MMCDRSP,DRSP);
mmcsdResponse->errorToken = MMCSD_FGET(MMCETOK,ETOK);
mmcsdResponse->commandIdk = MMCSD_FGET(MMCCIDX,CIDX);
return E_PASS;
}
/**
\brief Set MMCSD Controller DMA configuration
\param dmaConfig MMC/SD DMA Controller configuration parameters
\return if success, \c E_PASS, else error code
\see MMCSD_DmaConfigData
\note SDRAM address should be 32 bit aligned
*/
STATUS MMCSD_setDmaConfig(MMCSD_DmaConfigData * dmaConfig) {
Uint32 addr;
addr = dmaConfig->sdramAddress - (Uint32)SDRAM_MEMORY_BASE;
if(addr % 4 != 0)
return E_INVALID_INPUT;
MMCSD_FSET(DMAMODE,DIR,dmaConfig->direction);
if(dmaConfig->direction == MMCSD_FROM_MMC)
{
if(dmaConfig->wordSwapEnable == TRUE)
MMCSD_FSET(DMAMODE,DPRMDR,1);
else
MMCSD_FSET(DMAMODE,DPRMDR,0);
}
else if(dmaConfig->direction == MMCSD_TO_MMC)
{
if(dmaConfig->wordSwapEnable == TRUE)
MMCSD_FSET(DMAMODE,DPRMDX,1);
else
MMCSD_FSET(DMAMODE,DPRMDX,0);
}
MMCSD_RSET(DMATOR, dmaConfig->timeoutValue);
if(dmaConfig->timeoutIntEnable == TRUE)
MMCSD_FSET(DMAMODE,DTOIE,1);
else
MMCSD_FSET(DMAMODE,DTOIE,0);
MMCSD_RSET(DMAAD0, addr);
MMCSD_FSET(DMAAD1, ADRH, addr >> 16);
return E_PASS;
}
/**
\brief Update the SDRAM address
\param sdramAddress SDRAM address to be updated, SDRAM address should be 32 bit aligned
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_updateDmaAddress(Uint32 sdramAddress) {
Uint32 addr;
addr = sdramAddress - (Uint32)SDRAM_MEMORY_BASE;
if(addr % 4 != 0)
return E_INVALID_INPUT;
MMCSD_RSET(DMAAD0, addr);
MMCSD_FSET(DMAAD1, ADRH, addr >> 16);
return E_PASS;
}
/**
\brief Start DMA transfer
\return if success, \c E_PASS, else error code
*/
STATUS MMCSD_dmaStart() {
MMCSD_FSET(DMATRG,TRG,1);
return E_PASS;
}
/**
\brief Stop DMA transfer
\return if success, \c E_PASS, else error code
\note This function returns just after breaking DMA transfer. Check using MMCSD_dmaWait() for the complete halt of DMA transfer
*/
STATUS MMCSD_dmaStop() {
MMCSD_FSET(DMATRG,BRK,1);
return E_PASS;
}
/**
\brief Wait for DMA transfer completion
\return if success, \c E_PASS, Does not return if DMA is still running
*/
STATUS MMCSD_dmaWait() {
while(MMCSD_FGET(DMASTAT1,RUNST) != 0);
return E_PASS;
}
/**
\brief Get the total number of bytes remaining in dma transfer
\return number of bytes remaining for transfer
*/
Uint32 MMCSD_getDmaCount() {
Uint32 remBytes = 0x0;
remBytes = MMCSD_FGET(DMASTAT1,REMH);
remBytes = remBytes << 16;
remBytes |= MMCSD_RGET(DMASTAT0);
return remBytes;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -