📄 mmcdrv.c
字号:
/*****************************************************************************
* FileName: MMCDRV.C
*
* SanDisk Host Developer's Toolkit
*
* Copyright (c) 1997 - 2000 SanDisk Corporation
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*
* Description:
* MMC driver
*
******************************************************************************/
#include "sdconfig.h"
#include <bvd1.h>
extern MMC_REGS *v_pMMCReg;
#if (USE_MMC || USE_MMC_EMULATION)
#include "sdmmc.h"
;
/***********************************************************************************
* Public Functions
* ----------------
************************************************************************************/
/***********************************************************************************
* Name: mmcBusStart
*
* Description:
* Starts the MMC bus by sending 80 clock cycles.
* Reset the MMC devices. Put them in IDLE mode and configure all
* devices with proper OCR and wait for ready.
*
* Input:
* INT16 controller_no Controller Number
*
* Output:
* None.
*
* Returns:
* None.
*
************************************************************************************/
SDBOOL mmcBusStart( INT16 ctrlNo )
{
/* Reset the MMC host controller */
// resetMMCController(ctrlNo);
/* IDENTIFICATION STATE process in OPEN-DRAIN mode. */
/* This process is operated at low clock rate 250KHz */
if ( !setMMCClockRate(6) )
{
// RETAILMSG(1, (TEXT("fail to set setMMCClockRate()\r\n")));
return NO;
}
/* Enable MMC interface in open drain mode and turn on the clock. */
startMMC80Clocks(ctrlNo);
return YES;
}
/*****************************************************************************
* Name: mmc_init_setup
*
* Description:
* Initialize MMC devices. The MMC controller is operated in
* OPEN-DRAIN mode.
* - 80 clocks
* - IDLE STATE
* - OPERATIING VOLTAGE CONDITION
*
* Input:
* None
*
* Output:
* All devices should be ready
*
* Returns:
* YES if successful
* NO if failure
*
*****************************************************************************/
SDBOOL mmc_init_setup(SDVOID) /*__fn__*/
{
PDEVICE_CONTROLLER pc;
INT16 ctrlNo;
INT16 nFailures;
nFailures = 0;
// RETAILMSG(1, (TEXT("mmc_init_setup() \r\n")));
/* This is a starting point in the IDENTIFICATION STATE process. */
/* Apply to all MMC controllers */
for (ctrlNo = 0; ctrlNo < N_INTERFACES; ctrlNo++)
{
// RETAILMSG(1, (TEXT("mmc_init_setup() enter loop %d\r\n"), ctrlNo));
pc = &controller_s[ctrlNo];
pc->controller_number = ctrlNo;
// Send 80 clocks to start the bus
if ( mmcBusStart(ctrlNo) ) // Put all device in idle mode
{
// RETAILMSG(1, (TEXT("mmcBusStart successful\r\n")));
// Reset all devices on the bus and wait for ready.
//Make sure all devices are READY.
//- IDLE STATE
//- OPERATIING VOLTAGE CONDITION
if ( MMC_NO_ERROR == mmcReset ( pc, 0x00020000 ) ) //made change here by Yi, actually, originally value is 0xFFC000
{
// Set max. clock rate
// RETAILMSG(1, (TEXT("mmcReset() no error \r\n")));
setMMCClockRate(0);
}
else
{
nFailures++;
}
}
pc->controller_number = -1;
}
if ( nFailures >= N_INTERFACES )
return NO;
// RETAILMSG(1, (TEXT("mmc_init_setup() end, return value is YES \r\n")));
return (YES);
}
/****************************************************************************
* Name: mmcConfigDevice
*
* Description:
* Configure MMC devices and assign device ID.
*
* Input:
* pc Device Controller structure
* driveno Drive Number
*
* Output:
* None.
*
* Returns:
* Complete code.
*
****************************************************************************/
MMC_CC mmcConfigDevice( INT16 driveno )
{
PDEVICE_CONTROLLER pc;
INT16 phys_drive;
/* THIS IS A INDENTIFICATION STATE phase */
#if (N_INTERFACES > 1)
pc = drno_to_controller(driveno);
phys_drive = drno_to_phys(driveno);
#else
pc = &controller_s[0];
phys_drive = driveno;
#endif
/* Allow all card to identify itself and Assign ID to the device. */
return (mmcIdentify( pc, pc->drive[phys_drive].drv_type, phys_drive ));
}
/****************************************************************************
* Name: receive_data
*
* Description:
* While monitoring the MMC bus for data start bit condition, waits for
* certain time before issue CARD NOT RESPONSE condition.
* The data is read and stored after the start bit is detected. MMC timeouts
* are observed and the received CRC number is validated.
*
* Input:
* buffDATA - pointer to the data buffer.
* length - Expected length of data block.
*
* Output:
* buffData[] - Received data.
*
* Returns:
* Completion code
*
****************************************************************************/
MMC_CC receive_data( PDEVICE_CONTROLLER pc, UINT16 dLength, UINT16 noBlocks, UINT16 xferMode )
{
/* Data is ready. Get it from the MMC BUFFER */
// RETAILMSG(1, (TEXT("receive_data is entered\r\n")));
return (MMCReceive((UCHAR *)pc->user_address, dLength, noBlocks, xferMode));
}
/****************************************************************************
* Name: send_data
*
* Description:
* Writes data block to the card.
*
* Input:
* pc Controller structure pointer.
* dataLength Length of data block.
*
* Output:
* Data are sent to the device.
*
* Returns:
* Completion code
*
****************************************************************************/
MMC_CC send_data( PDEVICE_CONTROLLER pc, UINT16 dLength, UINT16 noBlocks, UINT16 xferMode )
{
/* Write data to the device */
return (MMCTransmit((UCHAR *)pc->user_address, dLength, noBlocks, xferMode));
}
/*****************************************************************************
* Name: MMCReceivedResponse - Get the response from MMC card
*
* Description:
* Get the response from MMC card
*
* Input:
* pc Device information structure
* Resp Response Type
*
* Output:
*
* Return:
*
*****************************************************************************/
MMC_CC MMCReceivedResponse(PDEVICE_CONTROLLER pc, RESP_TYPE Resp)
{
UINT08 *respBuff;
UINT16 respLength;
if ( Resp == R0 )
return (MMC_NO_ERROR);
respLength = BYTE_LENGTH; /* 6 bytes R1, R3 or R6 response */
if ( Resp == R2 )
respLength = CID_BYTE_LENGTH -1;/* (17-1) bytes R2 response */
respBuff = (UINT08 *)pc->LastResponse;
/* Read status and wait for response. */
return (getMMCResponseInfo(respBuff, respLength, (UINT16)Resp));
}
/***************************************************************************
* Name: MMCAnalysisResponse - Analyze the MMC response
*
* Description:
* Analyze the response from MMC card and convert the RAW
* information to the known status
*
* Input:
* pc Device information structure
*
* Output:
* None
*
* Return:
* MMC completion code
*
***************************************************************************/
MMC_CC MMCAnalysisResponse( PDEVICE_CONTROLLER pc, RESP_TYPE respType )
{
UINT32 statusInfo;
UINT08 *respBuff;
UINT16 ij, tt;
respBuff = (UINT08 *)pc->LastResponse;
if (respType == R6)
{
ij = (UINT16)respBuff[1];
ij <<= 8;
ij |= (UINT16)respBuff[2];
pc->LastResponse[4] = ij;
#if (LITTLE_ENDIAN)
/* Clear bits 31-24 of Status register */
pc->LastResponse[0] &= 0x00FF;
/* Extract bits 23, 22 and clear bits 23-16 */
ij = (pc->LastResponse[1] & 0xC000);
/* Extract bit 19 */
tt = (pc->LastResponse[1] & 0x0800) << 2;
ij |= tt;
/* Pack bits 23,22 and 19 to bits 15-13 of Status register */
pc->LastResponse[1] = ij;
ij = pc->LastResponse[2] & 0x001F;
/* Extract bits 12-8 then pack to bits 12-8 */
pc->LastResponse[1] |= (ij << 8);
ij = pc->LastResponse[2] >> 8;
/* Extract bit 7-0 then pack to bit 7-0 */
pc->LastResponse[2] = ij;
#else
/* Clear bits 31-24 of Status register */
pc->LastResponse[0] &= 0xFF00;
/* Extract bits 23, 22 */
ij = pc->LastResponse[1] & 0x00C0;
/* Extract bit 19 */
tt = (pc->LastResponse[1] & 0x0008) << 2;
ij |= tt;
/* Pack bits 23,22 and 19 to bits 15-13 */
pc->LastResponse[1] = ij;
/* Extract bits 12-8 */
ij = (pc->LastResponse[2] >> 8) & 0x1F;
/* Pack to bits 12-8 of Status register */
pc->LastResponse[1] |= ij;
ij = pc->LastResponse[2] & 0x00FF;
/* Extract bit 7-0 then pack to bit 7-0 */
pc->LastResponse[2] = (ij << 8);
#endif
}
/* Get the RAW MMC status */
statusInfo = (UINT32)(respBuff[1] & 0xFF);
statusInfo <<= 8;
statusInfo |= (UINT32)(respBuff[2] & 0xFF);
statusInfo <<= 8;
statusInfo |= (UINT32)(respBuff[3] & 0xE0);
statusInfo <<= 8;
/* Get the MMC state */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -