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

📄 fs_sdmmc_dev.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
        Sdmmc_to_cnt++;
    }

    //FS_sdmmc_delay(400);
    Sdmmc_to_cnt = 0;
#if 0
    while (0 == (CMD_RESP_INT & ReadReg32(SDMMC_SD_INT)))
    {
//   while (SDMMC_CMD_RESP_TX_INT_STAT_YES != (SDMMC_CMD_RESP_TX_INT_STAT_YES & ReadReg32(SDMMC_SD_INT)))  {
        if (Sdmmc_to_cnt > 0x10000000)
        {
            //printf("Socle SD/MMC: comamnd%d and response it timeout\n", cmd_abbr);
            return -1;
        }
        Sdmmc_to_cnt++;
    }
#endif

    WriteReg32(SDMMC_SD_INT, (ReadReg32(SDMMC_SD_INT) & (~SDMMC_CMD_RESP_TX_INT_STAT_YES)));

#else
    while (0 == (CMD_RESP_INT & CardIntStatus))
    {
        if (Sdmmc_to_cnt > 0x1000000)
        {
            return -1;
        }
        Sdmmc_to_cnt++;
    }
    CardIntStatus &= ~CMD_RESP_INT;
#endif

    /* Check whether command transfer cause errors */
    rdata = ReadReg32(SDMMC_SD_CMDREST);
    if (SDMMC_CMD_RESP_TX_STAT_ERR == (rdata & SDMMC_CMD_RESP_TX_STAT_ERR))
    {
        //goto send_cmd_error;
        rdata = ReadReg32(SDMMC_SD_CMDREST);
        return rdata;

    }

    return 0;

}

volatile uint32 SdTansIsrFlag;
void SdTansIsrProc(void)
{
    SdTansIsrFlag = 0;
}


/*********************************************************************************************************
*函数描述: 动态设置卡的运行频率
*入口参数: 无
*出口参数: 无
*调用函数: WriteReg32, ReadReg32
*
* History:
*         <author>      <time>              <version>       <desc>
*         Xiebangwang   2008-03-18             1.0          x
*********************************************************************************************************/
void  SdmmcSetFrequency(void)
{
    UINT32 freq;

    freq = Pll_get_apb_freq();

    if (freq <= 40000)
    {
        MMC_Divider = 0;
        SD_Divider  = 0;
    }
    else if (freq < 51000)
    {
        MMC_Divider = 1;
        SD_Divider  = 0;
    }
    else
    {
        MMC_Divider = 1;
        SD_Divider  = 1;
    }

    if ((prevMMC_Divider != MMC_Divider) || (prevSD_Divider != SD_Divider))
    {
        /* Change clock rate to enter the data transfer mode */
        if (MMC_CARD != SdmmcCardType)
        {
            WriteReg32(SDMMC_SD_CTRL, (ReadReg32(SDMMC_SD_CTRL)&0xF800) | SD_Divider);
        }
        else
        {
            WriteReg32(SDMMC_SD_CTRL, (ReadReg32(SDMMC_SD_CTRL)&0xF800) | MMC_Divider);
        }
    }

    prevMMC_Divider = MMC_Divider;
    prevSD_Divider  = SD_Divider;

}




/*********************************************************************************************************
*函数描述: 获取卡的拔插状态
*入口参数: 无
*出口参数: TRUE--表示卡是插入状态; FALSE--表示卡处于拔出状态
*调用函数:
*
* History:
*         <author>      <time>              <version>       <desc>
*         Xiebangwang   2008-03-12             1.0          检查当前卡的拔插状态
*********************************************************************************************************/
int SdmmcInsertState(void)
{
    uint32 rdata;
    uint32 InsertState;

    rdata = GPIO_GetPinLevel(SD_DETECT_PIN);

#if (SDCheckInsetLevel == 0)
    if (rdata == 1)
#else
    if (rdata == 0)
#endif
    {
        InsertState = FALSE;
    }
    else
    {
        InsertState = TRUE;
    }

    return InsertState;
}



/*********************************************************************************************************
*函数描述: SD卡忙状态检测
*入口参数: 无
*出口参数: 0表示正确,非0表示错误
*调用函数:
*
* History:
*         <author>      <time>              <version>       <desc>
*         Xiebangwang   2008-03-08             1.0          检测写函数是否完全结束
*********************************************************************************************************/
int SdmmcChkBusy(void)
{
    int i, rep;
    rep = 0;

    do
    {
        WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);

        WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                   SDMMC_DATA_TX_DIR_READ |
                   SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                   SDMMC_DATA_TX_DMA_DIS |
                   SDMMC_DATA_TX_CYC_MULTIPLE);


        Sdmmc_data_transfer_end();
        Sdmmc_mmu_swap();

        for (i = 128; i != 0; i--)
        {
            if (0xFFFFFFFF == ReadReg32(SDMMC_MMU_DATA))
            {
                break;
            }
        }

        if (i != 0)
        {
            break;
        }

        rep++;
    }
    while (rep < 5);


    if (rep >= 5)
        return 222;
    else
        return 0;
}


/*********************************************************************************************************
*函数描述: 读SD卡
*入口参数: 块地址,块数,写数据缓冲。
*出口参数: 0表示正确,非0表示错误
*调用函数: WriteReg32, Sdmmc_send_cmd, Sdmmc_data_transfer_end, Sdmmc_mmu_swap, ReadReg32
*
* History:
*         <author>      <time>              <version>       <desc>
*          LXS,FZF                             1.0          采用关中断方法
*
*         Xiebangwang   2008-02-16             2.0          取消关中断操作,改变读函数设置时序
*         Xiebangwang   2008-02-27             2.1          修改LBA,兼容Ver2.00 or later SD Memory Card
*
*********************************************************************************************************/
int SdmmcReadMSecs(unsigned long LBA, unsigned int count, void *buf)
{
    int i;
    unsigned int *rbuf;
    unsigned int cnt;
    int rt = 0; //本函数返回值,0表示正确,非0表示错误
    int repeat_times = 0;  // 数据传输不成功时,重复读的次数

    if (count < 1) //防止非法参数
    {
        return (-1);
    }

    /*动态改变卡的运行频率,使卡运行于最佳频率*/
    SdmmcSetFrequency();

    /* If it is not SDHC,the memory address shoud be in the byte address format */
    if (SdmmcCardType != HC_SD_CARD)
    {
        LBA = LBA << 9; /* convert block number to byte address */
    }

    Scu_ClockEnable(SDMMC_CLOCK);

    for (repeat_times = 0; repeat_times < 20; repeat_times++)
    {
        rbuf = (unsigned int *)buf;
        cnt  = count;
        rt   = 0;

        WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);

        if (cnt > 1)
        {
            WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                       SDMMC_DATA_TX_DIR_READ |
                       SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                       SDMMC_DATA_TX_DMA_DIS |
                       SDMMC_DATA_TX_CYC_MULTIPLE);
        }
        else
        {
            WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                       SDMMC_DATA_TX_DIR_READ |
                       SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                       SDMMC_DATA_TX_DMA_DIS |
                       SDMMC_DATA_TX_CYC_SINGLE);
        }

        /* Send CMD18 to read blocks */
        if (Sdmmc_send_cmd(MMC_READ_MULTIPLE_BLOCK, LBA))
        {
            rt = -2;
        }
        else
        {
            while (cnt > 0)
            {
                /* Wait for the reading transmission to be complete */
                if (Sdmmc_data_transfer_end())
                {
                    rt = -3;
                    break;
                }

                Sdmmc_mmu_swap();

                cnt --;
                if (cnt == 0)
                {
                    Sdmmc_delay(200);

                    /* Send CMD12 to stop the transimission */
                    if (Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000))
                    {
                        rt = -4;
                        break;
                    }
                }
                else if (cnt == 1)
                {
                    WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                               SDMMC_DATA_TX_DIR_READ |
                               SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                               SDMMC_DATA_TX_DMA_DIS |
                               SDMMC_DATA_TX_CYC_SINGLE);
                }
                else
                {
                    WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                               SDMMC_DATA_TX_DIR_READ |
                               SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                               SDMMC_DATA_TX_DMA_DIS |
                               SDMMC_DATA_TX_CYC_MULTIPLE);
                }

                for (i = 128; i != 0; i--)
                {
                    *rbuf++ = ReadReg32(SDMMC_MMU_DATA);
                }
            }
        }

        if (rt == 0)
        {
            break;
        }
        else
        {
            if (!SdmmcInsertState())
            {
                Scu_ClockDisable(SDMMC_CLOCK);
                return rt;  //若是由于,拔卡出现错误,直接退出
            }

            Sdmmc_delay(200);

            /* Send CMD12 to stop the transimission */
            Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000);
        }
    }

#if 0
    //下面仅用于设置调试断点
    if ((repeat_times == 20) && (rt != 0))
    {
        int j ;
        ReadReg32(SDMMC_SD_CMDREST);
        j = 10 ;
        cnt++;
    }
#endif
    Scu_ClockDisable(SDMMC_CLOCK);
    return rt;
}


/*********************************************************************************************************
*函数描述: SD卡写函数
*入口参数: 块地址,块数,写数据缓冲。
*出口参数: 0表示正确,非0表示错误
*调用函数: WriteReg32, Sdmmc_send_cmd, Sdmmc_data_transfer_end, Sdmmc_mmu_swap, ReadReg32
*
* History:
*         <author>      <time>              <version>       <desc>
*          LXS,FZF                             1.0          采用关中断方法
*
*         Xiebangwang   2008-02-16             2.0          取消关中断操作,改变读函数设置时序
*         Xiebangwang   2008-02-27             2.1          修改LBA,兼容Ver2.00 or later SD Memory Card
*
*********************************************************************************************************/
int SdmmcWriteMSecs(unsigned long LBA, unsigned int count, void *buf)
{
    unsigned long i;
    unsigned long rdata;
    unsigned int  *rbuf;
    unsigned long Sdmmc_to_cnt;
    int rt = 0;

    int repeat_times;
    unsigned int cnt;

    char  bufIdentify[2];

    if (count < 1) //防止非法参数
    {
        return (1);
    }

    bufIdentify[0] = *((char*)buf + 510);
    bufIdentify[1] = *((char*)buf + 511);

    /*动态改变卡的运行频率,使卡运行于最佳频率*/
    SdmmcSetFrequency();

    /* If it is not SDHC,the memory address should be in the byte address format */
    if (SdmmcCardType != HC_SD_CARD)
    {
        LBA = LBA << 9; /* convert block number to byte address */
    }

    repeat_times = 0;
    Scu_ClockEnable(SDMMC_CLOCK);
    while (repeat_times < 20)
    {
        rbuf = (unsigned int *)buf;
        cnt = count;

        WriteReg32(SDMMC_MMU_CTRL, SDMMC_MMU_DATA_WIDTH_WORD);

        for (i = 128; i != 0; i--)
        {
            WriteReg32(SDMMC_MMU_DATA, *rbuf++);
        }

        //Sdmmc_send_cmd(MMC_APP_CMD, SdmmcCardRca); // CMD55(), Make ACMD
        //Sdmmc_send_cmd(SD_SET_WR_BLK_ERASE_COUNT,0xff800000|count); // ACMD23 (count) pre erase

        /* CMD25 WRITE MULTIPLE BLOCKs  */
        if (Sdmmc_send_cmd(MMC_WRITE_MULTIPLE_BLOCK, LBA))
        {
            rt = -1;
            goto Repeat_Wrtie_Test;
        }

        while (cnt > 0)
        {
            Sdmmc_mmu_swap();

            if (cnt == 1)
            {
                WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                           SDMMC_DATA_TX_DIR_WRITE |
                           SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                           SDMMC_DATA_TX_DMA_DIS |
                           SDMMC_DATA_TX_CYC_SINGLE);
            }
            else
            {
                WriteReg32(SDMMC_SD_DATAT, SDMMC_DATA_TX_SIGNAL_BEGIN |
                           SDMMC_DATA_TX_DIR_WRITE |
                           SDMMC_DATA_TX_BUS_WIDTH_LINE_1 |
                           SDMMC_DATA_TX_DMA_DIS |
                           SDMMC_DATA_TX_CYC_MULTIPLE);

                for (i = 128; i != 0; i--)
                {
                    WriteReg32(SDMMC_MMU_DATA, *rbuf++);
                }
            }

            /* Wait for the writing transmission to be complete */
            if (Sdmmc_data_transfer_end())
            {
                rt = -3;
                break;
            }

            cnt--;
        }

        /* Send CMD12 to stop the transimission */
        if (Sdmmc_send_cmd(MMC_STOP_TRANSMISSION, 0x00000000))
        {
            rt = -4;
        }

        /* Wait for the card to depart from the busy state */
        Sdmmc_to_cnt = 0;
        do
        {
            if (Sdmmc_to_cnt > 0x1000000)
            {
                rt = -5;
                break;
            }
            rdata = ReadReg32(SDMMC_SD_CARDA);
            Sdmmc_to_cnt++;
        }
        while (SDMMC_CARD_BUSY_SIGNAL_HIGH != (rdata & SDMMC_CARD_BUSY_SIGNAL_HIGH));

Repeat_Wrtie_Test:

        if (rt == 0)
        {
            break;
        }

        if (!SdmmcInsertState())
        {
            Scu_ClockDisable(SDMMC_CLOCK);
            return rt;  //若是由于,拔卡出现错误,直接退出
        }

        repeat_times ++;

    }

    if ((count >= 0x20) && (count <= 0x26) && (0x55 == bufIdentify[0]) && (0x0AA == bufIdentify[1]))
    {
        SdmmcChkBusy();
    }
    Scu_ClockDisable(SDMMC_CLOCK);
    return(rt);
}

#endif



#endif

⌨️ 快捷键说明

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