📄 mmcfs.c
字号:
// // Send the CRC16 to the MMC card. // MMCWriteByte((ulData & 0x0000ff00) >> 8); MMCWriteByte(ulData & 0x000000ff); // // Send a single one bit the MMC card. // pulPtr[MMC_DAT_PORT >> 2] |= MMC_DAT_BIT; MMCClock(1); // // Configure the data line as an input. // MMCDatInput; // // Wait for the start of the CRC status. // while((pulPtr[MMC_DAT_PORT >> 2] & MMC_DAT_BIT) != 0) { // // Clock the MMC bus. // MMCClock(1); } // // Loop through the four bits of the CRC status. // for(ulLoop = 0, ulData = 0; ulLoop < 4; ulLoop++) { // // Clock the MMC bus. // MMCClock(1); // // See if the data line is high. // if((pulPtr[MMC_DAT_PORT >> 2] & MMC_DAT_BIT) != 0) { ulData |= 0x08 >> ulLoop; } } // // Continue to clock the MMC bus until the data line goes high. // MMCClock(1); while((pulPtr[MMC_DAT_PORT >> 2] & MMC_DAT_BIT) == 0) { MMCClock(100); } // // Check the CRC status. // if(ulData != 0x05) { // // The CRC status was bad, so return a failure. // return(0); } // // Advance to the next page. // ulStart++; // // Skip to the next portion of the data buffer. // pulBuffer += 128; } // // Success. // return(1);}//****************************************************************************//// MMCGetCapacity determines the capacity of the MMC card.////****************************************************************************unsigned longMMCGetCapacity(void){ volatile unsigned long *pulPtr = (unsigned long *)HwBaseAddress; unsigned long ulLength, ulSize, ulSizeMult; unsigned char ucRes[18]; // // Configure the data line as an output. // MMCDatOutput; // // Deselect all the cards. // MMCSendCommand(SELECT_CARD, 0x00000000); // // Read back the response. // MMCReadResponse(ucRes, 6); // // Clock the MMC bus. // MMCClock(8); // // Tell the MMC card that we want to read it's card specific data (CSD) // register. // MMCSendCommand(SEND_CSD, (sMMC.usCurrent == 0) ? 0x00010000 : 0x00020000); // // Read back the CSD. // ulSize = MMCReadResponse(ucRes, 17); // // Clock the MMC bus. // MMCClock(8); // // Reselect the current card. // MMCSendCommand(SELECT_CARD, (sMMC.usCurrent == 0) ? 0x00010000 : 0x00020000); // // Read back the response. // MMCReadResponse(ucRes, 6); // // Clock the MMC bus. // MMCClock(8); // // Make sure that the MMC card sent its CSD register. // if(ulSize == 0) { // // The MMC card did not send its CSD register, so return the capacity // as zero. // return(0); } // // Extract the read block length field from the CSD. // ulLength = 1 << (ucRes[6] & 0x0F); // // Extract the device size field from the CSD. // ulSize = (((ucRes[7] & 0x03) << 10) + (ucRes[8] << 2) + ((ucRes[9] & 0xc0) >> 6) + 1); // // Extract the device size multiplier field from the CSD. // ulSizeMult = 4 << (((ucRes[10] & 0x3) << 1) | ((ucRes[11] & 0x80) >> 7)); // // Return the capacity of this device. // return(ulLength * ulSize * ulSizeMult);}//****************************************************************************//// The block driver for the MMC card.////****************************************************************************unsigned longMMCBlockIoctl(void *pvState, unsigned char *pucScratch, unsigned long ulIoctl, unsigned long ulParam1, unsigned long ulParam2, unsigned long ulParam3){ // // Determine what to do based on the requested IOCTL. // switch(ulIoctl) { // // Initialize the block driver. // case IOCTL_BLOCK_INIT: { // // There is nothing to be done, so return success. // return(1); } // // Return the media unique ID. // case IOCTL_BLOCK_GETMEDIAID: { // // MMC cards do not support a media unique ID, so return a // failure. // return(0); } // // Read a block (or blocks) from the media. // case IOCTL_BLOCK_READ: { // // Read from the MMC card. // return(MMCRead(ulParam1, ulParam2, (unsigned long *)ulParam3, 0)); } // // Read a block (or blocks) from the media with byte swapping. // case IOCTL_BLOCK_READ_BS: { // // Read from the MMC card. // return(MMCRead(ulParam1, ulParam2, (unsigned long *)ulParam3, 1)); } // // Write a block (or blocks) to the media. // case IOCTL_BLOCK_WRITE: { // // Write to the MMC card. // return(MMCWrite(ulParam1, ulParam2, (unsigned long *)ulParam3)); } // // Return the capacity of the media. // case IOCTL_BLOCK_CAPACITY: { // // Not used at this point. The assumption is made that FAT // formatted MMC cards are being used. // return(MMCGetCapacity()); } // // Format the media. // case IOCTL_BLOCK_FORMAT: { // // We do not need to block format a MMC card, so return success. // return(1); } // // We should never get here, but just in case... // default: { // // Return a failure. // return(0); } }}//****************************************************************************//// The file system IOCTL entry point for the first MMC card.////****************************************************************************unsigned longMMCIoctl1(unsigned char *pucScratch, unsigned char *pucWriteBuffer, unsigned long ulIoctl, unsigned long ulInstance, unsigned long ulParam1, unsigned long ulParam2){ // // If we are being initialized, then we need to setup our global variables. // if(ulIoctl == IOCTL_FS_INIT) { // // Set the address of the block driver to be used by the FAT layer. // sMMC.sFAT1.pfnBlockDriver = MMCBlockIoctl; sMMC.sFAT1.pvBlockDriverState = 0; // // Initialize the MMC cards. // if(MMCInit() == 0) { return(0); } // // Select the first MMC card. // MMCSelectCardOne(); // // The first card is the currently selected card. // sMMC.usCurrent = 0; } // // If the name of the media is being requested, then return it. // if(ulIoctl == IOCTL_FS_GETMEDIANAME) { // // Return the name of the drive. // memcpy((void *)ulParam1, pusDriveName1, sizeof(pusDriveName1)); // // Return the length of the drive name. // *((unsigned long *)ulParam2) = sizeof(pusDriveName1); // // Success. // return(1); } // // See if there are any MMC cards. // if(sMMC.usNumCards == 0) { // // There are no cards, so return a failure. // return(0); } // // See if the first card is the one currently selected. // if(sMMC.usCurrent != 0) { // // The second card is currently selected, so select the first card. // MMCSelectCardOne(); // // The first card is the currently selected card. // sMMC.usCurrent = 0; } // // Call the FAT code. // return(FATIoctl(&sMMC.sFAT1, pucScratch, pucWriteBuffer, ulIoctl, ulInstance, ulParam1, ulParam2));}//****************************************************************************//// The file system IOCTL entry point for the second MMC card.////****************************************************************************unsigned longMMCIoctl2(unsigned char *pucScratch, unsigned char *pucWriteBuffer, unsigned long ulIoctl, unsigned long ulInstance, unsigned long ulParam1, unsigned long ulParam2){ // // If we are being initialized, then we need to setup our global variables. // if(ulIoctl == IOCTL_FS_INIT) { // // Set the address of the block driver to be used by the FAT layer. // sMMC.sFAT2.pfnBlockDriver = MMCBlockIoctl; sMMC.sFAT2.pvBlockDriverState = 0; } // // If the name of the media is being requested, then return it. // if(ulIoctl == IOCTL_FS_GETMEDIANAME) { // // Return the name of the drive. // memcpy((void *)ulParam1, pusDriveName2, sizeof(pusDriveName2)); // // Return the length of the drive name. // *((unsigned long *)ulParam2) = sizeof(pusDriveName2); // // Success. // return(1); } // // See if there are two MMC cards. // if(sMMC.usNumCards < 2) { // // There are not two MMC cards, so return a failure. // return(0); } // // See if the second cards is the one currently selected. // if(sMMC.usCurrent != 1) { // // The first card is currently selected, so select the second card. // MMCSelectCardTwo(); // // The second card is the currently selected card. // sMMC.usCurrent = 1; } // // Call the FAT code. // return(FATIoctl(&sMMC.sFAT2, pucScratch, pucWriteBuffer, ulIoctl, ulInstance, ulParam1, ulParam2));}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -