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 + -
显示快捷键?