📄 mmcdrv.c
字号:
pc->currentState = (UINT16)(respBuff[3] & 0x1F);
pc->mmcStatus = statusInfo;
pc->mmcRdyState = pc->currentState & 01;
pc->currentState >>= 1;
/* Check status for error. Convert RAW status to driver error code */
if (statusInfo == 0)
return MMC_NO_ERROR;
if (statusInfo & OUT_OF_RANGE_ERROR)
return MMC_OUT_OF_RANGE;
if (statusInfo & ADDRESS_ERROR)
return MMC_ADDRESS_ERROR;
if (statusInfo & BLK_LENGTH_ERROR)
return MMC_DATA_LENGTH_ERROR;
if (statusInfo & ERASE_SEQ_ERROR)
return MMC_ERASE_SEQ_ERROR;
if (statusInfo & ERASE_PARAM)
return MMC_ERASE_PARAM;
if (statusInfo & WP_VIOLATION)
return MMC_WP_VIOLATION;
if (statusInfo & CMD_CRC_ERROR)
return MMC_CMD_CRC_ERROR;
if (statusInfo & COMUNC_ILLEG_COM)
return MMC_COMUNC_ILLEG_COM;
if (statusInfo & CARD_ECC_FAILED)
return MMC_CARD_ECC_FAILED;
if (statusInfo & CONTROLLER_ERROR)
return MMC_INTERFACE_ERROR;
if (statusInfo & EERROR)
return MMC_ERROR;
if (statusInfo & UNDERRUN)
return MMC_UNDERRUN;
if (statusInfo & OVERRUN)
return MMC_OVERRUN;
if (statusInfo & CIDCSD_OVERWRITE)
return MMC_CIDCSD_OVERWRITE;
if (statusInfo & WP_ERASE_SKIP)
return MMC_WP_ERASE_SKIP;
if (statusInfo & CARD_ECC_DISABLED)
return MMC_CARD_ECC_DISABLED;
if (statusInfo & ERASE_RESET)
return MMC_ERASE_RESET;
#if (USE_SD)
if (statusInfo & CARD_IS_LOCKED)
return MMC_CARD_IS_LOCKED;
if (statusInfo & LOCK_UNLOCK_FAILED)
return MMC_LOCK_UNLOCK_FAILED;
#endif
return MMC_CARD_IS_NOT_RESPONDING;
}
/***************************************************************************
* Name: MMCCommandAndResponse - Send the command to the MMC card
*
* Description:
* Send the command to the MMC card
*
* Input:
* pc Device information structure
* Cmd MMC Command
* Arg MMC Argument
* noBlocks Number of blocks to transfer
* Resp Response Type
*
* Output:
* Command is sent and Response is analyzed
*
* Return:
* MMC Completion Code
*
***************************************************************************/
MMC_CC mmcCommandAndResponse(PDEVICE_CONTROLLER pc, UINT32 Arg, UINT16 Cmd, UINT16 noBlocks, RESP_TYPE Resp )
{
MMC_CC resErr =0;
INT16 i;
// RETAILMSG(1, (TEXT("Inside Command&Resp stat is %x\r\n"),v_pMMCReg->stat));
/* Check for stop transmission command to set approriated flag */
if ( Cmd == STOP_TRANSMISSION)
{
if ( (pc->mode & READ_MODE) == READ_MODE )
multipleRdWr = DATA; /* For read */
else if ( (pc->mode & WRITE_MODE) == WRITE_MODE )
multipleRdWr = RCV; /* For write */
else
multipleRdWr = NO;
}
// RETAILMSG(1, (TEXT("insdie Com&Resp after stop trans stat is %x\r\n"),v_pMMCReg->stat));
/* Setup the command */
if ( Resp == R6 )
{
// RETAILMSG(1, (TEXT("in R6 Arg=%x Cmd=%x noBlocks=%x, stat is %x\r\n"),Arg,Cmd,noBlocks,v_pMMCReg->stat));
if ( !MMCPrepareAndSetup(Arg, Cmd, noBlocks, R1) )
return MMC_INTERFACE_ERROR;
}
else
{
// RETAILMSG(1, (TEXT("else Arg=%x Cmd=%x noBlocks=%x, stat is %x\r\n"),Arg,Cmd,noBlocks,v_pMMCReg->stat));
if ( !MMCPrepareAndSetup(Arg, Cmd, noBlocks, (UINT16)Resp) )
return MMC_INTERFACE_ERROR;
}
// RETAILMSG(1, (TEXT("inside Com&Resp after resp stat is %x\r\n"),v_pMMCReg->stat));
if ( !Resp ) /* Command without response (R0) */
return MMC_NO_ERROR;
for (i = 0; i < (CID_BYTE_LENGTH>>1); i++)
pc->LastResponse[i] = 0;/* Clear buffer */
/* Check the response */
resErr = MMCReceivedResponse( pc, Resp );
if ( resErr == MMC_NO_ERROR)
{
if ( (Resp == R1) || (Resp == R6) )
resErr = MMCAnalysisResponse(pc, Resp);
}
// RETAILMSG(1, (TEXT("mmcCommandAndResponse, resErr is %x\r\n"), resErr));
return resErr;
}
SDLOCAL SDBOOL getDeviceStatus(INT16 driveno, INT16 dFlag);
/*******************************************************************************
* Name: IsCardBusy
*
* Description:
* Check for READY/BUSY state of the device
*
* Input:
* INT16 driveno Drive number
*
* Output:
* None
*
* Returns:
* YES if the device is busy
* NO otherwise
*
********************************************************************************/
MMC_CC IsCardBusy(INT16 driveno)
{
/* Check for the card READY/BUSY */
return (getDeviceStatus(driveno, 1));
}
/*******************************************************************************
* Name: is_device_changed
*
* Description:
* Check for device removal and insertion
*
* Input:
* INT16 driveno Drive number
*
* Output:
* None
*
* Returns:
* YES if the device is removed or inserted back.
* NO otherwise
*
********************************************************************************/
SDBOOL is_device_changed (INT16 driveno) /*__fn__*/
{
return (getDeviceStatus(driveno, 0));
}
SDLOCAL SDBOOL getDeviceStatus(INT16 driveno, INT16 dFlag) /* __fn__ */
{
PDEVICE_CONTROLLER pc;
UINT16 phys_drive;
#if (N_INTERFACES > 1)
pc = drno_to_controller(driveno);
phys_drive = drno_to_phys(driveno);
#else
phys_drive = driveno;
pc = &controller_s[0];
#endif
MMCSelectController(pc->controller_number, phys_drive);
pc->drive_active = (((UINT16)phys_drive) | DRV_ACTIVE);
/* Get status information. */
if ( MMC_NO_ERROR != mmcGetStatus ( pc, pc->drive[phys_drive].RCA) )
{
return (YES);
}
if ( dFlag ) /* For Card Ready/Busy state */
{
/* READY/BUSY of the device */
if ( pc->mmcRdyState == YES )
return NO;
else
/* Card is busy */
return YES;
}
/* The device has not changed */
return NO;
}
#if (USE_MMC)
/***************************************************************************
* Name: setupMMcHostDataRegister - Configure MMC info. for MMC controller
*
* Description:
* Set up the information to configure the MMC controller
*
* Input:
* cmdIndex Command index
* cmdDatContReg Control information of CMD_DAT_CON_REG
* noBlocks Number of blocks to transfer
* blkLength Block data length
*
* Output:
* None
*
* Return:
* None
*
***************************************************************************/
SDVOID setupMMcHostDataRegister(UINT16 cmdIndex, UINT16 *cmdDatContReg, UINT16 *noBlocks, UINT16 *blkLength)
{
#if (USE_SECURITY)
if ( cmdIndex & SECURITY_CMD_BIT )
{
SETUPSPECIALCOMMANDS(cmdIndex, cmdDatContReg, noBlocks, blkLength);
return;
}
#endif
/* For normal driver */
switch ( cmdIndex )
{
case READ_BLOCK: /* DATA TRANSFER */
case READ_MULTIPLE_BLOCK: /* DATA TRANSFER */
case READ_DAT_UNTIL_STOP: /* STREAM READ */
*cmdDatContReg = DATA_ENABLE;
*blkLength = DEFAULT_BLK_LENGTH;
break;
case WRITE_BLOCK: /* DATA TRANSFER */
case WRITE_MULTIPLE_BLOCK: /* DATA TRANSFER */
case WRITE_DAT_UNTIL_STOP: /* STREAM WRITE */
*cmdDatContReg = (DATA_ENABLE + DATA_WRITE_SET);
/* *cmdDatContReg |= BUSY_SET; */
*blkLength = DEFAULT_BLK_LENGTH;
break;
case SEND_WRITE_PROT:
*cmdDatContReg = DATA_ENABLE;
*blkLength = NO;
break;
#if (USE_SD)
case SD_STATUS:
*cmdDatContReg = DATA_ENABLE;
*blkLength = (DEFAULT_BLK_LENGTH >> 3);
*noBlocks = 1;
break;
case SD_SEND_SCR:
*cmdDatContReg = DATA_ENABLE;
*blkLength = 8;
*noBlocks = 1;
break;
#endif
case PROGRAM_CSD:
case PROGRAM_CID:
*cmdDatContReg = (DATA_ENABLE + DATA_WRITE_SET);
*blkLength = 16;
*noBlocks = 1;
break;
case ERASE_SECTORS:
*cmdDatContReg = NO;
*blkLength = NO;
break;
case STOP_TRANSMISSION:
if ( multipleRdWr == RCV) /* For write */
/* *cmdDatContReg = (BUSY_SET | DATA_WRITE_SET); */
/* If BUSY_SET and one sector write using MultipleWrite the host will write two
sectors, one correct and one dummy */
/* *cmdDatContReg = (BUSY_SET); */
*cmdDatContReg = NO;
else /* For read */
*cmdDatContReg = NO;
*blkLength = NO;
break;
/* NO DATA TRANSFER */
case GO_IDLE_STATE:
case SEND_OP_COND:
case ALL_SEND_CID:
case SEND_CID:
case SEND_CSD:
case SEND_STATUS:
*cmdDatContReg = NO;
*blkLength = NO;
*noBlocks = NO;
break;
} /* END SWITCH */
}
#endif /* USE_MMC */
#endif /* (USE_MMC || USE_MMC_EMULATION) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -