Browse Source

添加sdio驱动

文件系统挂载
master
sc 2 months ago
parent
commit
91c4751d7c
  1. 20
      .config
  2. 11
      .cproject
  3. 2
      .project
  4. BIN
      .settings/.rtmenus
  5. 2
      .settings/language.settings.xml
  6. 2
      .settings/local_temp_storage.prefs
  7. 95
      applications/SDIO_elmfatfs.c
  8. 4
      applications/main.c
  9. 3
      drivers/board.h
  10. 718
      drivers/drv_sdio.c
  11. 194
      drivers/include/drv_sdio.h
  12. 4
      rtconfig.h

20
.config

@ -199,7 +199,13 @@ CONFIG_RT_MMCSD_STACK_SIZE=1024
CONFIG_RT_MMCSD_THREAD_PREORITY=22 CONFIG_RT_MMCSD_THREAD_PREORITY=22
CONFIG_RT_MMCSD_MAX_PARTITION=16 CONFIG_RT_MMCSD_MAX_PARTITION=16
# CONFIG_RT_SDIO_DEBUG is not set # CONFIG_RT_SDIO_DEBUG is not set
# CONFIG_RT_USING_SPI is not set CONFIG_RT_USING_SPI=y
# CONFIG_RT_USING_SPI_BITOPS is not set
CONFIG_RT_USING_QSPI=y
CONFIG_RT_USING_SPI_MSD=y
# CONFIG_RT_USING_SFUD is not set
# CONFIG_RT_USING_ENC28J60 is not set
# CONFIG_RT_USING_SPI_WIFI is not set
# CONFIG_RT_USING_WDT is not set # CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set # CONFIG_RT_USING_AUDIO is not set
# CONFIG_RT_USING_SENSOR is not set # CONFIG_RT_USING_SENSOR is not set
@ -245,7 +251,17 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
# #
# POSIX (Portable Operating System Interface) layer # POSIX (Portable Operating System Interface) layer
# #
# CONFIG_RT_USING_POSIX_FS is not set CONFIG_RT_USING_POSIX_FS=y
# CONFIG_RT_USING_POSIX_DEVIO is not set
# CONFIG_RT_USING_POSIX_STDIO is not set
# CONFIG_RT_USING_POSIX_POLL is not set
# CONFIG_RT_USING_POSIX_SELECT is not set
# CONFIG_RT_USING_POSIX_EVENTFD is not set
# CONFIG_RT_USING_POSIX_TIMERFD is not set
# CONFIG_RT_USING_POSIX_SOCKET is not set
# CONFIG_RT_USING_POSIX_TERMIOS is not set
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_POSIX_MMAN is not set
# CONFIG_RT_USING_POSIX_DELAY is not set # CONFIG_RT_USING_POSIX_DELAY is not set
# CONFIG_RT_USING_POSIX_CLOCK is not set # CONFIG_RT_USING_POSIX_CLOCK is not set
# CONFIG_RT_USING_POSIX_TIMER is not set # CONFIG_RT_USING_POSIX_TIMER is not set

11
.cproject

@ -79,6 +79,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/spi}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" />
@ -131,7 +132,10 @@
</option> </option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.2007675975" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" /> <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.2007675975" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.2105838438" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean" /> <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.2105838438" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs.934137837" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs" useByScannerDiscovery="false" /> <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs.934137837" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="c " />
<listOptionValue builtIn="false" value="m " />
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart.2118356996" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" /> <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart.2118356996" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs.1427884346" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs.1427884346" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs.1433863653" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" /> <option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs.1433863653" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean" />
@ -187,6 +191,7 @@
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/filesystems/elmfat}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/dfs/dfs_v1/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/drivers/spi}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/finsh}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/common/include}&quot;" />
<listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" /> <listOptionValue builtIn="false" value="&quot;${workspace_loc://${ProjName}//rt-thread/components/libc/compilers/newlib}&quot;" />
@ -206,7 +211,7 @@
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="//cubemx/Drivers|//cubemx/EWARM|//cubemx/Src/stm32h7xx_it.c|//cubemx/Src/system_stm32h7xx.c|//rt-thread/components/dfs/dfs_v1/filesystems/cromfs|//rt-thread/components/dfs/dfs_v1/filesystems/mqueue|//rt-thread/components/dfs/dfs_v1/filesystems/nfs|//rt-thread/components/dfs/dfs_v1/filesystems/ramfs|//rt-thread/components/dfs/dfs_v1/filesystems/romfs|//rt-thread/components/dfs/dfs_v1/filesystems/skeleton|//rt-thread/components/dfs/dfs_v1/filesystems/tmpfs|//rt-thread/components/dfs/dfs_v2|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/bus.c|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/fdt|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/pin_dm.c|//rt-thread/components/drivers/pin/pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/rtc|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/serial_v2.c|//rt-thread/components/drivers/spi|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/watchdog|//rt-thread/components/drivers/wlan|//rt-thread/components/fal|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/atomic_arm.c|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu.c|//rt-thread/src/mem.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/signal.c|//rt-thread/src/slab.c|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" /> <entry excluding="//cubemx/Drivers|//cubemx/EWARM|//cubemx/Src/stm32h7xx_it.c|//cubemx/Src/system_stm32h7xx.c|//rt-thread/components/dfs/dfs_v1/filesystems/cromfs|//rt-thread/components/dfs/dfs_v1/filesystems/mqueue|//rt-thread/components/dfs/dfs_v1/filesystems/nfs|//rt-thread/components/dfs/dfs_v1/filesystems/ramfs|//rt-thread/components/dfs/dfs_v1/filesystems/romfs|//rt-thread/components/dfs/dfs_v1/filesystems/skeleton|//rt-thread/components/dfs/dfs_v1/filesystems/tmpfs|//rt-thread/components/dfs/dfs_v2|//rt-thread/components/drivers/audio|//rt-thread/components/drivers/can|//rt-thread/components/drivers/clk|//rt-thread/components/drivers/core/bus.c|//rt-thread/components/drivers/core/dm.c|//rt-thread/components/drivers/core/driver.c|//rt-thread/components/drivers/core/platform.c|//rt-thread/components/drivers/core/platform_ofw.c|//rt-thread/components/drivers/cputime|//rt-thread/components/drivers/fdt|//rt-thread/components/drivers/hwcrypto|//rt-thread/components/drivers/hwtimer|//rt-thread/components/drivers/i2c|//rt-thread/components/drivers/ktime|//rt-thread/components/drivers/misc|//rt-thread/components/drivers/mtd|//rt-thread/components/drivers/ofw|//rt-thread/components/drivers/phy|//rt-thread/components/drivers/pic|//rt-thread/components/drivers/pin/pin_dm.c|//rt-thread/components/drivers/pin/pin_ofw.c|//rt-thread/components/drivers/pinctrl|//rt-thread/components/drivers/pm|//rt-thread/components/drivers/rtc|//rt-thread/components/drivers/sensor|//rt-thread/components/drivers/serial/serial_dm.c|//rt-thread/components/drivers/serial/serial_tty.c|//rt-thread/components/drivers/serial/serial_v2.c|//rt-thread/components/drivers/spi/enc28j60.c|//rt-thread/components/drivers/spi/sfud|//rt-thread/components/drivers/spi/spi-bit-ops.c|//rt-thread/components/drivers/spi/spi_flash_sfud.c|//rt-thread/components/drivers/spi/spi_wifi_rw009.c|//rt-thread/components/drivers/touch|//rt-thread/components/drivers/usb|//rt-thread/components/drivers/virtio|//rt-thread/components/drivers/watchdog|//rt-thread/components/drivers/wlan|//rt-thread/components/fal|//rt-thread/components/legacy|//rt-thread/components/libc/compilers/armlibc|//rt-thread/components/libc/compilers/dlib|//rt-thread/components/libc/compilers/musl|//rt-thread/components/libc/compilers/picolibc|//rt-thread/components/libc/cplusplus|//rt-thread/components/libc/posix|//rt-thread/components/lwp|//rt-thread/components/mm|//rt-thread/components/mprotect|//rt-thread/components/net|//rt-thread/components/utilities|//rt-thread/components/vbus|//rt-thread/libcpu/aarch64|//rt-thread/libcpu/arc|//rt-thread/libcpu/arm/AT91SAM7S|//rt-thread/libcpu/arm/AT91SAM7X|//rt-thread/libcpu/arm/am335x|//rt-thread/libcpu/arm/arm926|//rt-thread/libcpu/arm/armv6|//rt-thread/libcpu/arm/common/atomic_arm.c|//rt-thread/libcpu/arm/common/divsi3.S|//rt-thread/libcpu/arm/cortex-a|//rt-thread/libcpu/arm/cortex-m0|//rt-thread/libcpu/arm/cortex-m23|//rt-thread/libcpu/arm/cortex-m3|//rt-thread/libcpu/arm/cortex-m33|//rt-thread/libcpu/arm/cortex-m4|//rt-thread/libcpu/arm/cortex-m7/context_iar.S|//rt-thread/libcpu/arm/cortex-m7/context_rvds.S|//rt-thread/libcpu/arm/cortex-m7/mpu.c|//rt-thread/libcpu/arm/cortex-m85|//rt-thread/libcpu/arm/cortex-r4|//rt-thread/libcpu/arm/cortex-r52|//rt-thread/libcpu/arm/dm36x|//rt-thread/libcpu/arm/lpc214x|//rt-thread/libcpu/arm/lpc24xx|//rt-thread/libcpu/arm/realview-a8-vmm|//rt-thread/libcpu/arm/s3c24x0|//rt-thread/libcpu/arm/s3c44b0|//rt-thread/libcpu/arm/sep4020|//rt-thread/libcpu/arm/zynqmp-r5|//rt-thread/libcpu/avr32|//rt-thread/libcpu/blackfin|//rt-thread/libcpu/c-sky|//rt-thread/libcpu/ia32|//rt-thread/libcpu/m16c|//rt-thread/libcpu/mips|//rt-thread/libcpu/nios|//rt-thread/libcpu/ppc|//rt-thread/libcpu/risc-v|//rt-thread/libcpu/rx|//rt-thread/libcpu/sim|//rt-thread/libcpu/sparc-v8|//rt-thread/libcpu/ti-dsp|//rt-thread/libcpu/unicore32|//rt-thread/libcpu/v850|//rt-thread/libcpu/xilinx|//rt-thread/src/cpu.c|//rt-thread/src/mem.c|//rt-thread/src/scheduler_mp.c|//rt-thread/src/signal.c|//rt-thread/src/slab.c|//rt-thread/tools" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="" />
</sourceEntries> </sourceEntries>
</configuration> </configuration>
</storageModule> </storageModule>
@ -225,7 +230,7 @@
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders" /> <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders" />
<storageModule moduleId="refreshScope" versionNumber="2"> <storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug"> <configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/828F" /> <resource resourceType="PROJECT" workspacePath="/project" />
</configuration> </configuration>
</storageModule> </storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets" /> <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets" />

2
.project

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>828F</name> <name>project</name>
<comment /> <comment />
<projects> <projects>
</projects> </projects>

BIN
.settings/.rtmenus

Binary file not shown.

2
.settings/language.settings.xml

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1130338007442180612" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true"> <provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1076862496448840086" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/> <language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/> <language-scope id="org.eclipse.cdt.core.g++"/>
</provider> </provider>

2
.settings/local_temp_storage.prefs

@ -0,0 +1,2 @@
eclipse.preferences.version=1
temp.toolchain.exec.path=C\:\\RT-ThreadStudio\\repo\\Extract\\ToolChain_Support_Packages\\ARM\\GNU_Tools_for_ARM_Embedded_Processors\\13.3/bin

95
applications/SDIO_elmfatfs.c

@ -0,0 +1,95 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-07-29 andy the first version
*/
#include <rtthread.h>
#include "dfs_fs.h"
#define DBG_TAG "mount_fs"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
rt_sem_t mount_sem = RT_NULL;
void sd_mount(void *parameter)
{
LOG_I("SD mount thread started, waiting for SD card...");
int retry = 0;
while (retry<10)
{
if (rt_device_find("sd") != RT_NULL)
{
if (dfs_mount("sd", "/", "elm", 0, NULL) == RT_EOK)
{
LOG_I("SD card mounted to '/' successfully");
// 挂载成功,释放信号量
if (mount_sem != RT_NULL)
{
rt_sem_release(mount_sem);
}
break; // 退出线程循环
}
else
{
LOG_W("SD card mount failed, retrying...");
}
}
else
{
LOG_D("SD device 'sd' not found, retrying...");
}
// 避免空转,延时 100ms 再试
rt_thread_mdelay(500);
retry++;
}
}
int stm32_sdcard_mount(void)
{
rt_thread_t tid;
rt_thread_mdelay(1000);
// 删除旧的信号量(如果存在)
if (mount_sem != RT_NULL)
{
rt_sem_delete(mount_sem);
}
// 创建计数信号量,初始值为 0
mount_sem = rt_sem_create("sd_mount", 0, RT_IPC_FLAG_FIFO);
if (mount_sem == RT_NULL)
{
LOG_E("Failed to create semaphore for SD mount!");
return -RT_ENOMEM;
}
tid = rt_thread_create("sd_mount",
sd_mount,
RT_NULL,
1024*6, // 避免溢出
RT_THREAD_PRIORITY_MAX - 2,
20);
if (tid != RT_NULL)
{
rt_thread_startup(tid);
LOG_I("SD mount thread created and started");
}
else
{
LOG_E("Failed to create SD mount thread!");
rt_sem_delete(mount_sem);
mount_sem = RT_NULL;
return -RT_ERROR;
}
return RT_EOK;
}
// 使用 INIT_COMPONENTS_INIT 或 INIT_APP_EXPORT 自动启动
//INIT_COMPONENTS_INIT(stm32_sdcard_mount); // 在组件初始化阶段运行
INIT_APP_EXPORT(stm32_sdcard_mount);

4
applications/main.c

@ -15,8 +15,12 @@
#define DBG_LVL DBG_LOG #define DBG_LVL DBG_LOG
#include <rtdbg.h> #include <rtdbg.h>
extern rt_sem_t mount_sem; // 引用上面SD挂载线程定义的信号量
int main(void) int main(void)
{ {
rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒
rt_thread_mdelay(500);
thread_RUN_LED();//运行指示灯线程 thread_RUN_LED();//运行指示灯线程
return RT_EOK; return RT_EOK;

3
drivers/board.h

@ -295,7 +295,8 @@ extern "C"
*/ */
/*#define BSP_USING_SDIO*/ /*#define BSP_USING_SDIO*/
#define BSP_USING_SDIO
#define BSP_USING_SDIO1
/*-------------------------- SDIO CONFIG END --------------------------*/ /*-------------------------- SDIO CONFIG END --------------------------*/
/*-------------------------- ETH CONFIG BEGIN --------------------------*/ /*-------------------------- ETH CONFIG BEGIN --------------------------*/

718
drivers/drv_sdio.c

@ -1,35 +1,35 @@
/* /*
* Copyright (c) 2006-2018, RT-Thread Development Team * Copyright (c) 2006-2020, RT-Thread Development Team
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2018-06-22 tyx first * 2020-05-23 liuduanfei first version
* 2018-12-12 balanceTWK first version
* 2019-06-11 WillianChan Add SD card hot plug detection
*/ */
#include "board.h" #include "board.h"
#include "drv_sdio.h"
#include "drv_config.h"
#include<rtthread.h>
#include<rtdevice.h>
#ifdef BSP_USING_SDIO #ifdef RT_USING_SDIO
//#define DRV_DEBUG #if !defined(BSP_USING_SDIO1) && !defined(BSP_USING_SDIO2)
#define LOG_TAG "drv.sdio" #error "Please define at least one BSP_USING_SDIOx"
#include <drv_log.h> #endif
static struct stm32_sdio_config sdio_config = SDIO_BUS_CONFIG; #include "drv_sdio.h"
static struct stm32_sdio_class sdio_obj;
static struct rt_mmcsd_host *host; //#define DRV_DEBUG
#define DBG_TAG "drv.sdio"
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif /* DRV_DEBUG */
#include <rtdbg.h>
#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000) static struct rt_mmcsd_host *host1;
static struct rt_mmcsd_host *host2;
#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER) #define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (1000000)
#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
struct sdio_pkg struct sdio_pkg
{ {
@ -43,22 +43,17 @@ struct rthw_sdio
struct rt_mmcsd_host *host; struct rt_mmcsd_host *host;
struct stm32_sdio_des sdio_des; struct stm32_sdio_des sdio_des;
struct rt_event event; struct rt_event event;
struct rt_mutex mutex;
struct sdio_pkg *pkg; struct sdio_pkg *pkg;
}; };
#ifndef ALIGN
ALIGN(SDIO_ALIGN_LEN) #define ALIGN(SDIO_ALIGN_LEN) __attribute__((aligned(SDIO_ALIGN_LEN)))
static rt_uint8_t cache_buf[SDIO_BUFF_SIZE]; //ALIGN(SDIO_ALIGN_LEN)
static __attribute__((section(".ram_d1"))) rt_uint8_t cache_buf[SDIO_BUFF_SIZE] __attribute__((aligned(32)));
static rt_uint32_t stm32_sdio_clk_get(struct stm32_sdio *hw_sdio) //static rt_uint8_t cache_buf[SDIO_BUFF_SIZE];
{
return SDIO_CLOCK_FREQ;
}
/** /**
* @brief This function get order from sdio. * @brief This function get order from sdio.
* @param data * @param data
* @retval sdio order * @retval sdio order
*/ */
static int get_order(rt_uint32_t data) static int get_order(rt_uint32_t data)
{ {
@ -115,43 +110,39 @@ static int get_order(rt_uint32_t data)
order = 0; order = 0;
break; break;
} }
return order; return order;
} }
/** /**
* @brief This function wait sdio completed. * @brief This function wait sdio cmd completed.
* @param sdio rthw_sdio * @param sdio rthw_sdio
* @retval None * @retval None
*/ */
static void rthw_sdio_wait_completed(struct rthw_sdio *sdio) static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
{ {
rt_uint32_t status; rt_uint32_t status;
struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd; struct rt_mmcsd_cmd *cmd = sdio->pkg->cmd;
struct rt_mmcsd_data *data = cmd->data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, if (rt_event_recv(&sdio->event, 0xffffffff, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
rt_tick_from_millisecond(5000), &status) != RT_EOK) rt_tick_from_millisecond(5000), &status) != RT_EOK)
{ {
LOG_E("wait completed timeout"); LOG_E("wait cmd completed timeout");
cmd->err = -RT_ETIMEOUT; cmd->err = -RT_ETIMEOUT;
return; return;
} }
if (sdio->pkg == RT_NULL) cmd->resp[0] = hw_sdio->resp1;
if (resp_type(cmd) == RESP_R2)
{ {
return; cmd->resp[1] = hw_sdio->resp2;
cmd->resp[2] = hw_sdio->resp3;
cmd->resp[3] = hw_sdio->resp4;
} }
cmd->resp[0] = hw_sdio->resp1; if (status & SDIO_ERRORS)
cmd->resp[1] = hw_sdio->resp2;
cmd->resp[2] = hw_sdio->resp3;
cmd->resp[3] = hw_sdio->resp4;
if (status & HW_SDIO_ERRORS)
{ {
if ((status & HW_SDIO_IT_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4))) if ((status & SDMMC_STA_CCRCFAIL) && (resp_type(cmd) & (RESP_R3 | RESP_R4)))
{ {
cmd->err = RT_EOK; cmd->err = RT_EOK;
} }
@ -159,103 +150,27 @@ static void rthw_sdio_wait_completed(struct rthw_sdio *sdio)
{ {
cmd->err = -RT_ERROR; cmd->err = -RT_ERROR;
} }
if (status & HW_SDIO_IT_CTIMEOUT)
{
cmd->err = -RT_ETIMEOUT;
}
if (status & HW_SDIO_IT_DCRCFAIL)
{
data->err = -RT_ERROR;
}
if (status & HW_SDIO_IT_DTIMEOUT)
{
data->err = -RT_ETIMEOUT;
}
if (cmd->err == RT_EOK)
{
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
}
else
{
LOG_D("err:0x%08x, %s%s%s%s%s%s%s cmd:%d arg:0x%08x rw:%c len:%d blksize:%d",
status,
status & HW_SDIO_IT_CCRCFAIL ? "CCRCFAIL " : "",
status & HW_SDIO_IT_DCRCFAIL ? "DCRCFAIL " : "",
status & HW_SDIO_IT_CTIMEOUT ? "CTIMEOUT " : "",
status & HW_SDIO_IT_DTIMEOUT ? "DTIMEOUT " : "",
status & HW_SDIO_IT_TXUNDERR ? "TXUNDERR " : "",
status & HW_SDIO_IT_RXOVERR ? "RXOVERR " : "",
status == 0 ? "NULL" : "",
cmd->cmd_code,
cmd->arg,
data ? (data->flags & DATA_DIR_WRITE ? 'w' : 'r') : '-',
data ? data->blks * data->blksize : 0,
data ? data->blksize : 0
);
}
} }
else else
{ {
cmd->err = RT_EOK; cmd->err = RT_EOK;
LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
} }
}
/**
* @brief This function transfer data by dma.
* @param sdio rthw_sdio
* @param pkg sdio package
* @retval None
*/
static void rthw_sdio_transfer_by_dma(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
{
struct rt_mmcsd_data *data;
int size;
void *buff;
struct stm32_sdio *hw_sdio;
if ((RT_NULL == pkg) || (RT_NULL == sdio)) if (cmd->err == RT_EOK)
{ {
LOG_E("rthw_sdio_transfer_by_dma invalid args"); LOG_D("sta:0x%08X [%08X %08X %08X %08X]", status, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
return;
}
data = pkg->cmd->data;
if (RT_NULL == data)
{
LOG_E("rthw_sdio_transfer_by_dma invalid args");
return;
}
buff = pkg->buff;
if (RT_NULL == buff)
{
LOG_E("rthw_sdio_transfer_by_dma invalid args");
return;
}
hw_sdio = sdio->sdio_des.hw_sdio;
size = data->blks * data->blksize;
if (data->flags & DATA_DIR_WRITE)
{
sdio->sdio_des.txconfig((rt_uint32_t *)buff, (rt_uint32_t *)&hw_sdio->fifo, size);
hw_sdio->dctrl |= HW_SDIO_DMA_ENABLE;
} }
else if (data->flags & DATA_DIR_READ) else
{ {
sdio->sdio_des.rxconfig((rt_uint32_t *)&hw_sdio->fifo, (rt_uint32_t *)buff, size); LOG_D("send command error = %d", cmd->err);
hw_sdio->dctrl |= HW_SDIO_DMA_ENABLE | HW_SDIO_DPSM_ENABLE;
} }
} }
/** /**
* @brief This function send command. * @brief This function send command.
* @param sdio rthw_sdio * @param sdio rthw_sdio
* @param pkg sdio package * @param pkg sdio package
* @retval None * @retval None
*/ */
static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg) static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
@ -265,10 +180,11 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
rt_uint32_t reg_cmd; rt_uint32_t reg_cmd;
rt_event_control(&sdio->event,RT_IPC_CMD_RESET,RT_NULL);
/* save pkg */ /* save pkg */
sdio->pkg = pkg; sdio->pkg = pkg;
LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d", LOG_D("CMD:%d ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d\n",
cmd->cmd_code, cmd->cmd_code,
cmd->arg, cmd->arg,
resp_type(cmd) == RESP_NONE ? "NONE" : "", resp_type(cmd) == RESP_NONE ? "NONE" : "",
@ -285,47 +201,30 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
data ? data->blksize : 0 data ? data->blksize : 0
); );
/* config cmd reg */ hw_sdio->mask |= SDIO_MASKR_ALL;
reg_cmd = cmd->cmd_code | HW_SDIO_CPSM_ENABLE; reg_cmd = cmd->cmd_code | SDMMC_CMD_CPSMEN;
if (resp_type(cmd) == RESP_NONE)
reg_cmd |= HW_SDIO_RESPONSE_NO;
else if (resp_type(cmd) == RESP_R2)
reg_cmd |= HW_SDIO_RESPONSE_LONG;
else
reg_cmd |= HW_SDIO_RESPONSE_SHORT;
/* config data reg */ /* data pre configuration */
if (data != RT_NULL) if (data != RT_NULL)
{ {
rt_uint32_t dir = 0; SCB_CleanInvalidateDCache();
rt_uint32_t size = data->blks * data->blksize;
int order;
hw_sdio->dctrl = 0; reg_cmd |= SDMMC_CMD_CMDTRANS;
hw_sdio->mask &= ~(SDMMC_MASK_CMDRENDIE | SDMMC_MASK_CMDSENTIE);
hw_sdio->dtimer = HW_SDIO_DATATIMEOUT; hw_sdio->dtimer = HW_SDIO_DATATIMEOUT;
hw_sdio->dlen = size; hw_sdio->dlen = data->blks * data->blksize;
order = get_order(data->blksize); hw_sdio->dctrl = (get_order(data->blksize)<<4) | (data->flags & DATA_DIR_READ ? SDMMC_DCTRL_DTDIR : 0);
dir = (data->flags & DATA_DIR_READ) ? HW_SDIO_TO_HOST : 0; hw_sdio->idmabase0r = (rt_uint32_t)cache_buf;
hw_sdio->dctrl = HW_SDIO_IO_ENABLE | (order << 4) | dir; hw_sdio->idmatrlr = SDMMC_IDMA_IDMAEN;
} }
/* transfer config */ if (resp_type(cmd) == RESP_R2)
if (data != RT_NULL) reg_cmd |= SDMMC_CMD_WAITRESP;
{ else if(resp_type(cmd) != RESP_NONE)
rthw_sdio_transfer_by_dma(sdio, pkg); reg_cmd |= SDMMC_CMD_WAITRESP_0;
}
/* open irq */
hw_sdio->mask |= HW_SDIO_IT_CMDSENT | HW_SDIO_IT_CMDREND | HW_SDIO_ERRORS;
if (data != RT_NULL)
{
hw_sdio->mask |= HW_SDIO_IT_DATAEND;
}
/* send cmd */
hw_sdio->arg = cmd->arg; hw_sdio->arg = cmd->arg;
hw_sdio->cmd = reg_cmd; hw_sdio->cmd = reg_cmd;
/* wait completed */ /* wait completed */
rthw_sdio_wait_completed(sdio); rthw_sdio_wait_completed(sdio);
@ -334,22 +233,26 @@ static void rthw_sdio_send_command(struct rthw_sdio *sdio, struct sdio_pkg *pkg)
{ {
volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS; volatile rt_uint32_t count = SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS;
while (count && (hw_sdio->sta & (HW_SDIO_IT_TXACT | HW_SDIO_IT_RXACT))) while (count && (hw_sdio->sta & SDMMC_STA_DPSMACT))
{ {
count--; count--;
} }
if ((count == 0) || (hw_sdio->sta & SDIO_ERRORS))
if ((count == 0) || (hw_sdio->sta & HW_SDIO_ERRORS))
{ {
cmd->err = -RT_ERROR; cmd->err = -RT_ERROR;
} }
} }
/* close irq, keep sdio irq */ /* data post configuration */
hw_sdio->mask = hw_sdio->mask & HW_SDIO_IT_SDIOIT ? HW_SDIO_IT_SDIOIT : 0x00; if (data != RT_NULL)
{
if (data->flags & DATA_DIR_READ)
{
rt_memcpy(data->buf, cache_buf, data->blks * data->blksize);
SCB_CleanInvalidateDCache();
/* clear pkg */ }
sdio->pkg = RT_NULL; }
} }
/** /**
@ -364,11 +267,9 @@ static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *r
struct rthw_sdio *sdio = host->private_data; struct rthw_sdio *sdio = host->private_data;
struct rt_mmcsd_data *data; struct rt_mmcsd_data *data;
RTHW_SDIO_LOCK(sdio);
if (req->cmd != RT_NULL) if (req->cmd != RT_NULL)
{ {
memset(&pkg, 0, sizeof(pkg)); rt_memset(&pkg, 0, sizeof(pkg));
data = req->cmd->data; data = req->cmd->data;
pkg.cmd = req->cmd; pkg.cmd = req->cmd;
@ -378,37 +279,43 @@ static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *r
RT_ASSERT(size <= SDIO_BUFF_SIZE); RT_ASSERT(size <= SDIO_BUFF_SIZE);
pkg.buff = data->buf; if (data->flags & DATA_DIR_WRITE)
if ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1))
{ {
pkg.buff = cache_buf; rt_memcpy(cache_buf, data->buf, size);
if (data->flags & DATA_DIR_WRITE)
{
memcpy(cache_buf, data->buf, size);
}
} }
} }
rthw_sdio_send_command(sdio, &pkg); rthw_sdio_send_command(sdio, &pkg);
if ((data != RT_NULL) && (data->flags & DATA_DIR_READ) && ((rt_uint32_t)data->buf & (SDIO_ALIGN_LEN - 1)))
{
memcpy(data->buf, cache_buf, data->blksize * data->blks);
}
} }
if (req->stop != RT_NULL) if (req->stop != RT_NULL)
{ {
memset(&pkg, 0, sizeof(pkg)); rt_memset(&pkg, 0, sizeof(pkg));
pkg.cmd = req->stop; pkg.cmd = req->stop;
rthw_sdio_send_command(sdio, &pkg); rthw_sdio_send_command(sdio, &pkg);
} }
RTHW_SDIO_UNLOCK(sdio);
mmcsd_req_complete(sdio->host); mmcsd_req_complete(sdio->host);
} }
/**
* @brief This function interrupt process function.
* @param host rt_mmcsd_host
* @retval None
*/
void rthw_sdio_irq_process(struct rt_mmcsd_host *host)
{
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
rt_uint32_t intstatus = hw_sdio->sta;
/* clear irq flag*/
hw_sdio->icr = intstatus;
rt_event_send(&sdio->event, intstatus);
}
/** /**
* @brief This function config sdio. * @brief This function config sdio.
* @param host rt_mmcsd_host * @param host rt_mmcsd_host
@ -417,28 +324,13 @@ static void rthw_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *r
*/ */
static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
{ {
rt_uint32_t clkcr, div, clk_src; rt_uint32_t temp, clk_src;
rt_uint32_t clk = io_cfg->clock; rt_uint32_t clk = io_cfg->clock;
struct rthw_sdio *sdio = host->private_data; struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio; struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
clk_src = sdio->sdio_des.clk_get(sdio->sdio_des.hw_sdio); LOG_D("clk:%dK width:%s%s%s power:%s%s%s",
if (clk_src < 400 * 1000) clk/1000,
{
LOG_E("The clock rate is too low! rata:%d", clk_src);
return;
}
if (clk > host->freq_max) clk = host->freq_max;
if (clk > clk_src)
{
LOG_W("Setting rate is greater than clock source rate.");
clk = clk_src;
}
LOG_D("clk:%d width:%s%s%s power:%s%s%s",
clk,
io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "", io_cfg->bus_width == MMCSD_BUS_WIDTH_8 ? "8" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "", io_cfg->bus_width == MMCSD_BUS_WIDTH_4 ? "4" : "",
io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "", io_cfg->bus_width == MMCSD_BUS_WIDTH_1 ? "1" : "",
@ -447,172 +339,39 @@ static void rthw_sdio_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *
io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : "" io_cfg->power_mode == MMCSD_POWER_ON ? "ON" : ""
); );
RTHW_SDIO_LOCK(sdio); clk_src = SDIO_CLOCK_FREQ;
div = clk_src / clk; if (clk > 0)
if ((clk == 0) || (div == 0))
{ {
clkcr = 0; if (clk > host->freq_max)
} clk = host->freq_max;
else temp = DIV_ROUND_UP(clk_src, 2 * clk);
{ if (temp > 0x3FF)
if (div < 2) temp = 0x3FF;
{
div = 2;
}
else if (div > 0xFF)
{
div = 0xFF;
}
div -= 2;
clkcr = div | HW_SDIO_CLK_ENABLE;
} }
if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8) if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
{ temp |= SDMMC_CLKCR_WIDBUS_0;
clkcr |= HW_SDIO_BUSWIDE_8B; else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
} temp |= SDMMC_CLKCR_WIDBUS_1;
else if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
{
clkcr |= HW_SDIO_BUSWIDE_4B;
}
else
{
clkcr |= HW_SDIO_BUSWIDE_1B;
}
hw_sdio->clkcr = clkcr; hw_sdio->clkcr = temp;
switch (io_cfg->power_mode) if (io_cfg->power_mode == MMCSD_POWER_ON)
{ hw_sdio->power |= SDMMC_POWER_PWRCTRL;
case MMCSD_POWER_OFF:
hw_sdio->power = HW_SDIO_POWER_OFF;
break;
case MMCSD_POWER_UP:
hw_sdio->power = HW_SDIO_POWER_UP;
break;
case MMCSD_POWER_ON:
hw_sdio->power = HW_SDIO_POWER_ON;
break;
default:
LOG_W("unknown power_mode %d", io_cfg->power_mode);
break;
}
RTHW_SDIO_UNLOCK(sdio);
}
/**
* @brief This function update sdio interrupt.
* @param host rt_mmcsd_host
* @param enable
* @retval None
*/
void rthw_sdio_irq_update(struct rt_mmcsd_host *host, rt_int32_t enable)
{
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
if (enable)
{
LOG_D("enable sdio irq");
hw_sdio->mask |= HW_SDIO_IT_SDIOIT;
}
else
{
LOG_D("disable sdio irq");
hw_sdio->mask &= ~HW_SDIO_IT_SDIOIT;
}
}
/**
* @brief This function delect sdcard.
* @param host rt_mmcsd_host
* @retval 0x01
*/
static rt_int32_t rthw_sd_delect(struct rt_mmcsd_host *host)
{
LOG_D("try to detect device");
return 0x01;
}
/**
* @brief This function interrupt process function.
* @param host rt_mmcsd_host
* @retval None
*/
void rthw_sdio_irq_process(struct rt_mmcsd_host *host)
{
int complete = 0;
struct rthw_sdio *sdio = host->private_data;
struct stm32_sdio *hw_sdio = sdio->sdio_des.hw_sdio;
rt_uint32_t intstatus = hw_sdio->sta;
if (intstatus & HW_SDIO_ERRORS)
{
hw_sdio->icr = HW_SDIO_ERRORS;
complete = 1;
}
else
{
if (intstatus & HW_SDIO_IT_CMDREND)
{
hw_sdio->icr = HW_SDIO_IT_CMDREND;
if (sdio->pkg != RT_NULL)
{
if (!sdio->pkg->cmd->data)
{
complete = 1;
}
else if ((sdio->pkg->cmd->data->flags & DATA_DIR_WRITE))
{
hw_sdio->dctrl |= HW_SDIO_DPSM_ENABLE;
}
}
}
if (intstatus & HW_SDIO_IT_CMDSENT)
{
hw_sdio->icr = HW_SDIO_IT_CMDSENT;
if (resp_type(sdio->pkg->cmd) == RESP_NONE)
{
complete = 1;
}
}
if (intstatus & HW_SDIO_IT_DATAEND)
{
hw_sdio->icr = HW_SDIO_IT_DATAEND;
complete = 1;
}
}
if ((intstatus & HW_SDIO_IT_SDIOIT) && (hw_sdio->mask & HW_SDIO_IT_SDIOIT))
{
hw_sdio->icr = HW_SDIO_IT_SDIOIT;
sdio_irq_wakeup(host);
}
if (complete)
{
hw_sdio->mask &= ~HW_SDIO_ERRORS;
rt_event_send(&sdio->event, intstatus);
}
} }
static const struct rt_mmcsd_host_ops ops = static const struct rt_mmcsd_host_ops ops =
{ {
rthw_sdio_request, rthw_sdio_request,
rthw_sdio_iocfg, rthw_sdio_iocfg,
rthw_sd_delect, RT_NULL,
rthw_sdio_irq_update, RT_NULL,
}; };
/** /**
* @brief This function create mmcsd host. * @brief This function create mmcsd host.
* @param sdio_des stm32_sdio_des * @param sdio_des stm32_sdio_des
* @retval rt_mmcsd_host * @retval rt_mmcsd_host
*/ */
struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des) struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
@ -620,20 +379,15 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
struct rt_mmcsd_host *host; struct rt_mmcsd_host *host;
struct rthw_sdio *sdio = RT_NULL; struct rthw_sdio *sdio = RT_NULL;
if ((sdio_des == RT_NULL) || (sdio_des->txconfig == RT_NULL) || (sdio_des->rxconfig == RT_NULL)) if (sdio_des == RT_NULL)
{ {
LOG_E("L:%d F:%s %s %s %s",
(sdio_des == RT_NULL ? "sdio_des is NULL" : ""),
(sdio_des ? (sdio_des->txconfig ? "txconfig is NULL" : "") : ""),
(sdio_des ? (sdio_des->rxconfig ? "rxconfig is NULL" : "") : "")
);
return RT_NULL; return RT_NULL;
} }
sdio = rt_malloc(sizeof(struct rthw_sdio)); sdio = rt_malloc(sizeof(struct rthw_sdio));
if (sdio == RT_NULL) if (sdio == RT_NULL)
{ {
LOG_E("L:%d F:%s malloc rthw_sdio fail"); LOG_E("malloc rthw_sdio fail");
return RT_NULL; return RT_NULL;
} }
rt_memset(sdio, 0, sizeof(struct rthw_sdio)); rt_memset(sdio, 0, sizeof(struct rthw_sdio));
@ -641,28 +395,33 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
host = mmcsd_alloc_host(); host = mmcsd_alloc_host();
if (host == RT_NULL) if (host == RT_NULL)
{ {
LOG_E("L:%d F:%s mmcsd alloc host fail"); LOG_E("alloc host fail");
rt_free(sdio); goto err;
return RT_NULL;
} }
rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des)); rt_memcpy(&sdio->sdio_des, sdio_des, sizeof(struct stm32_sdio_des));
sdio->sdio_des.hw_sdio = (sdio_des->hw_sdio == RT_NULL ? (struct stm32_sdio *)SDIO_BASE_ADDRESS : sdio_des->hw_sdio);
sdio->sdio_des.clk_get = (sdio_des->clk_get == RT_NULL ? stm32_sdio_clk_get : sdio_des->clk_get);
rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO); if(sdio_des->hsd.Instance == SDMMC1){
rt_mutex_init(&sdio->mutex, "sdio", RT_IPC_FLAG_FIFO); sdio->sdio_des.hw_sdio = (struct stm32_sdio *)SDIO1_BASE_ADDRESS;
rt_event_init(&sdio->event, "sdio", RT_IPC_FLAG_FIFO);
}
if(sdio_des->hsd.Instance == SDMMC2){
sdio->sdio_des.hw_sdio = (struct stm32_sdio *)SDIO2_BASE_ADDRESS;
rt_event_init(&sdio->event, "sdio2", RT_IPC_FLAG_FIFO);
}
/* set host defautl attributes */ /* set host default attributes */
host->ops = &ops; host->ops = &ops;
host->freq_min = 400 * 1000; host->freq_min = 400 * 1000;
host->freq_max = SDIO_MAX_FREQ; host->freq_max = SDIO_MAX_FREQ;
host->valid_ocr = 0X00FFFF80;/* The voltage range supported is 1.65v-3.6v */ host->valid_ocr = VDD_32_33 | VDD_33_34;/* The voltage range supported is 3.2v-3.4v */
#ifndef SDIO_USING_1_BIT //#ifndef SDIO_USING_1_BIT
host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ; host->flags = MMCSD_BUSWIDTH_4 | MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED;
#else //#else
host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_SDIO_IRQ; // host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED;
#endif //#endif
host->max_seg_size = SDIO_BUFF_SIZE; host->max_seg_size = SDIO_BUFF_SIZE;
host->max_dma_segs = 1; host->max_dma_segs = 1;
host->max_blk_size = 512; host->max_blk_size = 512;
@ -672,218 +431,75 @@ struct rt_mmcsd_host *sdio_host_create(struct stm32_sdio_des *sdio_des)
sdio->host = host; sdio->host = host;
host->private_data = sdio; host->private_data = sdio;
rthw_sdio_irq_update(host, 1);
/* ready to change */ /* ready to change */
mmcsd_change(host); mmcsd_change(host);
return host; return host;
}
/** err:
* @brief This function configures the DMATX. if (sdio) rt_free(sdio);
* @param BufferSRC: pointer to the source buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_TxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
{
#if defined(SOC_SERIES_STM32F1)
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
/* DMA_PFCTRL */
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#elif defined(SOC_SERIES_STM32L4)
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Request = sdio_config.dma_tx.request;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.Mode = DMA_NORMAL;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#else
static uint32_t size = 0;
size += BufferSize * 4;
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_tx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_tx.Init.Channel = sdio_config.dma_tx.channel;
sdio_obj.dma.handle_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
sdio_obj.dma.handle_tx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_tx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_tx.Init.Mode = DMA_PFCTRL;
sdio_obj.dma.handle_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
sdio_obj.dma.handle_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
sdio_obj.dma.handle_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
sdio_obj.dma.handle_tx.Init.MemBurst = DMA_MBURST_INC4;
sdio_obj.dma.handle_tx.Init.PeriphBurst = DMA_PBURST_INC4;
/* DMA_PFCTRL */
HAL_DMA_DeInit(&sdio_obj.dma.handle_tx);
HAL_DMA_Init(&sdio_obj.dma.handle_tx);
HAL_DMA_Start(&sdio_obj.dma.handle_tx, (uint32_t)src, (uint32_t)dst, BufferSize);
#endif
}
/** return RT_NULL;
* @brief This function configures the DMARX.
* @param BufferDST: pointer to the destination buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_RxConfig(uint32_t *src, uint32_t *dst, uint32_t BufferSize)
{
#if defined(SOC_SERIES_STM32F1)
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#elif defined(SOC_SERIES_STM32L4)
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Request = sdio_config.dma_tx.request;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.Mode = DMA_NORMAL;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#else
sdio_obj.cfg = &sdio_config;
sdio_obj.dma.handle_rx.Instance = sdio_config.dma_tx.Instance;
sdio_obj.dma.handle_rx.Init.Channel = sdio_config.dma_tx.channel;
sdio_obj.dma.handle_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
sdio_obj.dma.handle_rx.Init.PeriphInc = DMA_PINC_DISABLE;
sdio_obj.dma.handle_rx.Init.MemInc = DMA_MINC_ENABLE;
sdio_obj.dma.handle_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
sdio_obj.dma.handle_rx.Init.Mode = DMA_PFCTRL;
sdio_obj.dma.handle_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
sdio_obj.dma.handle_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
sdio_obj.dma.handle_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
sdio_obj.dma.handle_rx.Init.MemBurst = DMA_MBURST_INC4;
sdio_obj.dma.handle_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_DeInit(&sdio_obj.dma.handle_rx);
HAL_DMA_Init(&sdio_obj.dma.handle_rx);
HAL_DMA_Start(&sdio_obj.dma.handle_rx, (uint32_t)src, (uint32_t)dst, BufferSize);
#endif
}
/**
* @brief This function get stm32 sdio clock.
* @param hw_sdio: stm32_sdio
* @retval PCLK2Freq
*/
static rt_uint32_t stm32_sdio_clock_get(struct stm32_sdio *hw_sdio)
{
return HAL_RCC_GetPCLK2Freq();
} }
static rt_err_t DMA_TxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size) void SDMMC1_IRQHandler(void)
{ {
SD_LowLevel_DMA_TxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4); /* enter interrupt */
return RT_EOK; rt_interrupt_enter();
} /* Process All SDIO Interrupt Sources */
if (host1) rthw_sdio_irq_process(host1);
static rt_err_t DMA_RxConfig(rt_uint32_t *src, rt_uint32_t *dst, int Size) /* leave interrupt */
{ rt_interrupt_leave();
SD_LowLevel_DMA_RxConfig((uint32_t *)src, (uint32_t *)dst, Size / 4);
return RT_EOK;
} }
void SDIO_IRQHandler(void) void SDMMC2_IRQHandler(void)
{ {
/* enter interrupt */ /* enter interrupt */
rt_interrupt_enter(); rt_interrupt_enter();
/* Process All SDIO Interrupt Sources */ /* Process All SDIO Interrupt Sources */
rthw_sdio_irq_process(host); if (host2) rthw_sdio_irq_process(host2);
/* leave interrupt */ /* leave interrupt */
rt_interrupt_leave(); rt_interrupt_leave();
} }
int rt_hw_sdio_init(void) int rt_hw_sdio_init(void)
{ {
struct stm32_sdio_des sdio_des; #ifdef BSP_USING_SDIO1
SD_HandleTypeDef hsd; struct stm32_sdio_des sdio_des1;
hsd.Instance = SDCARD_INSTANCE; sdio_des1.hsd.Instance = SDMMC1;
HAL_SD_MspInit(&sdio_des1.hsd);
host1 = sdio_host_create(&sdio_des1);
if (host1 == RT_NULL)
{ {
rt_uint32_t tmpreg = 0x00U; LOG_E("host create fail");
#if defined(SOC_SERIES_STM32F1) return RT_NULL;
/* enable DMA clock && Delay after an RCC peripheral clock enabling*/
SET_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
tmpreg = READ_BIT(RCC->AHBENR, sdio_config.dma_rx.dma_rcc);
#elif defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4)
SET_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHB1ENR, sdio_config.dma_rx.dma_rcc);
#endif
UNUSED(tmpreg); /* To avoid compiler warnings */
} }
HAL_NVIC_SetPriority(SDIO_IRQn, 2, 0); #endif
HAL_NVIC_EnableIRQ(SDIO_IRQn);
HAL_SD_MspInit(&hsd);
sdio_des.clk_get = stm32_sdio_clock_get; #ifdef BSP_USING_SDIO2
sdio_des.hw_sdio = (struct stm32_sdio *)SDCARD_INSTANCE; //sdmmc2 wifi
sdio_des.rxconfig = DMA_RxConfig; struct stm32_sdio_des sdio_des2;
sdio_des.txconfig = DMA_TxConfig; sdio_des2.hsd.Instance = SDMMC2;
HAL_SD_MspInit(&sdio_des2.hsd);
host = sdio_host_create(&sdio_des); host2 = sdio_host_create(&sdio_des2);
if (host == RT_NULL) if (host2 == RT_NULL)
{ {
LOG_E("host create fail"); LOG_E("host2 create fail");
return -1; return RT_NULL;
} }
#endif
return 0; return 0;
} }
INIT_DEVICE_EXPORT(rt_hw_sdio_init); INIT_DEVICE_EXPORT(rt_hw_sdio_init);
void stm32_mmcsd_change(void) void sdcard_change(void)
{ {
mmcsd_change(host); mmcsd_change(host1);
} }
#endif /* RT_USING_SDIO */
#endif #endif

194
drivers/include/drv_sdio.h

@ -1,52 +1,38 @@
/* /*
* Copyright (c) 2006-2018, RT-Thread Development Team * Copyright (c) 2006-2020, RT-Thread Development Team
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2018-12-13 BalanceTWK first version * 2020-05-23 liuduanfei first version
* 2019-06-11 WillianChan Add SD card hot plug detection * 2020-08-25 wanghaijing add sdmmmc2
*/ */
#ifndef _DRV_SDIO_H #ifndef __DRV_SDIO_H__
#define _DRV_SDIO_H #define __DRV_SDIO_H__
#include <rtthread.h> #include <rtthread.h>
#include "rtdevice.h" #include "rtdevice.h"
#include <rthw.h> #include <rthw.h>
#include <drv_common.h> #include <drv_common.h>
#include "drv_dma.h"
#include <string.h> #include <string.h>
#include <drivers/mmcsd_core.h> #include <drivers/mmcsd_core.h>
#include <drivers/sdio.h> #include <drivers/sdio.h>
#ifdef BSP_USING_SDIO
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4)
#define SDCARD_INSTANCE_TYPE SDIO_TypeDef
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
#define SDCARD_INSTANCE_TYPE SDMMC_TypeDef
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */
#if defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4)
#define SDCARD_INSTANCE SDIO
#elif defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32F7)
#define SDCARD_INSTANCE SDMMC1
#endif /* defined(SOC_SERIES_STM32F1) || defined(SOC_SERIES_STM32F4) */
#define SDIO_BUFF_SIZE 4096 #define SDIO_BUFF_SIZE 4096
#define SDIO_ALIGN_LEN 32 #define SDIO_ALIGN_LEN 32
#ifndef SDIO_MAX_FREQ #ifndef SDIO1_BASE_ADDRESS
#define SDIO_MAX_FREQ (1000000) #define SDIO1_BASE_ADDRESS (0x52007000)
#endif #endif
#ifndef SDIO_BASE_ADDRESS #ifndef SDIO2_BASE_ADDRESS
#define SDIO_BASE_ADDRESS (0x40012800U) #define SDIO2_BASE_ADDRESS (0x48022400)
#endif #endif
#ifndef SDIO_CLOCK_FREQ #ifndef SDIO_CLOCK_FREQ
#define SDIO_CLOCK_FREQ (48U * 1000 * 1000) #define SDIO_CLOCK_FREQ (150U * 1000 * 1000)
#endif #endif
#ifndef SDIO_BUFF_SIZE #ifndef SDIO_BUFF_SIZE
@ -58,126 +44,59 @@
#endif #endif
#ifndef SDIO_MAX_FREQ #ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (24 * 1000 * 1000) #define SDIO_MAX_FREQ (25 * 1000 * 1000)
#endif #endif
#define HW_SDIO_IT_CCRCFAIL (0x01U << 0) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define HW_SDIO_IT_DCRCFAIL (0x01U << 1)
#define HW_SDIO_IT_CTIMEOUT (0x01U << 2) #define SDIO_ERRORS \
#define HW_SDIO_IT_DTIMEOUT (0x01U << 3) (SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
#define HW_SDIO_IT_TXUNDERR (0x01U << 4) SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \
#define HW_SDIO_IT_RXOVERR (0x01U << 5) SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \
#define HW_SDIO_IT_CMDREND (0x01U << 6) SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL)
#define HW_SDIO_IT_CMDSENT (0x01U << 7)
#define HW_SDIO_IT_DATAEND (0x01U << 8) #define SDIO_MASKR_ALL \
#define HW_SDIO_IT_STBITERR (0x01U << 9) (SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \
#define HW_SDIO_IT_DBCKEND (0x01U << 10) SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \
#define HW_SDIO_IT_CMDACT (0x01U << 11) SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE)
#define HW_SDIO_IT_TXACT (0x01U << 12)
#define HW_SDIO_IT_RXACT (0x01U << 13) #define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU)
#define HW_SDIO_IT_TXFIFOHE (0x01U << 14)
#define HW_SDIO_IT_RXFIFOHF (0x01U << 15)
#define HW_SDIO_IT_TXFIFOF (0x01U << 16)
#define HW_SDIO_IT_RXFIFOF (0x01U << 17)
#define HW_SDIO_IT_TXFIFOE (0x01U << 18)
#define HW_SDIO_IT_RXFIFOE (0x01U << 19)
#define HW_SDIO_IT_TXDAVL (0x01U << 20)
#define HW_SDIO_IT_RXDAVL (0x01U << 21)
#define HW_SDIO_IT_SDIOIT (0x01U << 22)
#define HW_SDIO_ERRORS \
(HW_SDIO_IT_CCRCFAIL | HW_SDIO_IT_CTIMEOUT | \
HW_SDIO_IT_DCRCFAIL | HW_SDIO_IT_DTIMEOUT | \
HW_SDIO_IT_RXOVERR | HW_SDIO_IT_TXUNDERR)
#define HW_SDIO_POWER_OFF (0x00U)
#define HW_SDIO_POWER_UP (0x02U)
#define HW_SDIO_POWER_ON (0x03U)
#define HW_SDIO_FLOW_ENABLE (0x01U << 14)
#define HW_SDIO_BUSWIDE_1B (0x00U << 11)
#define HW_SDIO_BUSWIDE_4B (0x01U << 11)
#define HW_SDIO_BUSWIDE_8B (0x02U << 11)
#define HW_SDIO_BYPASS_ENABLE (0x01U << 10)
#define HW_SDIO_IDLE_ENABLE (0x01U << 9)
#define HW_SDIO_CLK_ENABLE (0x01U << 8)
#define HW_SDIO_SUSPEND_CMD (0x01U << 11)
#define HW_SDIO_CPSM_ENABLE (0x01U << 10)
#define HW_SDIO_WAIT_END (0x01U << 9)
#define HW_SDIO_WAIT_INT (0x01U << 8)
#define HW_SDIO_RESPONSE_NO (0x00U << 6)
#define HW_SDIO_RESPONSE_SHORT (0x01U << 6)
#define HW_SDIO_RESPONSE_LONG (0x03U << 6)
#define HW_SDIO_DATA_LEN_MASK (0x01FFFFFFU)
#define HW_SDIO_IO_ENABLE (0x01U << 11)
#define HW_SDIO_RWMOD_CK (0x01U << 10)
#define HW_SDIO_RWSTOP_ENABLE (0x01U << 9)
#define HW_SDIO_RWSTART_ENABLE (0x01U << 8)
#define HW_SDIO_DBLOCKSIZE_1 (0x00U << 4)
#define HW_SDIO_DBLOCKSIZE_2 (0x01U << 4)
#define HW_SDIO_DBLOCKSIZE_4 (0x02U << 4)
#define HW_SDIO_DBLOCKSIZE_8 (0x03U << 4)
#define HW_SDIO_DBLOCKSIZE_16 (0x04U << 4)
#define HW_SDIO_DBLOCKSIZE_32 (0x05U << 4)
#define HW_SDIO_DBLOCKSIZE_64 (0x06U << 4)
#define HW_SDIO_DBLOCKSIZE_128 (0x07U << 4)
#define HW_SDIO_DBLOCKSIZE_256 (0x08U << 4)
#define HW_SDIO_DBLOCKSIZE_512 (0x09U << 4)
#define HW_SDIO_DBLOCKSIZE_1024 (0x0AU << 4)
#define HW_SDIO_DBLOCKSIZE_2048 (0x0BU << 4)
#define HW_SDIO_DBLOCKSIZE_4096 (0x0CU << 4)
#define HW_SDIO_DBLOCKSIZE_8192 (0x0DU << 4)
#define HW_SDIO_DBLOCKSIZE_16384 (0x0EU << 4)
#define HW_SDIO_DMA_ENABLE (0x01U << 3)
#define HW_SDIO_STREAM_ENABLE (0x01U << 2)
#define HW_SDIO_TO_HOST (0x01U << 1)
#define HW_SDIO_DPSM_ENABLE (0x01U << 0)
#define HW_SDIO_DATATIMEOUT (0xF0000000U)
struct stm32_sdio struct stm32_sdio
{ {
volatile rt_uint32_t power; volatile rt_uint32_t power; /* offset 0x00 */
volatile rt_uint32_t clkcr; volatile rt_uint32_t clkcr; /* offset 0x04 */
volatile rt_uint32_t arg; volatile rt_uint32_t arg; /* offset 0x08 */
volatile rt_uint32_t cmd; volatile rt_uint32_t cmd; /* offset 0x0C */
volatile rt_uint32_t respcmd; volatile rt_uint32_t respcmd; /* offset 0x10 */
volatile rt_uint32_t resp1; volatile rt_uint32_t resp1; /* offset 0x14 */
volatile rt_uint32_t resp2; volatile rt_uint32_t resp2; /* offset 0x18 */
volatile rt_uint32_t resp3; volatile rt_uint32_t resp3; /* offset 0x1C */
volatile rt_uint32_t resp4; volatile rt_uint32_t resp4; /* offset 0x20 */
volatile rt_uint32_t dtimer; volatile rt_uint32_t dtimer; /* offset 0x24 */
volatile rt_uint32_t dlen; volatile rt_uint32_t dlen; /* offset 0x28 */
volatile rt_uint32_t dctrl; volatile rt_uint32_t dctrl; /* offset 0x2C */
volatile rt_uint32_t dcount; volatile rt_uint32_t dcount; /* offset 0x30 */
volatile rt_uint32_t sta; volatile rt_uint32_t sta; /* offset 0x34 */
volatile rt_uint32_t icr; volatile rt_uint32_t icr; /* offset 0x38 */
volatile rt_uint32_t mask; volatile rt_uint32_t mask; /* offset 0x3C */
volatile rt_uint32_t reserved0[2]; volatile rt_uint32_t acktimer; /* offset 0x40 */
volatile rt_uint32_t fifocnt; volatile rt_uint32_t reserved0[3]; /* offset 0x44 ~ 0x4C */
volatile rt_uint32_t reserved1[13]; volatile rt_uint32_t idmatrlr; /* offset 0x50 */
volatile rt_uint32_t fifo; volatile rt_uint32_t idmabsizer; /* offset 0x54 */
volatile rt_uint32_t idmabase0r; /* offset 0x58 */
volatile rt_uint32_t idmabase1r; /* offset 0x5C */
volatile rt_uint32_t reserved1[8]; /* offset 0x60 ~ 7C */
volatile rt_uint32_t fifo; /* offset 0x80 */
}; };
typedef rt_err_t (*dma_txconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
typedef rt_err_t (*dma_rxconfig)(rt_uint32_t *src, rt_uint32_t *dst, int size);
typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio); typedef rt_uint32_t (*sdio_clk_get)(struct stm32_sdio *hw_sdio);
struct stm32_sdio_des struct stm32_sdio_des
{ {
struct stm32_sdio *hw_sdio; struct stm32_sdio *hw_sdio;
dma_txconfig txconfig;
dma_rxconfig rxconfig;
sdio_clk_get clk_get; sdio_clk_get clk_get;
}; SD_HandleTypeDef hsd;
struct stm32_sdio_config
{
SDCARD_INSTANCE_TYPE *Instance;
struct dma_config dma_rx, dma_tx;
}; };
/* stm32 sdio dirver class */ /* stm32 sdio dirver class */
@ -186,15 +105,8 @@ struct stm32_sdio_class
struct stm32_sdio_des *des; struct stm32_sdio_des *des;
const struct stm32_sdio_config *cfg; const struct stm32_sdio_config *cfg;
struct rt_mmcsd_host host; struct rt_mmcsd_host host;
struct
{
DMA_HandleTypeDef handle_rx;
DMA_HandleTypeDef handle_tx;
} dma;
}; };
extern void stm32_mmcsd_change(void); extern void sdcard_change(void);
#endif
#endif /* BSP_USING_SDIO */ #endif /* __DRV_SDIO_H__ */

4
rtconfig.h

@ -122,6 +122,9 @@
#define RT_MMCSD_STACK_SIZE 1024 #define RT_MMCSD_STACK_SIZE 1024
#define RT_MMCSD_THREAD_PREORITY 22 #define RT_MMCSD_THREAD_PREORITY 22
#define RT_MMCSD_MAX_PARTITION 16 #define RT_MMCSD_MAX_PARTITION 16
#define RT_USING_SPI
#define RT_USING_QSPI
#define RT_USING_SPI_MSD
#define RT_USING_PIN #define RT_USING_PIN
/* Using USB */ /* Using USB */
@ -144,6 +147,7 @@
/* POSIX (Portable Operating System Interface) layer */ /* POSIX (Portable Operating System Interface) layer */
#define RT_USING_POSIX_FS
/* Interprocess Communication (IPC) */ /* Interprocess Communication (IPC) */

Loading…
Cancel
Save