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

📄 sdmmc.c

📁 基于RM9200主芯片
💻 C
📖 第 1 页 / 共 5 页
字号:
{
    MMC_CC  resErr;

#if (USE_SPI || USE_SPI_EMULATION)
        selectChip( RCA );
#else   /* This is for MMC */
        /* Set the card to transfer state */
        resErr = mmcSetXferState( pc, RCA );
#endif

    /* START */             
    resErr = mmcCommandAndResponse ( pc,
                (start << 13),
                TAG_ERASE_GROUP_START, 
                0,
                R1 );
    if ( resErr == MMC_NO_ERROR )
    {
        /* END */
        resErr = mmcCommandAndResponse ( pc,
                (end << 13),
                TAG_ERASE_GROUP_END, 
                0,
                R1 );
    }
    if ( resErr == MMC_NO_ERROR )
    {
        /* UNTAG */
        if(untag)
        {
            resErr = mmcCommandAndResponse ( pc,
                    (untag << 13),
                    UNTAG_ERASE_GROUP, 
                    0,
                    R1 );
        }
    }

    if ( resErr == MMC_NO_ERROR )
    {
        /* ERASE */
        resErr = mmcCommandAndResponse ( pc,
                0L,
                ERASE_SECTORS, 
                0,
                R1 );
    }

#if (USE_SPI || USE_SPI_EMULATION)
    /* DeSelect the card */
        deSelectChip( RCA );
#endif

    pc->error_code = (UINT16)resErr;
    return (resErr);
}

/***********************************************************************************
* Name: mmcErase
*
* Description:
*       Erases a sector range on the card.
* 
* Input:
*       PDEVICE_CONTROLLER      pc
*       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( PDEVICE_CONTROLLER pc,
                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( pc,
                    RCA,
                    start, 
                    (start + numSectStartGR), 
                    0 );
            if ( resErr )
            {
                pc->error_code = (UINT16)resErr;
                return resErr;
            }
        }
        if (numSectEndGR)
        {
            E_EraseGroup -= 1;
            resErr = mmcEraseSectors( pc,
                    RCA,
                    (end - numSectEndGR + 1), 
                    end, 
                    0 );
            if ( resErr )
            {
                pc->error_code = (UINT16)resErr;
                return resErr;
            }
        }

        resErr = mmcEraseGroup( pc,
                RCA,
                S_EraseGroup, 
                E_EraseGroup, 
                0 );
        if ( resErr )
        {
            pc->error_code = (UINT16)resErr;
            return resErr;
        }
    }
    else if ((E_EraseGroup - S_EraseGroup) < 1)
    {
        resErr = mmcEraseSectors( pc,
                RCA,
                start,
                end,
                0 );
        if ( resErr )
        {
            pc->error_code = (UINT16)resErr;
            return resErr;
        }
    }       
    else if ((E_EraseGroup - S_EraseGroup) == 1)
    {
        if ( numSectStartGR )
        {
            resErr = mmcEraseSectors( pc,
                    RCA,
                    start, 
                    (start + numSectStartGR), 
                    0 );
            if ( resErr )
            {
                pc->error_code = (UINT16)resErr;
                return resErr;
            }
        }
        if (numSectEndGR)
        {
            resErr = mmcEraseSectors( pc,
                    RCA,
                    (end - numSectEndGR + 1), 
                    end, 
                    0 );
            if ( resErr )
            {
                pc->error_code = (UINT16)resErr;
                return resErr;
            }
        }
    }

    pc->error_code = MMC_NO_ERROR;
    return (MMC_NO_ERROR);
}


/***********************************************************************************
* Name: mmcGetStatus
*
* Description:
*       Retrieves the card current status.
* 
* Input:
*       PDEVICE_CONTROLLER      pc      Pointer to the controller structure
*       UINT16  RCA     Card address.
* 
* Output:
*       status  A 32 bit status word. Error/status bits.
* 
* Returns:
*       Completion code
*
************************************************************************************/
MMC_CC mmcGetStatus ( PDEVICE_CONTROLLER pc, UINT16 RCA)
{
    MMC_CC  resErr;

#if (USE_MMC || USE_MMC_EMULATION)

    resErr = mmcCommandAndResponse ( pc,
                                (((ULONG)RCA) << 16),
                SEND_STATUS, 
                0,
                R1 );
#else

        selectChip ( RCA );
    resErr = mmcCommandAndResponse ( pc,
                0L,
                SEND_STATUS, 
                0,
                R2 );
        deSelectChip( RCA );
#endif

    pc->error_code = (UINT16)resErr;
    return (resErr);
}

#if (USE_SPI || USE_SPI_EMULATION)
#if (USE_SET_FEATURES)
/***********************************************************************************
* Name: mmcTurnCRCOnOff - (SPI mode only)
*
* Description:
*       Turns the CRC option ON or OFF.
*
* Input:
*       PDEVICE_CONTROLLER      pc      Pointer to the controller structure
*       UINT16  opt             Enable/Disable CRC feature
*               - 1, turns the option ON.
*               - 0, turns the option OFF.
*       UINT16  RCA             Card address.
*
* Output:
*       None.
*
* Returns:
*       Completion code
*
************************************************************************************/
MMC_CC mmcTurnCRCOnOff( PDEVICE_CONTROLLER pc, UINT16 RCA, UINT16 opt )
{
    MMC_CC  resErr;

    selectChip ( RCA );

    resErr = mmcCommandAndResponse ( pc,
                (ULONG)opt,
                CRC_ON_OFF, 
                0,
                R1 );

    deSelectChip ( RCA );

    pc->error_code = (UINT16)resErr;
    return (resErr);
}

#endif  /* (USE_SET_FEATURES) */
#endif  /* (USE_SPI || USE_SPI_EMULATION) */



/*********************************************************************************
* Name: mmedia_io
*
* Description:
*       Read/write handler. Single and multiple READ/WRITE are supported.
*
* Input:
*       INT16 driveno
*       ULONG sector
*       UCHAR *buffer
*       UCOUNT scount
*       INT16 op
*
* Output:
*
* Return:
*
**********************************************************************************/
MMC_CC mmedia_io( INT16 driveno, ULONG sector, UCHAR *buffer, UCOUNT scount, INT16 op ) /*__fn__*/
{
    PDEVICE_CONTROLLER pc;
    ULONG   starting_sector;
    MMC_CC  ret_val;
    INT16   phys_drive;
    UINT16  RCA;

    phys_drive = (INT16)(driveno & 0x7FFF);

#if (N_CONTROLLERS > 1)
    pc = drno_to_controller(phys_drive);
#else
    pc = &controller_s[0];
#endif

    if ( !scount || !pc )             /* Must have a count */
    {
        pc->error_code = MMC_ADDRESS_ERROR;
        return (MMC_ADDRESS_ERROR);
    }

#if (N_CONTROLLERS > 1)
    phys_drive = drno_to_phys(phys_drive);
#endif

    pc->drive_active = (INT16)(phys_drive | DRV_ACTIVE);

    /* Set it up. Select the base address */
    MMCSelectController(pc->controller_number, phys_drive);
    RCA = pc->drive[phys_drive].RCA;

    starting_sector = sector;

    /* Get the block length */
    pc->block_size = pc->drive[phys_drive].block_size;

    if ( (starting_sector+scount) > pc->drive[phys_drive].total_lba )
    {
        pc->error_code = BUS_ERC_ADDR_RANGE;
        return (MMC_ADDRESS_ERROR);
    }

    ret_val = MMC_NO_ERROR;

    /* Set up a counter for data transfer */
    pc->sectors_remaining = scount;

    pc->user_address = (USERADDRESS)buffer;

    if (op == READING)
    {
                pc->mode = READ_MODE;

#if (USE_SD)
#if (USE_SECURITY)
        /* Is the request a security request? */
        if (FINDSOURCEOFREQUEST(driveno))
        {
            /* Make sure to access to the security device */
            if (pc->drive[phys_drive].securityDrv)
            {
                /* Execute Security driver */
                ret_val = mmcSecureRead(starting_sector,                        
                        buffer, scount, driveno);
                                return ret_val;
            }
        }
#endif
#endif

#if (USE_MULTI) /* Read multiple */
 #if (USE_SPI || USE_SPI_EMULATION)
  #if (USE_SD)
        if (scount > 1)
        {
                        pc->mode |= MULTIPLE_MODE;

            ret_val = mmcReadMultiple(pc,
                        starting_sector,
                        RCA,
                        scount);
        }
        else
        {
                        pc->mode |= SINGLE_MODE;

            ret_val = mmcRead(pc,
                    starting_sector,
                    RCA,
                    1);
        }

        if (ret_val != MMC_NO_ERROR )
        {
            pc->error_code = (UINT16)ret_val;
            return ret_val;
        }

  #else
        pc->error_code = MMC_ILLEGAL_MODE;
        return MMC_ILLEGAL_MODE;
  #endif
 #endif

 #if (USE_MMC || USE_MMC_EMULATION)
        if (scount > 1)
        {
                        pc->mode |= MULTIPLE_MODE;

            ret_val = mmcReadMultiple(pc,
                        starting_sector,
                        RCA,
                        scount);
        }
        else
        {
                        pc->mode |= SINGLE_MODE;

            ret_val = mmcRead(pc,
                    starting_sector,
                    RCA,
                    1);
        }
        if (ret_val != MMC_NO_ERROR )
        {
            pc->error_code = (UINT16)ret_val;
            return ret_val;
        }
 #endif

#else   /* Single read */

                pc->mode |= SINGLE_MODE;

        while (pc->sectors_remaining)
        {
            ret_val = mmcRead(pc,
                    starting_sector,
                    RCA,
                    1);

            if ( ret_val != MMC_NO_ERROR )
            {
                pc->error_code = (UINT16)ret_val;
                return ret_val;
            }

            pc->sector

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -