mmcsd.c
来自「老外的一个开源项目」· C语言 代码 · 共 1,776 行 · 第 1/4 页
C
1,776 行
* Completion code
*
********************************************************************************/
MMC_CC mmcReadMultiple( ULONG dataAddress,
UINT16 RCA,
UINT16 noBlocks )
{
MMC_CC resErr;
UINT16 option;
/* Set the card to transfer state */
resErr = mmcSetXferState( RCA );
resErr = mmcCommandAndResponse ((dataAddress * (ULONG)DeviceController.block_size),
READ_MULTIPLE_BLOCK,
noBlocks,
R1 );
if ( resErr != MMC_NO_ERROR )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/* Get data */
option = (TRUE | 0xFF00); /* set SD user area or MMC card flag */
resErr = mmcReceiveData(DeviceController.block_size, noBlocks, option);
/* Stop receiving data */
mmcStopTransmission( RCA );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/* Get device status */
DeviceController.mmcRdyState = FALSE;
DeviceController.tempData = 0xFF;
while ( (DeviceController.mmcRdyState != TRUE) && (DeviceController.tempData > 0) )
{
/* Get the device status */
resErr = mmcGetStatus( RCA );
if ( resErr )
break;
DeviceController.tempData--;
}
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/***********************************************************************************
* Name: mmcWriteMultiple
*
* Description:
* Initiates a multiple block write operation.
*
* This function will (unless already selecetd) select
* an mmc card using the given RCA (CMD7) set the block
* length to a specified block length (CMD16) and
* starts the multiple write (CMD15).
*
* Input:
* dataAddress - Sector address
* bufPtr - Data to be written.
* RCA - card address
* |
* |
* Returns:
* Completion code
*
************************************************************************************/
MMC_CC mmcWriteMultiple( ULONG dataAddress,
UINT16 RCA,
UINT16 noBlocks )
{
MMC_CC resErr;
UINT16 option;
/* Set the card to transfer state */
resErr = mmcSetXferState( RCA );
resErr = mmcCommandAndResponse ((dataAddress * (ULONG)DeviceController.block_size),
WRITE_MULTIPLE_BLOCK,
noBlocks,
R1 );
if ( resErr != MMC_NO_ERROR )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/* Send data */
option = (TRUE | 0xFF00); /* set SD user area or MMC card flag */
resErr = mmcSendData( DeviceController.block_size, noBlocks, option );
/* Stop sending data */
mmcStopTransmission( RCA );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/* Get device status and check for READY state */
DeviceController.tempData = 0xFF;
DeviceController.mmcRdyState = FALSE;
while ( (DeviceController.mmcRdyState != TRUE) && (DeviceController.tempData > 0) )
{
/* Get the device status */
resErr = mmcGetStatus( RCA );
if ( resErr )
break;
DeviceController.tempData--;
Stallms(1);
}
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
/************************************************************************************
* Name: mmcEraseSectors
*
* Description:
* Erases a sector range on the card. The rane must be within
* a single erase group.
*
* Input:
* UINT16 RCA Card address.
* ULONG Start Adsress of first sector in the erase range.
* ULONG End Address of the last sector in the erase range.
* ULONG untag Adress of one sector in the range to skip (not erase)
*
* Output:
* None
*
* Returns:
* Completion code
*
************************************************************************************/
MMC_CC mmcEraseSectors (UINT16 RCA,
ULONG start,
ULONG end,
ULONG untag )
{
MMC_CC resErr;
/* Set the card to transfer state */
resErr = mmcSetXferState( RCA );
/* START */
resErr = mmcCommandAndResponse ((start << 9),
TAG_SECTOR_START,
0,
R1 );
if ( resErr == MMC_NO_ERROR )
{
/* END */
resErr = mmcCommandAndResponse ((end << 9),
TAG_SECTOR_END,
0,
R1 );
}
if ( resErr == MMC_NO_ERROR )
{
/* UNTAG */
if (untag)
{
resErr = mmcCommandAndResponse ((untag << 9),
UNTAG_SECTOR,
0,
R1 );
}
}
if ( resErr == MMC_NO_ERROR )
{
/* ERASE */
resErr = mmcCommandAndResponse ( 0L,
ERASE_SECTORS,
0,
R1 );
}
DeviceController.error_code = (UINT16)resErr;
return (resErr);
}
/***********************************************************************************
* Name: mmcEraseGroup
*
* Description:
* Erases an erase group range on the card.
*
* Input:
* RCA Card address.
* Start Adsress of first earse group in the erase range.
* End Address of the last erase group in the erase range.
* untag Adress of one earse group in the range to skip (not erase)
*
* Output:
* None.
*
* Returns:
* Completion code.
*
************************************************************************************/
MMC_CC mmcEraseGroup(UINT16 RCA,
ULONG start,
ULONG end,
ULONG untag )
{
MMC_CC resErr;
/* Set the card to transfer state */
resErr = mmcSetXferState( RCA );
/* START */
resErr = mmcCommandAndResponse ((start << 13),
TAG_ERASE_GROUP_START,
0,
R1 );
if ( resErr == MMC_NO_ERROR )
{
/* END */
resErr = mmcCommandAndResponse ((end << 13),
TAG_ERASE_GROUP_END,
0,
R1 );
}
if ( resErr == MMC_NO_ERROR )
{
/* UNTAG */
if(untag)
{
resErr = mmcCommandAndResponse ((untag << 13),
UNTAG_ERASE_GROUP,
0,
R1 );
}
}
if ( resErr == MMC_NO_ERROR )
{
/* ERASE */
resErr = mmcCommandAndResponse (0L,
ERASE_SECTORS,
0,
R1 );
}
DeviceController.error_code = (UINT16)resErr;
return (resErr);
}
/***********************************************************************************
* Name: mmcErase
*
* Description:
* Erases a sector range on the card.
*
* Input:
* UINT16 RCA Device address
* ULONG Start Adsress of first sector in the erase range.
* ULONG End Address of the last sector in the erase range.
*
* Output:
* None.
*
* Returns:
* Completion code.
*
************************************************************************************/
MMC_CC mmcErase(
UINT16 RCA,
ULONG start,
ULONG end )
{
ULONG numSectStartGR, numSectEndGR;
ULONG S_EraseGroup, E_EraseGroup;
MMC_CC resErr;
/* START PARAMETERS */
numSectStartGR = DEFAULT_ERASE_GROUP - (start % DEFAULT_ERASE_GROUP);
/* END PARAMETERS */
numSectEndGR = end % DEFAULT_ERASE_GROUP;
S_EraseGroup = start / DEFAULT_ERASE_GROUP;
E_EraseGroup = end / DEFAULT_ERASE_GROUP;
if ( (E_EraseGroup - S_EraseGroup) > 1 )
{
if (numSectStartGR)
{
S_EraseGroup += 1;
resErr = mmcEraseSectors(RCA,
start,
(start + numSectStartGR),
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
if (numSectEndGR)
{
E_EraseGroup -= 1;
resErr = mmcEraseSectors(RCA,
(end - numSectEndGR + 1),
end,
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
resErr = mmcEraseGroup(RCA,
S_EraseGroup,
E_EraseGroup,
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
else if ((E_EraseGroup - S_EraseGroup) < 1)
{
resErr = mmcEraseSectors(RCA,
start,
end,
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
else if ((E_EraseGroup - S_EraseGroup) == 1)
{
if ( numSectStartGR )
{
resErr = mmcEraseSectors(RCA,
start,
(start + numSectStartGR),
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
if (numSectEndGR)
{
resErr = mmcEraseSectors( RCA,
(end - numSectEndGR + 1),
end,
0 );
if ( resErr )
{
DeviceController.error_code = (UINT16)resErr;
return resErr;
}
}
}
DeviceController.error_code = MMC_NO_ERROR;
return (MMC_NO_ERROR);
}
/***********************************************************************************
* Name: mmcGetStatus
*
* Description:
* Retrieves the card current status.
*
* Input:
* UINT16 RCA Card address.
*
* Output:
* status A 32 bit status word. Error/status bits.
*
* Returns:
* Completion code
*
************************************************************************************/
MMC_CC mmcGetStatus (UINT16 RCA)
{
MMC_CC resErr;
resErr = mmcCommandAndResponse ((((ULONG)RCA) << 16),
SEND_STATUS,
0,
R1 );
DeviceController.error_code = (UINT16)resErr;
return (resErr);
}
/*********************************************************************************
* Name: mmedia_io
*
* Description:
* Read/write handler. Single and multiple READ/WRITE are supported.
*
* Input:
* ULONG sector
* UCHAR *buffer
* USHORT scount
* INT16 op
*
* Output:
*
* Return:
*
**********************************************************************************/
MMC_CC mmedia_io(ULONG sector, UCHAR *buffer, USHORT scount, INT16 op )
{
ULONG starting_sector;
MMC_CC ret_val;
UINT16 RCA;
if ( !scount ) /* Must have a count */
{
DeviceController.error_code = MMC_ADDRESS_ERROR;
return (MMC_ADDRESS_ERROR);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?