static unsigned int HSMMCSDCmdStatusGet(mmcsdCtrlInfo *ctrl) { unsigned int status = 0; while ((cmdCompFlag == 0) && (cmdTimeout == 0)) { status = HSMMCSDStatusGet(); } if (cmdCompFlag) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_CMDCOMP); status = 1; cmdCompFlag = 0; } if (cmdTimeout) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_CMDTIMEOUT); status = 0; cmdTimeout = 0; } return status; }
static void HSMMCSDIsr(void) { volatile unsigned int status = 0; status = HSMMCSDIntrStatusGet(ctrlInfo.memBase, 0xFFFFFFFF); HSMMCSDIntrStatusClear(ctrlInfo.memBase, status); if (status & HS_MMCSD_STAT_CMDCOMP) { cmdCompFlag = 1; } if (status & HS_MMCSD_STAT_ERR) { errFlag = status & 0xFFFF0000; if (status & HS_MMCSD_STAT_CMDTIMEOUT) { cmdTimeout = 1; } if (status & HS_MMCSD_STAT_DATATIMEOUT) { dataTimeout = 1; } } if (status & HS_MMCSD_STAT_TRNFCOMP) { xferCompFlag = 1; } }
static void HSMMCSDXferSetup(mmcsdCtrlInfo *ctrl, unsigned char rwFlag, void *ptr,unsigned int blkSize, unsigned int nBlks) { HSMMCSDIntrStatusClear(ctrl->memBase, HS_MMCSD_INTR_TRNFCOMP); if (rwFlag == 1) { HSMMCSDIntrStatusClear(ctrl->memBase, HS_MMCSD_INTR_BUFRDRDY); HSMMCSDIntrStatusEnable(ctrl->memBase, HS_MMCSD_INTR_BUFRDRDY); HSMMCSDIntrStatusDisable(ctrl->memBase, HS_MMCSD_INTR_BUFWRRDY); } else { HSMMCSDIntrStatusClear(ctrl->memBase, HS_MMCSD_INTR_BUFWRRDY); HSMMCSDIntrStatusEnable(ctrl->memBase, HS_MMCSD_INTR_BUFWRRDY); HSMMCSDIntrStatusDisable(ctrl->memBase, HS_MMCSD_INTR_BUFRDRDY); } HSMMCSDBlkLenSet(ctrl->memBase, blkSize); hsmmcsd_dataLen = (nBlks * blkSize); hsmmcsd_buffer = ptr; xferPend = 1; }
/** *\brief This function gets the Xfer status.\n * * \param - ctrl - MMCSD controller info.\n * * \return Xfer status.\n * */ static unsigned int HSMMCSDXferStatusGet(mmcsdCtrlInfo *ctrl) { volatile unsigned int status = 0; volatile unsigned int temp; unsigned int i; while(1) { status = HSMMCSDStatusGet(); if (status & HS_MMCSD_STAT_BUFRDRDY) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_BUFRDRDY); if (hsmmcsd_buffer != NULL) { for (i = 0; i < hsmmcsd_dataLen; i+=4) { temp = HWREG(MMCSD_BASE + MMCHS_DATA); hsmmcsd_buffer[i] = *((char*)&temp); hsmmcsd_buffer[i+1] = *((char*)&temp + 1); hsmmcsd_buffer[i+2] = *((char*)&temp + 2); hsmmcsd_buffer[i+3] = *((char*)&temp + 3); } } } if (status & HS_MMCSD_STAT_BUFWRRDY) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_BUFRDRDY); if (hsmmcsd_buffer != NULL) { for (i = 0; i < hsmmcsd_dataLen; i+=4) { *((char*)&temp) = hsmmcsd_buffer[i]; *((char*)&temp + 1) = hsmmcsd_buffer[i+1]; *((char*)&temp + 2) = hsmmcsd_buffer[i+2]; *((char*)&temp + 3) = hsmmcsd_buffer[i+3]; HWREG(MMCSD_BASE + MMCHS_DATA) = temp; } } } if (status & HS_MMCSD_STAT_DATATIMEOUT) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_DATATIMEOUT); status = 0; xferPend = 0; break; } if (status & HS_MMCSD_STAT_TRNFCOMP) { HSMMCSDIntrStatusClear(ctrlInfo.memBase, HS_MMCSD_STAT_TRNFCOMP); status = 1; xferPend = 0; break; } } return status; }
/** * \brief This function sends the command to MMCSD. * * \param mmcsdCtrlInfo It holds the mmcsd control information. * * \param mmcsdCmd It determines the mmcsd cmd * * \return status of the command. * **/ unsigned int HSMMCSDCmdSend(mmcsdCtrlInfo *ctrl, mmcsdCmd *c) { unsigned int cmdType = HS_MMCSD_CMD_TYPE_NORMAL; unsigned int dataPresent; unsigned int status = 0; unsigned int rspType; unsigned int cmdDir; unsigned int nblks; unsigned int cmd; if (c->flags & SD_CMDRSP_STOP) { cmdType = HS_MMCSD_CMD_TYPE_SUSPEND; } else if (c->flags & SD_CMDRSP_FS) { cmdType = HS_MMCSD_CMD_TYPE_FUNCSEL; } else if (c->flags & SD_CMDRSP_ABORT) { cmdType = HS_MMCSD_CMD_TYPE_ABORT; } cmdDir = (c->flags & SD_CMDRSP_READ) ? \ HS_MMCSD_CMD_DIR_READ : HS_MMCSD_CMD_DIR_WRITE; dataPresent = (c->flags & SD_CMDRSP_DATA) ? 1 : 0; nblks = (dataPresent == 1) ? c->nblks : 0; if (c->flags & SD_CMDRSP_NONE) { rspType = HS_MMCSD_NO_RESPONSE; } else if (c->flags & SD_CMDRSP_136BITS) { rspType = HS_MMCSD_136BITS_RESPONSE; } else if (c->flags & SD_CMDRSP_BUSY) { rspType = HS_MMCSD_48BITS_BUSY_RESPONSE; } else { rspType = HS_MMCSD_48BITS_RESPONSE; } cmd = HS_MMCSD_CMD(c->idx, cmdType, rspType, cmdDir); if (dataPresent) { HSMMCSDIntrStatusClear(ctrl->memBase, HS_MMCSD_STAT_TRNFCOMP); HSMMCSDDataTimeoutSet(ctrl->memBase, HS_MMCSD_DATA_TIMEOUT(27)); } HSMMCSDCommandSend(ctrl->memBase, cmd, c->arg, (void*)dataPresent, nblks, ctrl->dmaEnable); if (ctrl->cmdStatusGet) { status = ctrl->cmdStatusGet(ctrl); } if (status == 1) { HSMMCSDResponseGet(ctrl->memBase, c->rsp); } return status; }