📄 mmcsd.c
字号:
}
DeviceController.drive_active = (INT16)(DRV_ACTIVE);
/* Set it up. Select the base address */
RCA = DeviceController.drive.RCA;
starting_sector = sector;
/* Get the block length */
DeviceController.block_size = DeviceController.drive.block_size;
if ( (starting_sector+scount) > DeviceController.drive.total_lba )
{
DeviceController.error_code = MMC_ADDRESS_ERROR;
return (MMC_ADDRESS_ERROR);
}
ret_val = MMC_NO_ERROR;
/* Set up a counter for data transfer */
DeviceController.sectors_remaining = scount;
DeviceController.user_address = (USERADDRESS)buffer;
if (op == READING)
{
DeviceController.mode = READ_MODE;
if (scount > 1)
{
DeviceController.mode |= MULTIPLE_MODE;
ret_val = mmcReadMultiple(starting_sector,
RCA,
scount);
}
else
{
DeviceController.mode |= SINGLE_MODE;
ret_val = mmcRead(starting_sector,
RCA,
1);
}
if (ret_val != MMC_NO_ERROR )
{
DeviceController.error_code = (UINT16)ret_val;
return ret_val;
}
}
else if (op == WRITING)
{
DeviceController.mode = WRITE_MODE;
if (scount > 1)
{
DeviceController.mode |= MULTIPLE_MODE;
ret_val = mmcWriteMultiple(starting_sector,
RCA,
scount );
}
else
{
DeviceController.mode |= SINGLE_MODE;
ret_val = mmcWrite(starting_sector,
RCA,
1 );
}
/*
Wait for BUSY to go off before the next transfer. The
device may very well be programmed data into the flash memory.
*/
if ( ret_val ) /* If there is any READ/WRITE error, then return */
{
DeviceController.error_code = (UINT16)ret_val;
return ret_val;
}
}
else if ( op == ERASING )
{
ret_val = mmcEraseSectors(RCA,
starting_sector,
(starting_sector + (ULONG)(scount-1)),
0L );
if ( ret_val )
{
DeviceController.error_code = (UINT16)ret_val;
return (ret_val);
}
/* Get device status */
DeviceController.mmcRdyState = FALSE;
DeviceController.tempData = 0xFF;
while ( (DeviceController.mmcRdyState != TRUE) && (DeviceController.tempData > 0) )
{
/* Get the device status */
ret_val = mmcGetStatus( RCA );
if ( ret_val )
break;
if (DeviceController.tempData < 5)
Stallms(1);
DeviceController.tempData--;
}
}
DeviceController.error_code = (UINT16)ret_val;
return (ret_val);
}
/****************************************************************************************
* Name: mmedia_drive_open
*
* Description:
* Initialize a selected drive and set up data structure.
*
* Input:
*
* Output:
*
* Return:
* TRUE if successful
* FALSE if failure
*
*****************************************************************************************/
BOOL mmedia_drive_open ( void )
{
MMC_CC resErr;
SCRFields *pSCR;
SDSTATUSFields *pSDSTATUS;
ULONG ltemp;
BOOL retGood;
UINT16 heads;
UINT16 sectors;
UINT16 dTmp;
UINT16 buf[256];
retGood = FALSE;
DeviceController.drive_active = (INT16)(DRV_ACTIVE);
// Get device information
if ( MMC_NO_ERROR != mmcGetCardIdentification((UCHAR *)&buf[0], DeviceController.drive.RCA) )
{
goto DRIVE_OPEN_END;
}
// Get device configuration
if ( MMC_NO_ERROR != mmcGetConfiguration((UCHAR *)(&buf[0x20]), DeviceController.drive.RCA) )
{
goto DRIVE_OPEN_END;
}
resErr = mmcCommandAndResponse (((DeviceController.drive.RCA) << 16),
SELECT_DESELECT_CARD,
0,
R1 );
if(resErr != MMC_NO_ERROR)
{
goto DRIVE_OPEN_END;
}
// Get the current block length
heads = buf[0x20+2] >> 8;
dTmp = heads & 0x0F;
sectors = (UINT16)(1 << dTmp);
// Initialize default block length
DeviceController.block_size = DEFAULT_BLK_LEN;
if (sectors != DEFAULT_BLK_LEN)
{
/*
If the block length is not 512-byte block length, configure
it back to 512-byte block length.
*/
// Set the card with default block length
if ( mmcBlkLengthConfiguration(DeviceController.drive.RCA ) != MMC_NO_ERROR )
goto DRIVE_OPEN_END;
// The block length changed, get CSD again
if ( sectors != DEFAULT_BLK_LEN )
{
// Get device configuration again with new block length
if ( mmcGetConfiguration((UCHAR *)(buf+0x20), DeviceController.drive.RCA) != MMC_NO_ERROR )
goto DRIVE_OPEN_END;
}
}
// Get Device Size bits [73:62]
dTmp = (UINT16)buf[0x20+3];
sectors = (dTmp >> 8);
dTmp <<= 8;
dTmp |= sectors;
ltemp = ((ULONG)dTmp & 0x3FFL);
dTmp = (UINT16)buf[0x20+4];
sectors = (dTmp >> 8);
dTmp <<= 8;
dTmp |= sectors;
dTmp >>= 14;
ltemp <<= 2;
ltemp += (((ULONG)dTmp & 3L) + 1L);
heads = (((UINT16)buf[0x20+4]) >> 8);
sectors = (((UINT16)buf[0x20+5]) >> 7);
heads &= 3;
dTmp = ((heads << 1) + (sectors & 0x1));
// Total device capacity
ltemp <<= (dTmp + 2);
// Set up cylinders, heads and sectors
heads = 2; // Number of heads
if ( ltemp > 0xFFFF ) // 32 MB in size
heads = 4;
if ( ltemp > 0x1FFFF ) // 64 MB in size
heads = 8;
sectors = 32; // Number of sectors per track
DeviceController.drive.total_lba = ltemp;
ltemp = ltemp / (ULONG)(heads * sectors);
DeviceController.drive.num_cylinders = (UINT16)ltemp;
// Initialize the block size for each device
DeviceController.drive.block_size = DeviceController.block_size;
// Our view of the drive for block to track::sector::head xlations
DeviceController.drive.num_heads = heads;
DeviceController.drive.sec_p_track = sectors;
retGood = TRUE;
heads = dTmp; // Save the cSize multiplier
DeviceController.drive.securityDrv = FALSE;
DeviceController.drive.busWidth = SINGLE_BUS_WIDTH;
// Only apply to SD card
if (DeviceController.drive.card_type == SD_TYPE)
{
retGood = FALSE;
// Get SD configuration information ACMD51
if (MMC_NO_ERROR != mmcSDApplCmd((UCHAR *)buf, 0L, 0, DeviceController.drive.RCA, R1, SD_SEND_SCR))
goto DRIVE_OPEN_END;
pSCR = (SCRFields *)(buf);
DeviceController.drive.securityDrv = (UINT16)(pSCR->sd_security);
DeviceController.drive.busWidth = (UINT16)(pSCR->sd_bwidth);
dTmp = SINGLE_BUS_WIDTH;
// Set the bus width
if (MMC_NO_ERROR != mmcSDApplCmd((UCHAR *)buf, 0L, 0, DeviceController.drive.RCA, R1, SD_STATUS))
goto DRIVE_OPEN_END;
pSDSTATUS = (SDSTATUSFields *)(buf);
// Check the bus width. It should be 1-bit bus
sectors = (UINT16)(1 << ((UINT16)pSDSTATUS->sd_bwidth));
if (sectors != dTmp)
{
// The bus width does not match
goto DRIVE_OPEN_END;
}
// Get the capacity of the protected area
dTmp = (UINT16)pSDSTATUS->prt_size1;
sectors = dTmp >> 8;
dTmp <<= 8;
dTmp |= sectors;
ltemp = (0xFFFFL & (ULONG)dTmp);
ltemp <<= 16;
dTmp = (UINT16)pSDSTATUS->prt_size2;
sectors = dTmp >> 8;
dTmp <<= 8;
dTmp |= sectors;
ltemp |= (0xFFFFL & (ULONG)dTmp);
ltemp <<= (heads + 2);
DeviceController.drive.securedAreaSize = ltemp;
retGood = TRUE;
}
DRIVE_OPEN_END:
DeviceController.drive_active = -1;
return (retGood);
}
/****************************************************************************************
* Name: mmedia_drive_close
*
* Description:
* Remove all related information to the selected device.
*
* Input:
*
* Output:
*
* Return:
* TRUE if successful
* FALSE if failure
*
*****************************************************************************************/
BOOL mmedia_drive_close ( void )
{
DeviceController.drive.block_size = 0;
DeviceController.drive.total_lba = 0L;
return (TRUE);
}
#define BASE_10 10
/***************************************************************************************
* Name: number_to_ascii
*
* Description:
* Convert unsigned long number to ASCII string
* Inputs:
* UCHAR *asciiStrNum - card serial number
* UCHAR *buf - Serial number in binary
*
* Outputs:
* asciiStrNum contains serial number in ASCII
*
* Returns:
* Number of ASCII in the string
*
****************************************************************************************/
static UINT16 number_to_ASCII_Str(UCHAR *asciiStrNum, UCHAR *buf, UINT16 sLen)
{
ULONG serialNum;
UINT16 remainder;
UINT16 index;
UINT16 ind;
UCHAR arrayIndex;
UCHAR tailIndex;
UCHAR tmpChar;
serialNum = 0L;
for (index = 0; index < sLen; index++)
{
serialNum <<= 8;
serialNum |= (ULONG)buf[index];
}
index = 0;
do
{
remainder = (UINT16)(serialNum % BASE_10);
asciiStrNum[index++] = (UCHAR)(remainder+0x30);
serialNum /= (ULONG)BASE_10;
} while (serialNum);
asciiStrNum[index] = 0;
tailIndex = (UCHAR)(index - 1);
arrayIndex = (UCHAR)(index >> 1);
for (ind = 0; ind < arrayIndex; ind++, tailIndex--)
{
tmpChar = asciiStrNum[ind];
asciiStrNum[ind] = asciiStrNum[tailIndex];
asciiStrNum[tailIndex] = tmpChar;
}
return (index);
}
/***************************************************************************************
* Name: mmedia_read_serial
*
* Description:
* This routine does the following operations:
* . calls card identify to get serial no
* . copies the string into the output string and null terminate
*
* Inputs:
* pserialno - pointer to a buffer to hold the model number (at least 21 bytes)
*
* Returns:
* TRUE on success else FALSE.
* If FALSE, DeviceController.error_no will contain the error.
*
****************************************************************************************/
BOOL mmedia_read_serial(PDRV_GEOMETRY_DESC idDrvPtr)
{
UINT16 count;
UCHAR buf[128];
// Set it up. Select the base address
DeviceController.drive_active = (UINT16)DRV_ACTIVE;
// Get card CID
if ( mmcGetCardIdentification(buf, DeviceController.drive.RCA) != MMC_NO_ERROR )
return (FALSE);
// Get the physical geometry of the card
idDrvPtr->dfltHd = (UCHAR)DeviceController.drive.num_heads;
idDrvPtr->dfltSct = (UCHAR)DeviceController.drive.sec_p_track;
idDrvPtr->dfltCyl = (UINT16)DeviceController.drive.num_cylinders;
idDrvPtr->totalLBA = (UINT32)DeviceController.drive.total_lba;
count = 3;
// Is it an SD card?
if (DeviceController.drive.card_type == SD_TYPE)
{
count = 4;
}
count = number_to_ASCII_Str(((UCHAR *)buf + 32), ((UCHAR *)buf + 11), count);
memcpy(idDrvPtr->serialNum, ((UCHAR *)buf + 32), count);
idDrvPtr->serialNum[count] = 0;
for (count = 0; count < 7; count++)
buf[count] = buf[count+3];
memcpy(idDrvPtr->modelNum, ((UCHAR *)buf), 8);
idDrvPtr->modelNum[7] = 0;
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -