⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmcsd.c

📁 老外的一个开源项目
💻 C
📖 第 1 页 / 共 4 页
字号:
    }

    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 + -