SDIO使用参考

Version 1.0


1. 概述

SDIO主要分为四部分组成:外部引脚、内部寄存器、接口控制器和内部存储介质。

引脚:

CLK:时钟信号

CMD:命令和响应引脚

DAT0~3:数据线

Demo 板上引脚对应信息:

引脚 222_demo 9211_demo
SDIO_D[1] PAD_SD_D1 PAD_TTL1
SDIO_D[0] PAD_SD_D0 PAD_TTL2
SDIO_CLK PAD_SD_CLK PAD_TTL3
SDIO_CMD PAD_SD_CMD PAD_TTL4
SDIO_D[3] PAD_SD_D3 PAD_TTL5
SDIO_D[2] PAD_SD_D2 PAD_TTL6
SD_CDZ PAD_PM_SD_CDZ PAD_TTL0
PWR PAD_SD_GPIO0 PAD_TTL7

SDIO驱动路径:rtk/proj/sc/driver/sysdriver/sdmmc


2. 配置

2.1. sysdesc配置

以SSC9211 Demo板为例:

查表可知sdio mode为2,cdzs引脚使用PAD_TTL0,pwr使用PAD_TTL7

需要确认当前使用的product config是使用的何种sysdesc文件,可在rtk/proj/mak/product中找到当前工程的配置,打开配置搜索CONFIG_SYSDESC_SELECT确认当前使用的sysdesc文件。例如,当前工程使用pioneer3_ssc020a_64_freertos_smp_isw_usbdev,其对应的sysdesc文件为CONFIG_SYSDESC_SELECT = "pioneer3-ssc020a-s01b.sys",那么就去修改这个文件。

本例中修改:rtk/proj/sc/driver/sysdriver/sysdesc/hal/pioneer3/pub/pioneer3-ssc020a-s01b.sys下的sdmmc节点。

[slot_pad_orders_u8] 2, 1, 2; \rightarrow 指定第一位 = sdio mode-2


2.2. mak配置

在相应的product config中修改mak文件的配置,需要开启选项CONFIG_SDIO_CARD_SUPPORT = TRUE以及CONFIG_FREERTOS_PLUS_FAT_SUPPORT = TRUE


2.3. 库信息

freertos_plus_fat.lib


2.4. 命令调试

命令行输入: fatinfo mmc 0:0 简单验证SD卡功能,下图为正常打印


2.5. API 使用

API名称 说明
FF_Disk_t *FF_SDDiskInit(const char *pcName, Basetype_t xSlot, Basetype_t xPartition); 创建 ram disk
Basetype_t FF_SDDiskDelete(FF_Disk_t *pxDisk); 注销ram disk
FF_FILE *ff_fopen(const char *filePath, const char *opt); 打开文件
size_t ff_fclose(FF_FILE *fileHandle); 关闭文件
size_t ff_fread(void *pvBuffer, size_t xSize, size_t xItems, FF_FILE * fileHandle); 读文件
size_t ff_write(void *pvBuffe, size_t xSize, size_t xItems, FF_FILE * fileHandle); 写文件

2.6. 范例

#include "ff_headers.h"
#include "ff_stdio.h"
#include "ff_sddisk.h"

typedef enum
{
    SDDISK_OPT_READ = 0,
    SDDISK_OPT_WRITE,
    SDDISK_OPT_ADD,
}SDDisk_open_file_flag_type_e;

typedef enum
{
    SDDISK_RET_SUCCESSFUL,
    SDDISK_READ_ERR,
    SDDISK_WRIT_ERR,
}SDDisk_ret_type_e;


FF_Disk_t *open_SDDisk_dev(int dev, int hwPart)
{
    FF_Disk_t *SDDiskHandle = FF_SDDiskInit(NULL, dev, hwPart);
    if(NULL == SDDiskHandle)
    {
        CamOsPrintf("Failed to mount device %d:%d\n", dev, hwPart);
        return NULL;
    }
    FF_SDDiskShowPartition(SDDiskHandle);
    CamOsPrintf("succeed to mount device %d:%d\n", dev, hwPart);
    return SDDiskHandle;
}

void close_SDDisk_dev(FF_Disk_t *SDDiskHandle)
{
    if(NULL != SDDiskHandle)
    {
        FF_SDDiskDelete(SDDiskHandle);
        CamOsPrintf("succeed to unmount\n");
    }
    else
    {
        CamOsPrintf("close disk device fail\n");
    }
}

FF_FILE *open_SDDisk_file(FF_Disk_t *SDDiskHandle, char *filePath, SDDisk_open_file_flag_type_e optType)
{
    FF_FILE *fileHandle = NULL;
    if(NULL == SDDiskHandle)
    {
        CamOsPrintf("illegal SDDiskHandle \n");
        return NULL;
    }

    if(NULL == filePath)
    {
        CamOsPrintf("filePath is NULL\n");
        return NULL;
    }

    switch(optType)
    {
        case SDDISK_OPT_READ:
            fileHandle = ff_fopen(filePath, "r");
            CamOsPrintf("open file by read \n");
            break;

        case SDDISK_OPT_WRITE:
            fileHandle = ff_fopen(filePath, "w+");
            CamOsPrintf("pen file by write \n");
            break;

        case SDDISK_OPT_ADD:
            fileHandle = ff_fopen(filePath, "a+");
            CamOsPrintf("pen file by add \n");
            break;
        default:
            CamOsPrintf("illegal file optType:%d\n", optType);
    }

    if(NULL == fileHandle)
    {
        CamOsPrintf("Failed to open file \n");
        return NULL;
    }
    else
    {
        CamOsPrintf("succeed to open file \n");
    }

    return fileHandle;
}

void close_SDDisk_file(FF_FILE *fileHandle)
{
    if(NULL != fileHandle)
    {
        ff_fclose(fileHandle);
        CamOsPrintf("succeed to close file \n");
    }
}

SDDisk_ret_type_e read_SDDisk(FF_FILE *fileHandle, char *readBuff, uint32_t bytes, uint32_t pos)
{
    if(NULL == fileHandle)
    {
        CamOsPrintf("illegal fileHandle\n");
        return SDDISK_READ_ERR;
    }

    size_t xRead;
    size_t xReaded;
    size_t xRet;

    if (pos > 0)
        ff_fseek(fileHandle, pos, FF_SEEK_SET);

    xRet = ff_filelength(fileHandle);
//    if (bytes == 0 || bytes > xRet)
//        bytes = xRet;

    xReaded = 0;

    for (;;)
    {
        if (bytes < FATLOAD_UNIT)
        {
            xRead = bytes;
        }
        else
        {
            xRead = FATLOAD_UNIT;
        }


        xRet = ff_fread(readBuff + xReaded, 1, xRead, fileHandle);
        if (xRet > 0)
            xReaded += xRet;

        if (xRet != xRead)
        {
            CamOsPrintf("read error\n");
            break;
        }
        else
        {
            bytes -= xRet;
        }

        if (bytes <= 0)
            break;
    }

    return SDDISK_RET_SUCCESSFUL;
}

SDDisk_ret_type_e write_SDDisk(FF_FILE *fileHandle, char* addr, uint32_t bytes)
{
    if(NULL == fileHandle)
    {
        CamOsPrintf("illegal fileHandle\n");
        return SDDISK_WRIT_ERR;
    }

    if(NULL == addr)
    {
        CamOsPrintf("illegal write addr\n");
        return SDDISK_WRIT_ERR;
    }

    size_t xRet;
    xRet = ff_fwrite((char *)addr, 1, bytes, fileHandle);
    if (xRet != bytes)
        CamOsPrintf("write error\n");
    CamOsPrintf("done\nByes transferred = %d (%x hex)\n", xRet, xRet);

    return SDDISK_RET_SUCCESSFUL;
}