Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
人间散章
rt-thread
提交
840af38d
R
rt-thread
项目概览
人间散章
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
840af38d
编写于
12月 02, 2020
作者:
T
thread-liu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[add] sdmmc (sd_card and emmc) driver.
上级
3767a089
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
1385 addition
and
12 deletion
+1385
-12
bsp/stm32/libraries/STM32MPxx_HAL/SConscript
bsp/stm32/libraries/STM32MPxx_HAL/SConscript
+1
-9
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
...-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
+3
-1
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
...a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
+236
-0
bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
+26
-0
bsp/stm32/stm32mp157a-st-ev1/board/SConscript
bsp/stm32/stm32mp157a-st-ev1/board/SConscript
+6
-1
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c
+593
-0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h
+104
-0
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
+3
-1
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c
+413
-0
未找到文件。
bsp/stm32/libraries/STM32MPxx_HAL/SConscript
浏览文件 @
840af38d
...
...
@@ -35,10 +35,6 @@ if GetDepend(['RT_USING_SERIAL']):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_uart.c'
]
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_uart_ex.c'
]
#if GetDepend(['RT_USING_SPI']):
# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_spi.c']
# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_qspi.c']
if
GetDepend
([
'RT_USING_USB_HOST'
])
or
GetDepend
([
'RT_USING_USB_DEVICE'
]):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_pccard.c'
]
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_pcd.c'
]
...
...
@@ -49,11 +45,6 @@ if GetDepend(['RT_USING_USB_HOST']) or GetDepend(['RT_USING_USB_DEVICE']):
if
GetDepend
([
'RT_USING_CAN'
]):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_can.c'
]
#if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']) or GetDepend(['RT_USING_PULSE_ENCODER']):
# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_tim.c']
# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_tim_ex.c']
# src += ['STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_lptim.c']
if
GetDepend
([
'BSP_USING_ETH'
]):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_eth.c'
]
...
...
@@ -73,6 +64,7 @@ if GetDepend(['RT_USING_WDT']):
if
GetDepend
([
'RT_USING_SDIO'
]):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_sdmmc.c'
]
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_sd.c'
]
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_ll_delayblock.c'
]
if
GetDepend
([
'RT_USING_AUDIO'
]):
src
+=
[
'STM32MP1xx_HAL_Driver/Src/stm32mp1xx_hal_i2s.c'
]
...
...
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Inc/stm32mp1xx_hal_conf.h
浏览文件 @
840af38d
...
...
@@ -58,7 +58,7 @@
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
/*#define HAL_SAI_MODULE_ENABLED */
/*#define HAL_SD_MODULE_ENABLED */
#define HAL_SD_MODULE_ENABLED
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
...
...
@@ -153,6 +153,8 @@
#define CSI_VALUE 4000000U
/*!< Value of the Internal oscillator in Hz*/
#endif
/* CSI_VALUE */
#define USE_SD_TRANSCEIVER 1U
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
...
...
bsp/stm32/stm32mp157a-st-ev1/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
浏览文件 @
840af38d
...
...
@@ -965,6 +965,242 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hI2c)
}
}
/**
* @brief SD MSP Initialization
* This function configures the hardware resources used in this example
* @param hsd: SD handle pointer
* @retval None
*/
void
HAL_SD_MspInit
(
SD_HandleTypeDef
*
hsd
)
{
GPIO_InitTypeDef
GPIO_InitStruct
=
{
0
};
RCC_PeriphCLKInitTypeDef
PeriphClkInit
=
{
0
};
if
(
hsd
->
Instance
==
SDMMC1
)
{
/* USER CODE BEGIN SDMMC1_MspInit 0 */
if
(
IS_ENGINEERING_BOOT_MODE
())
{
/** Initializes the peripherals clock
*/
PeriphClkInit
.
Sdmmc12ClockSelection
=
RCC_SDMMC12CLKSOURCE_PLL4
;
PeriphClkInit
.
PeriphClockSelection
=
RCC_PERIPHCLK_SDMMC12
;
if
(
HAL_RCCEx_PeriphCLKConfig
(
&
PeriphClkInit
)
!=
HAL_OK
)
{
Error_Handler
();
}
}
/* USER CODE END SDMMC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDMMC1_CLK_ENABLE
();
__HAL_RCC_GPIOB_CLK_ENABLE
();
__HAL_RCC_GPIOC_CLK_ENABLE
();
__HAL_RCC_GPIOD_CLK_ENABLE
();
__HAL_RCC_GPIOE_CLK_ENABLE
();
__HAL_RCC_GPIOF_CLK_ENABLE
();
/**SDMMC1 GPIO Configuration
PB9 ------> SDMMC1_CDIR
PC7 ------> SDMMC1_D123DIR
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
PE4 ------> SDMMC1_CKIN
PF2 ------> SDMMC1_D0DIR
*/
GPIO_InitStruct
.
Pin
=
GPIO_PIN_9
;
GPIO_InitStruct
.
Mode
=
GPIO_MODE_AF_PP
;
GPIO_InitStruct
.
Pull
=
GPIO_PULLUP
;
GPIO_InitStruct
.
Speed
=
GPIO_SPEED_FREQ_VERY_HIGH
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF11_SDIO1
;
HAL_GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_2
;
HAL_GPIO_Init
(
GPIOF
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_7
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF8_SDIO1
;
HAL_GPIO_Init
(
GPIOC
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_4
;
HAL_GPIO_Init
(
GPIOE
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_8
|
GPIO_PIN_9
|
GPIO_PIN_10
|
GPIO_PIN_11
|
GPIO_PIN_12
;
GPIO_InitStruct
.
Pull
=
GPIO_NOPULL
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF12_SDIO1
;
HAL_GPIO_Init
(
GPIOC
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_2
;
HAL_GPIO_Init
(
GPIOD
,
&
GPIO_InitStruct
);
__HAL_RCC_SDMMC1_FORCE_RESET
();
__HAL_RCC_SDMMC1_RELEASE_RESET
();
/* SDMMC1 interrupt Init */
HAL_NVIC_SetPriority
(
SDMMC1_IRQn
,
2
,
0
);
HAL_NVIC_EnableIRQ
(
SDMMC1_IRQn
);
/* USER CODE BEGIN SDMMC1_MspInit 1 */
/* USER CODE END SDMMC1_MspInit 1 */
}
if
(
hsd
->
Instance
==
SDMMC2
)
{
/* USER CODE BEGIN SDMMC2_MspInit 0 */
if
(
IS_ENGINEERING_BOOT_MODE
())
{
/** Initializes the peripherals clock
*/
PeriphClkInit
.
Sdmmc12ClockSelection
=
RCC_SDMMC12CLKSOURCE_PLL4
;
PeriphClkInit
.
PeriphClockSelection
=
RCC_PERIPHCLK_SDMMC12
;
if
(
HAL_RCCEx_PeriphCLKConfig
(
&
PeriphClkInit
)
!=
HAL_OK
)
{
Error_Handler
();
}
}
/* USER CODE END SDMMC2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SDMMC2_CLK_ENABLE
();
__HAL_RCC_GPIOA_CLK_ENABLE
();
__HAL_RCC_GPIOB_CLK_ENABLE
();
__HAL_RCC_GPIOD_CLK_ENABLE
();
__HAL_RCC_GPIOE_CLK_ENABLE
();
__HAL_RCC_GPIOG_CLK_ENABLE
();
/**SDMMC2 GPIO Configuration
PB14 ------> SDMMC2_D0
PB15 ------> SDMMC2_D1
PB3 ------> SDMMC2_D2
PB4 ------> SDMMC2_D3
PA8 ------> SDMMC2_D4
PA9 ------> SDMMC2_D5
PE5 ------> SDMMC2_D6
PD3 ------> SDMMC2_D7
PE3 ------> SDMMC2_CK
PG6 ------> SDMMC2_CMD
*/
GPIO_InitStruct
.
Pin
=
GPIO_PIN_3
|
GPIO_PIN_4
|
GPIO_PIN_14
|
GPIO_PIN_15
;
GPIO_InitStruct
.
Mode
=
GPIO_MODE_AF_PP
;
GPIO_InitStruct
.
Pull
=
GPIO_PULLUP
;
GPIO_InitStruct
.
Speed
=
GPIO_SPEED_FREQ_HIGH
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF9_SDIO2
;
HAL_GPIO_Init
(
GPIOB
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_8
;
HAL_GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_3
;
HAL_GPIO_Init
(
GPIOD
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_3
|
GPIO_PIN_5
;
HAL_GPIO_Init
(
GPIOE
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_9
;
GPIO_InitStruct
.
Alternate
=
GPIO_AF10_SDIO2
;
HAL_GPIO_Init
(
GPIOA
,
&
GPIO_InitStruct
);
GPIO_InitStruct
.
Pin
=
GPIO_PIN_6
;
GPIO_InitStruct
.
Mode
=
GPIO_MODE_AF_PP
;
HAL_GPIO_Init
(
GPIOG
,
&
GPIO_InitStruct
);
__HAL_RCC_SDMMC2_FORCE_RESET
();
__HAL_RCC_SDMMC2_RELEASE_RESET
();
/* SDMMC2 interrupt Init */
HAL_NVIC_SetPriority
(
SDMMC2_IRQn
,
0X05
,
0
);
HAL_NVIC_EnableIRQ
(
SDMMC2_IRQn
);
/* USER CODE BEGIN SDMMC2_MspInit 1 */
/* USER CODE END SDMMC2_MspInit 1 */
}
}
/**
* @brief SD MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hsd: SD handle pointer
* @retval None
*/
void
HAL_SD_MspDeInit
(
SD_HandleTypeDef
*
hsd
)
{
if
(
hsd
->
Instance
==
SDMMC1
)
{
/* USER CODE BEGIN SDMMC1_MspDeInit 0 */
/* USER CODE END SDMMC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SDMMC1_CLK_DISABLE
();
/**SDMMC1 GPIO Configuration
PB9 ------> SDMMC1_CDIR
PC7 ------> SDMMC1_D123DIR
PC8 ------> SDMMC1_D0
PC9 ------> SDMMC1_D1
PC10 ------> SDMMC1_D2
PC11 ------> SDMMC1_D3
PC12 ------> SDMMC1_CK
PD2 ------> SDMMC1_CMD
PE4 ------> SDMMC1_CKIN
PF2 ------> SDMMC1_D0DIR
*/
HAL_GPIO_DeInit
(
GPIOC
,
GPIO_PIN_7
|
GPIO_PIN_8
|
GPIO_PIN_9
|
GPIO_PIN_10
|
GPIO_PIN_11
|
GPIO_PIN_12
);
HAL_GPIO_DeInit
(
GPIOD
,
GPIO_PIN_2
);
HAL_GPIO_DeInit
(
GPIOB
,
GPIO_PIN_9
);
HAL_GPIO_DeInit
(
GPIOE
,
GPIO_PIN_4
);
HAL_GPIO_DeInit
(
GPIOF
,
GPIO_PIN_2
);
/* SDMMC1 interrupt DeInit */
HAL_NVIC_DisableIRQ
(
SDMMC1_IRQn
);
/* USER CODE BEGIN SDMMC1_MspDeInit 1 */
/* USER CODE END SDMMC1_MspDeInit 1 */
}
if
(
hsd
->
Instance
==
SDMMC2
)
{
/* USER CODE BEGIN SDMMC2_MspDeInit 0 */
/* USER CODE END SDMMC2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SDMMC2_CLK_DISABLE
();
/**SDMMC2 GPIO Configuration
PB14 ------> SDMMC2_D0
PB15 ------> SDMMC2_D1
PB3 ------> SDMMC2_D2
PB4 ------> SDMMC2_D3
PA8 ------> SDMMC2_D4
PA9 ------> SDMMC2_D5
PE5 ------> SDMMC2_D6
PD3 ------> SDMMC2_D7
PE3 ------> SDMMC2_CK
PG6 ------> SDMMC2_CMD
*/
HAL_GPIO_DeInit
(
GPIOB
,
GPIO_PIN_3
|
GPIO_PIN_4
|
GPIO_PIN_14
|
GPIO_PIN_15
);
HAL_GPIO_DeInit
(
GPIOA
,
GPIO_PIN_8
|
GPIO_PIN_9
);
HAL_GPIO_DeInit
(
GPIOD
,
GPIO_PIN_3
);
HAL_GPIO_DeInit
(
GPIOE
,
GPIO_PIN_3
|
GPIO_PIN_5
);
HAL_GPIO_DeInit
(
GPIOF
,
GPIO_PIN_6
);
/* SDMMC2 interrupt DeInit */
HAL_NVIC_DisableIRQ
(
SDMMC2_IRQn
);
/* USER CODE BEGIN SDMMC2_MspDeInit 1 */
/* USER CODE END SDMMC2_MspDeInit 1 */
}
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
...
...
bsp/stm32/stm32mp157a-st-ev1/board/Kconfig
浏览文件 @
840af38d
...
...
@@ -37,6 +37,32 @@ menu "Onboard Peripheral Drivers"
bool "Enable Ethernet"
default n
select RT_USING_LWIP
menuconfig BSP_USING_SDMMC
bool "Enable SDMMC"
select RT_USING_SDIO
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
select BSP_USING_PMIC
if BSP_USING_SDMMC
menuconfig BSP_USING_SD_CARD
bool "Enable sd card"
default n
if BSP_USING_SD_CARD
config SD_USING_DFS
bool "sd card fatfs"
default n
endif
menuconfig BSP_USING_EMMC
bool "Enable eMMC (32 Gbits)"
default n
if BSP_USING_EMMC
config EMMC_USING_DFS
bool "emmc card fatfs"
default n
endif
endif
endmenu
menu "On-chip Peripheral Drivers"
...
...
bsp/stm32/stm32mp157a-st-ev1/board/SConscript
浏览文件 @
840af38d
...
...
@@ -22,6 +22,12 @@ if GetDepend(['BSP_USING_NAND']):
if
GetDepend
([
'BSP_USING_GBE'
]):
src
+=
Glob
(
'ports/eth/drv_eth.c'
)
if
GetDepend
([
'BSP_USING_SD_CARD'
]):
src
+=
Glob
(
'ports/drv_sdcard.c'
)
if
GetDepend
([
'BSP_USING_EMMC'
]):
src
+=
Glob
(
'ports/drv_emmc.c'
)
if
GetDepend
([
'BSP_USING_OPENAMP'
]):
src
+=
Glob
(
'CubeMX_Config/CM4/Src/ipcc.c'
)
src
+=
Glob
(
'CubeMX_Config/CM4/Src/openamp.c'
)
...
...
@@ -37,7 +43,6 @@ if GetDepend(['BSP_USING_OPENAMP']):
src
+=
Glob
(
'ports/OpenAMP/virtual_driver/*.c'
)
src
+=
Glob
(
'ports/OpenAMP/drv_openamp.c'
)
path
=
[
cwd
]
path
+=
[
cwd
+
'/CubeMX_Config/CM4/Inc'
]
path
+=
[
cwd
+
'/ports'
]
...
...
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.c
0 → 100644
浏览文件 @
840af38d
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-16 thread-liu first version
*/
#include "board.h"
#include "drv_emmc.h"
#include <dfs_fs.h>
#ifdef BSP_USING_EMMC
//#define DRV_DEBUG
//#define EMMC_RX_DUMP
//#define EMMC_TX_DUMP
#define DBG_TAG "drv.emmc"
#ifdef DRV_DEBUG
#define DBG_LVL DBG_LOG
#else
#define DBG_LVL DBG_INFO
#endif
/* DRV_DEBUG */
#include <rtdbg.h>
static
SD_HandleTypeDef
hsd
;
static
struct
rt_mmcsd_host
*
host
;
#define SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS (100000)
#define RTHW_SDIO_LOCK(_sdio) rt_mutex_take(&_sdio->mutex, RT_WAITING_FOREVER)
#define RTHW_SDIO_UNLOCK(_sdio) rt_mutex_release(&_sdio->mutex);
struct
sdio_pkg
{
struct
rt_mmcsd_cmd
*
cmd
;
void
*
buff
;
rt_uint32_t
flag
;
};
struct
rthw_sdio
{
struct
rt_mmcsd_host
*
host
;
struct
stm32_sdio_des
sdio_des
;
struct
rt_event
event
;
struct
rt_mutex
mutex
;
struct
sdio_pkg
*
pkg
;
};
#define EMMC_BUFF_SIZE 4096
#if defined(__CC_ARM) || defined(__CLANG_ARM)
rt_uint8_t
cache_buf
[
SDIO_BUFF_SIZE
]
__attribute__
((
at
(
0x2FFCB000
)));
#elif defined(__ICCARM__)
#pragma location = 0x2FFCB000
rt_uint8_t
cache_buf
[
EMMC_BUFF_SIZE
];
#elif defined ( __GNUC__ )
rt_uint8_t
cache_buf
[
SDIO_BUFF_SIZE
]
__attribute__
((
at
(
0x2FFCB000
)));
#endif
#if defined(EMMC_RX_DUMP) || defined(EMMC_TX_DUMP)
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
static
void
dump_hex
(
const
rt_uint8_t
*
ptr
,
rt_size_t
buflen
)
{
unsigned
char
*
buf
=
(
unsigned
char
*
)
ptr
;
int
i
,
j
;
for
(
i
=
0
;
i
<
buflen
;
i
+=
16
)
{
rt_kprintf
(
"%08X: "
,
i
);
for
(
j
=
0
;
j
<
16
;
j
++
)
if
(
i
+
j
<
buflen
)
rt_kprintf
(
"%02X "
,
buf
[
i
+
j
]);
else
rt_kprintf
(
" "
);
rt_kprintf
(
" "
);
for
(
j
=
0
;
j
<
16
;
j
++
)
if
(
i
+
j
<
buflen
)
rt_kprintf
(
"%c"
,
__is_print
(
buf
[
i
+
j
])
?
buf
[
i
+
j
]
:
'.'
);
rt_kprintf
(
"
\n
"
);
}
}
#endif
/**
* @brief This function get order from sdio.
* @param data
* @retval sdio order
*/
static
int
get_order
(
rt_uint32_t
data
)
{
int
order
=
0
;
switch
(
data
)
{
case
1
:
order
=
0
;
break
;
case
2
:
order
=
1
;
break
;
case
4
:
order
=
2
;
break
;
case
8
:
order
=
3
;
break
;
case
16
:
order
=
4
;
break
;
case
32
:
order
=
5
;
break
;
case
64
:
order
=
6
;
break
;
case
128
:
order
=
7
;
break
;
case
256
:
order
=
8
;
break
;
case
512
:
order
=
9
;
break
;
case
1024
:
order
=
10
;
break
;
case
2048
:
order
=
11
;
break
;
case
4096
:
order
=
12
;
break
;
case
8192
:
order
=
13
;
break
;
case
16384
:
order
=
14
;
break
;
default
:
order
=
0
;
break
;
}
return
order
;
}
/**
* @brief This function wait sdio cmd completed.
* @param sdio rthw_sdio
* @retval None
*/
static
void
rthw_sdio_wait_completed
(
struct
rthw_sdio
*
sdio
)
{
rt_uint32_t
status
;
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
;
if
(
rt_event_recv
(
&
sdio
->
event
,
0xffffffff
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
rt_tick_from_millisecond
(
5000
),
&
status
)
!=
RT_EOK
)
{
LOG_E
(
"wait cmd completed timeout"
);
cmd
->
err
=
-
RT_ETIMEOUT
;
return
;
}
if
(
sdio
->
pkg
==
RT_NULL
)
{
return
;
}
cmd
->
resp
[
0
]
=
hw_sdio
->
resp1
;
cmd
->
resp
[
1
]
=
hw_sdio
->
resp2
;
cmd
->
resp
[
2
]
=
hw_sdio
->
resp3
;
cmd
->
resp
[
3
]
=
hw_sdio
->
resp4
;
if
(
status
&
SDMMC_ERRORS
)
{
if
((
status
&
SDMMC_STA_CCRCFAIL
)
&&
(
resp_type
(
cmd
)
&
(
RESP_R3
|
RESP_R4
)))
{
cmd
->
err
=
RT_EOK
;
}
else
{
cmd
->
err
=
-
RT_ERROR
;
}
if
(
status
&
SDMMC_STA_CTIMEOUT
)
{
cmd
->
err
=
-
RT_ETIMEOUT
;
}
if
(
status
&
SDMMC_STA_DCRCFAIL
)
{
data
->
err
=
-
RT_ERROR
;
}
if
(
status
&
SDMMC_STA_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
&
SDMMC_STA_CCRCFAIL
?
"CCRCFAIL "
:
""
,
status
&
SDMMC_STA_DCRCFAIL
?
"DCRCFAIL "
:
""
,
status
&
SDMMC_STA_CTIMEOUT
?
"CTIMEOUT "
:
""
,
status
&
SDMMC_STA_DTIMEOUT
?
"DTIMEOUT "
:
""
,
status
&
SDMMC_STA_TXUNDERR
?
"TXUNDERR "
:
""
,
status
&
SDMMC_STA_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
{
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 send command.
* @param sdio rthw_sdio
* @param pkg sdio package
* @retval None
*/
static
void
rthw_sdio_send_command
(
struct
rthw_sdio
*
sdio
,
struct
sdio_pkg
*
pkg
)
{
struct
rt_mmcsd_cmd
*
cmd
=
pkg
->
cmd
;
struct
rt_mmcsd_data
*
data
=
cmd
->
data
;
struct
stm32_sdio
*
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
rt_uint32_t
reg_cmd
;
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
\n
"
,
cmd
->
cmd_code
,
cmd
->
arg
,
resp_type
(
cmd
)
==
RESP_NONE
?
"NONE"
:
""
,
resp_type
(
cmd
)
==
RESP_R1
?
"R1"
:
""
,
resp_type
(
cmd
)
==
RESP_R1B
?
"R1B"
:
""
,
resp_type
(
cmd
)
==
RESP_R2
?
"R2"
:
""
,
resp_type
(
cmd
)
==
RESP_R3
?
"R3"
:
""
,
resp_type
(
cmd
)
==
RESP_R4
?
"R4"
:
""
,
resp_type
(
cmd
)
==
RESP_R5
?
"R5"
:
""
,
resp_type
(
cmd
)
==
RESP_R6
?
"R6"
:
""
,
resp_type
(
cmd
)
==
RESP_R7
?
"R7"
:
""
,
data
?
(
data
->
flags
&
DATA_DIR_WRITE
?
'w'
:
'r'
)
:
'-'
,
data
?
data
->
blks
*
data
->
blksize
:
0
,
data
?
data
->
blksize
:
0
);
/* config cmd reg */
reg_cmd
=
cmd
->
cmd_code
|
SDMMC_CMD_CPSMEN
;
if
(
resp_type
(
cmd
)
==
RESP_NONE
)
{
reg_cmd
|=
SDMMC_RESPONSE_NO
;
}
else
if
(
resp_type
(
cmd
)
==
RESP_R2
)
{
reg_cmd
|=
SDMMC_RESPONSE_LONG
;
}
else
{
reg_cmd
|=
SDMMC_RESPONSE_SHORT
;
}
hw_sdio
->
mask
|=
SDIO_MASKR_ALL
;
/* data pre configuration */
if
(
data
!=
RT_NULL
)
{
hw_sdio
->
dctrl
=
0
;
hw_sdio
->
mask
&=
~
(
SDMMC_MASK_CMDRENDIE
|
SDMMC_MASK_CMDSENTIE
);
reg_cmd
|=
SDMMC_CMD_CMDTRANS
;
hw_sdio
->
dtimer
=
HW_SDIO_DATATIMEOUT
;
hw_sdio
->
dlen
=
data
->
blks
*
data
->
blksize
;
hw_sdio
->
dctrl
=
(
get_order
(
data
->
blksize
)
<<
4
)
|
(
data
->
flags
&
DATA_DIR_READ
?
SDMMC_DCTRL_DTDIR
:
0
);
hw_sdio
->
idmabase0r
=
(
rt_uint32_t
)
cache_buf
;
hw_sdio
->
idmatrlr
=
SDMMC_ENABLE_IDMA_SINGLE_BUFF
;
}
hw_sdio
->
arg
=
cmd
->
arg
;
hw_sdio
->
cmd
=
reg_cmd
;
/* wait completed */
rthw_sdio_wait_completed
(
sdio
);
/* Waiting for data to be sent to completion */
if
(
data
!=
RT_NULL
)
{
volatile
rt_uint32_t
count
=
SDIO_TX_RX_COMPLETE_TIMEOUT_LOOPS
;
while
(
count
&&
(
hw_sdio
->
sta
&
SDMMC_STA_DPSMACT
))
{
count
--
;
}
if
((
count
==
0
)
||
(
hw_sdio
->
sta
&
SDMMC_ERRORS
))
{
cmd
->
err
=
-
RT_ERROR
;
}
}
/* data post configuration */
if
(
data
!=
RT_NULL
)
{
if
(
data
->
flags
&
DATA_DIR_READ
)
{
#if defined(EMMC_RX_DUMP)
rt_kprintf
(
"
\n
EMMC Rx:
\n
"
);
dump_hex
(
cache_buf
,
data
->
blks
*
data
->
blksize
);
#endif
rt_memcpy
(
data
->
buf
,
cache_buf
,
data
->
blks
*
data
->
blksize
);
}
}
}
/**
* @brief This function send sdio request.
* @param sdio rthw_sdio
* @param req request
* @retval None
*/
static
void
rthw_sdio_request
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_req
*
req
)
{
struct
sdio_pkg
pkg
;
struct
rthw_sdio
*
sdio
=
host
->
private_data
;
struct
rt_mmcsd_data
*
data
;
RTHW_SDIO_LOCK
(
sdio
);
if
(
req
->
cmd
!=
RT_NULL
)
{
rt_memset
(
&
pkg
,
0
,
sizeof
(
pkg
));
data
=
req
->
cmd
->
data
;
pkg
.
cmd
=
req
->
cmd
;
if
(
data
!=
RT_NULL
)
{
rt_uint32_t
size
=
data
->
blks
*
data
->
blksize
;
RT_ASSERT
(
size
<=
SDIO_BUFF_SIZE
);
if
(
data
->
flags
&
DATA_DIR_WRITE
)
{
#if defined(EMMC_TX_DUMP)
rt_kprintf
(
"
\n
EMMC Tx:
\n
"
);
dump_hex
(
cache_buf
,
data
->
blks
*
data
->
blksize
);
#endif
rt_memcpy
(
cache_buf
,
data
->
buf
,
size
);
}
}
rthw_sdio_send_command
(
sdio
,
&
pkg
);
}
if
(
req
->
stop
!=
RT_NULL
)
{
rt_memset
(
&
pkg
,
0
,
sizeof
(
pkg
));
pkg
.
cmd
=
req
->
stop
;
rthw_sdio_send_command
(
sdio
,
&
pkg
);
}
RTHW_SDIO_UNLOCK
(
sdio
);
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.
* @param host rt_mmcsd_host
* @param io_cfg rt_mmcsd_io_cfg
* @retval None
*/
static
void
rthw_sdio_iocfg
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_io_cfg
*
io_cfg
)
{
rt_uint32_t
temp
,
clk_src
;
rt_uint32_t
clk
=
io_cfg
->
clock
;
struct
rthw_sdio
*
sdio
=
host
->
private_data
;
struct
stm32_sdio
*
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
LOG_D
(
"clk:%dK width:%s%s%s power:%s%s%s"
,
clk
/
1000
,
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_1
?
"1"
:
""
,
io_cfg
->
power_mode
==
MMCSD_POWER_OFF
?
"OFF"
:
""
,
io_cfg
->
power_mode
==
MMCSD_POWER_UP
?
"UP"
:
""
,
io_cfg
->
power_mode
==
MMCSD_POWER_ON
?
"ON"
:
""
);
RTHW_SDIO_LOCK
(
sdio
);
clk_src
=
EMMC_CLOCK_FREQ
;
if
(
clk
>
0
)
{
if
(
clk
>
host
->
freq_max
)
{
clk
=
host
->
freq_max
;
}
temp
=
DIV_ROUND_UP
(
clk_src
,
2
*
clk
);
if
(
temp
>
0x3FF
)
{
temp
=
0x3FF
;
}
}
if
(
io_cfg
->
bus_width
==
MMCSD_BUS_WIDTH_8
)
{
temp
|=
SDMMC_BUS_WIDE_8B
;
}
else
if
(
io_cfg
->
bus_width
==
MMCSD_BUS_WIDTH_4
)
{
temp
|=
SDMMC_BUS_WIDE_4B
;
}
else
{
temp
|=
SDMMC_BUS_WIDE_1B
;
}
hw_sdio
->
clkcr
=
temp
;
if
(
io_cfg
->
power_mode
==
MMCSD_POWER_ON
)
hw_sdio
->
power
|=
SDMMC_POWER_PWRCTRL
;
RTHW_SDIO_UNLOCK
(
sdio
);
}
static
const
struct
rt_mmcsd_host_ops
ops
=
{
rthw_sdio_request
,
rthw_sdio_iocfg
,
RT_NULL
,
RT_NULL
,
};
/**
* @brief This function create mmcsd host.
* @param sdio_des stm32_sdio_des
* @retval rt_mmcsd_host
*/
struct
rt_mmcsd_host
*
sdio_host_create
(
struct
stm32_sdio_des
*
sdio_des
)
{
struct
rt_mmcsd_host
*
host
;
struct
rthw_sdio
*
sdio
=
RT_NULL
;
if
(
sdio_des
==
RT_NULL
)
{
return
RT_NULL
;
}
sdio
=
rt_malloc
(
sizeof
(
struct
rthw_sdio
));
if
(
sdio
==
RT_NULL
)
{
LOG_E
(
"malloc rthw_sdio fail"
);
return
RT_NULL
;
}
rt_memset
(
sdio
,
0
,
sizeof
(
struct
rthw_sdio
));
host
=
mmcsd_alloc_host
();
if
(
host
==
RT_NULL
)
{
LOG_E
(
"alloc host fail"
);
goto
err
;
}
rt_memcpy
(
&
sdio
->
sdio_des
,
sdio_des
,
sizeof
(
struct
stm32_sdio_des
));
sdio
->
sdio_des
.
hw_sdio
=
(
struct
stm32_sdio
*
)
EMMC_BASE_ADDRESS
;
rt_event_init
(
&
sdio
->
event
,
"sdio"
,
RT_IPC_FLAG_FIFO
);
rt_mutex_init
(
&
sdio
->
mutex
,
"sdio"
,
RT_IPC_FLAG_FIFO
);
/* set host default attributes */
host
->
ops
=
&
ops
;
host
->
freq_min
=
400
*
1000
;
host
->
freq_max
=
EMMC_MAX_FREQ
;
host
->
valid_ocr
=
0X00FFFF80
;
/* The voltage range supported is 1.65v-3.6v */
host
->
flags
=
MMCSD_BUSWIDTH_8
|
MMCSD_MUTBLKWRITE
|
MMCSD_SUP_HIGHSPEED
;
host
->
max_seg_size
=
SDIO_BUFF_SIZE
;
host
->
max_dma_segs
=
1
;
host
->
max_blk_size
=
512
;
host
->
max_blk_count
=
512
;
/* link up host and sdio */
sdio
->
host
=
host
;
host
->
private_data
=
sdio
;
/* ready to change */
mmcsd_change
(
host
);
return
host
;
err:
if
(
sdio
)
{
rt_free
(
sdio
);
}
return
RT_NULL
;
}
void
SDMMC2_IRQHandler
(
void
)
{
rt_interrupt_enter
();
/* Process All SDIO Interrupt Sources */
rthw_sdio_irq_process
(
host
);
rt_interrupt_leave
();
}
int
rt_hw_sdio_init
(
void
)
{
struct
stm32_sdio_des
sdio_des
;
hsd
.
Instance
=
SDMMC2
;
HAL_SD_MspInit
(
&
hsd
);
host
=
sdio_host_create
(
&
sdio_des
);
if
(
host
==
RT_NULL
)
{
LOG_E
(
"host create fail"
);
return
RT_NULL
;
}
return
0
;
}
INIT_DEVICE_EXPORT
(
rt_hw_sdio_init
);
#if defined(EMMC_USING_DFS)
int
mnt_init
(
void
)
{
rt_device_t
sd
=
RT_NULL
;
#if defined(EMMC_RX_DUMP) || defined(EMMC_TX_DUMP)
rt_thread_delay
(
3000
);
#else
rt_thread_delay
(
RT_TICK_PER_SECOND
);
#endif
sd
=
rt_device_find
(
"sd0"
);
if
(
sd
==
RT_NULL
)
{
rt_kprintf
(
"can't find emmc device!
\n
"
);
return
RT_ERROR
;
}
if
(
dfs_mount
(
"sd0"
,
"/"
,
"elm"
,
0
,
0
)
!=
0
)
{
rt_kprintf
(
"file system mount failed!
\n
"
);
}
else
{
rt_kprintf
(
"file system mount success!
\n
"
);
}
return
0
;
}
INIT_APP_EXPORT
(
mnt_init
);
#endif
#endif
/* BSP_USING_SDMMC */
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_emmc.h
0 → 100644
浏览文件 @
840af38d
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-16 thread-liu first version
*/
#ifndef __DRV_EMMC_H__
#define __DRV_EMMC_H__
#include <rtthread.h>
#include "rtdevice.h"
#include <rthw.h>
#include <drv_common.h>
#include <string.h>
#include <drivers/mmcsd_core.h>
#include <drivers/sdio.h>
#define SDIO_BUFF_SIZE 4096
#ifndef EMMC_BASE_ADDRESS
#define EMMC_BASE_ADDRESS (SDMMC2)
#endif
#ifndef EMMC_CLOCK_FREQ
#define EMMC_CLOCK_FREQ (99U * 1000 * 1000)
#endif
#ifndef EMMC_MAX_FREQ
#define EMMC_MAX_FREQ (50 * 1000 * 1000)
#endif
#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
#define SDMMC_ERRORS \
(SDMMC_STA_IDMATE | SDMMC_STA_ACKTIMEOUT | \
SDMMC_STA_RXOVERR | SDMMC_STA_TXUNDERR | \
SDMMC_STA_DTIMEOUT | SDMMC_STA_CTIMEOUT | \
SDMMC_STA_DCRCFAIL | SDMMC_STA_CCRCFAIL)
#define SDIO_MASKR_ALL \
(SDMMC_MASK_CCRCFAILIE | SDMMC_MASK_DCRCFAILIE | SDMMC_MASK_CTIMEOUTIE | \
SDMMC_MASK_TXUNDERRIE | SDMMC_MASK_RXOVERRIE | SDMMC_MASK_CMDRENDIE | \
SDMMC_MASK_CMDSENTIE | SDMMC_MASK_DATAENDIE | SDMMC_MASK_ACKTIMEOUTIE)
#define HW_SDIO_DATATIMEOUT (0xFFFFFFFFU)
struct
stm32_sdio
{
volatile
rt_uint32_t
power
;
/* offset 0x00 */
volatile
rt_uint32_t
clkcr
;
/* offset 0x04 */
volatile
rt_uint32_t
arg
;
/* offset 0x08 */
volatile
rt_uint32_t
cmd
;
/* offset 0x0C */
volatile
rt_uint32_t
respcmd
;
/* offset 0x10 */
volatile
rt_uint32_t
resp1
;
/* offset 0x14 */
volatile
rt_uint32_t
resp2
;
/* offset 0x18 */
volatile
rt_uint32_t
resp3
;
/* offset 0x1C */
volatile
rt_uint32_t
resp4
;
/* offset 0x20 */
volatile
rt_uint32_t
dtimer
;
/* offset 0x24 */
volatile
rt_uint32_t
dlen
;
/* offset 0x28 */
volatile
rt_uint32_t
dctrl
;
/* offset 0x2C */
volatile
rt_uint32_t
dcount
;
/* offset 0x30 */
volatile
rt_uint32_t
sta
;
/* offset 0x34 */
volatile
rt_uint32_t
icr
;
/* offset 0x38 */
volatile
rt_uint32_t
mask
;
/* offset 0x3C */
volatile
rt_uint32_t
acktimer
;
/* offset 0x40 */
volatile
rt_uint32_t
reserved0
[
3
];
/* offset 0x44 ~ 0x4C */
volatile
rt_uint32_t
idmatrlr
;
/* offset 0x50 */
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
[
1
];
/* offset 0x60 */
volatile
rt_uint32_t
idmalar
;
volatile
rt_uint32_t
idmabar
;
volatile
rt_uint32_t
reserved2
[
5
];
volatile
rt_uint32_t
fifo
;
volatile
rt_uint32_t
reserved3
[
220
];
volatile
rt_uint32_t
verr
;
volatile
rt_uint32_t
ipidr
;
volatile
rt_uint32_t
sidr
;
};
typedef
rt_uint32_t
(
*
sdio_clk_get
)(
struct
stm32_sdio
*
hw_sdio
);
struct
stm32_sdio_des
{
struct
stm32_sdio
*
hw_sdio
;
sdio_clk_get
clk_get
;
};
/* stm32 sdio dirver class */
struct
stm32_sdio_class
{
struct
stm32_sdio_des
*
des
;
const
struct
stm32_sdio_config
*
cfg
;
struct
rt_mmcsd_host
host
;
};
extern
void
stm32_mmcsd_change
(
void
);
#endif
/* __DRV_SDIO_H__ */
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_pmic.c
浏览文件 @
840af38d
...
...
@@ -19,6 +19,8 @@
#define LOG_TAG "drv.pmic"
#include <drv_log.h>
#define I2C_NAME "i2c3"
static
struct
rt_i2c_bus_device
*
pmic_dev
=
RT_NULL
;
/* i2c read reg */
...
...
@@ -884,7 +886,7 @@ static int pmic_init(void)
{
BSP_PMIC_MspInit
();
result
=
rt_hw_pmic_init
(
"i2c3"
);
result
=
rt_hw_pmic_init
(
I2C_NAME
);
if
(
result
!=
RT_EOK
)
{
LOG_D
(
"stpmic init failed: %02x"
,
result
);
...
...
bsp/stm32/stm32mp157a-st-ev1/board/ports/drv_sdcard.c
0 → 100644
浏览文件 @
840af38d
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-04 thread-liu the first version
*/
#include "board.h"
#if defined(BSP_USING_SD_CARD)
#include <dfs_fs.h>
#define DRV_DEBUG
//#define SDMMC_TX_DUMP
//#define SDMMC_RX_DUMP
#define LOG_TAG "drv.sdmmc"
#include <drv_log.h>
static
SD_HandleTypeDef
SDCARD_Handler
=
{
0
};
static
HAL_SD_CardInfoTypeDef
SDCardInfo
=
{
0
};
struct
stm32_sd
{
struct
rt_device
sdcard
;
struct
rt_semaphore
sd_lock
;
volatile
rt_uint8_t
write_flage
;
volatile
rt_uint8_t
read_flage
;
volatile
rt_base_t
level
;
};
static
struct
stm32_sd
sd_device
;
#define SD_TIMEOUT ((uint32_t)30 * 1000)
#define DETECT_PIN GET_PIN(G, 1)
#define LDO_PIN GET_PIN(F, 14)
struct
rt_completion
tx_comp
;
struct
rt_completion
rx_comp
;
/* SYSRAM SDMMC1/2 accesses */
#define SDIO_BUFF_SIZE 512
#if defined(__CC_ARM) || defined(__CLANG_ARM)
__attribute__
((
at
(
0x2FFC0000
)))
#elif defined ( __GNUC__ )
__attribute__
((
at
(
0x2FFC0000
)))
#elif defined(__ICCARM__)
#pragma location = 0x2FFC0000
#endif
static
rt_uint32_t
cache_buf
[
SDIO_BUFF_SIZE
];
#if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
static
void
dump_hex
(
const
rt_uint8_t
*
ptr
,
rt_size_t
buflen
)
{
unsigned
char
*
buf
=
(
unsigned
char
*
)
ptr
;
int
i
,
j
;
for
(
i
=
0
;
i
<
buflen
;
i
+=
16
)
{
rt_kprintf
(
"%08X: "
,
i
);
for
(
j
=
0
;
j
<
16
;
j
++
)
if
(
i
+
j
<
buflen
)
rt_kprintf
(
"%02X "
,
buf
[
i
+
j
]);
else
rt_kprintf
(
" "
);
rt_kprintf
(
" "
);
for
(
j
=
0
;
j
<
16
;
j
++
)
if
(
i
+
j
<
buflen
)
rt_kprintf
(
"%c"
,
__is_print
(
buf
[
i
+
j
])
?
buf
[
i
+
j
]
:
'.'
);
rt_kprintf
(
"
\n
"
);
}
}
#endif
static
rt_err_t
rt_hw_sd_is_detected
(
void
)
{
return
rt_pin_read
(
DETECT_PIN
);
}
static
rt_err_t
rt_hw_sd_init
(
void
)
{
/* sd ldo*/
rt_pin_mode
(
LDO_PIN
,
PIN_MODE_OUTPUT
);
/* sd detect */
rt_pin_mode
(
DETECT_PIN
,
PIN_MODE_INPUT_PULLUP
);
/* judge we have a sd card */
if
(
rt_hw_sd_is_detected
()
!=
0x00
)
{
LOG_E
(
"can't find sd card!"
);
return
RT_ERROR
;
}
SDCARD_Handler
.
Instance
=
SDMMC1
;
HAL_SD_DeInit
(
&
SDCARD_Handler
);
/* if CLKDIV = 0 then SDMMC Clock frequency = SDMMC Kernel Clock
else SDMMC Clock frequency = SDMMC Kernel Clock / [2 * CLKDIV].
SDMMC Kernel Clock = 99MHz, SDMMC Clock frequency = 50MHz */
SDCARD_Handler
.
Init
.
ClockDiv
=
1
;
SDCARD_Handler
.
Init
.
ClockPowerSave
=
SDMMC_CLOCK_POWER_SAVE_DISABLE
;
SDCARD_Handler
.
Init
.
ClockEdge
=
SDMMC_CLOCK_EDGE_FALLING
;
SDCARD_Handler
.
Init
.
HardwareFlowControl
=
SDMMC_HARDWARE_FLOW_CONTROL_DISABLE
;
SDCARD_Handler
.
Init
.
BusWide
=
SDMMC_BUS_WIDE_4B
;
if
(
HAL_SD_Init
(
&
SDCARD_Handler
)
!=
RT_EOK
)
{
LOG_E
(
"sd device init error!"
);
return
RT_ERROR
;
}
if
(
HAL_SD_ConfigWideBusOperation
(
&
SDCARD_Handler
,
SDMMC_BUS_WIDE_4B
)
!=
RT_EOK
)
{
LOG_E
(
"sd bus config error!"
);
return
RT_ERROR
;
}
if
(
HAL_SD_GetCardInfo
(
&
SDCARD_Handler
,
&
SDCardInfo
)
!=
RT_EOK
)
{
LOG_E
(
"sd get card info error!"
);
return
RT_ERROR
;
}
rt_thread_mdelay
(
100
);
if
(
HAL_SD_GetCardState
(
&
SDCARD_Handler
)
!=
HAL_SD_CARD_TRANSFER
)
{
LOG_E
(
"sd get card state error!"
);
return
RT_ERROR
;
}
return
RT_EOK
;
}
static
void
rt_hw_sd_deinit
(
void
)
{
HAL_SD_DeInit
(
&
SDCARD_Handler
);
}
static
rt_err_t
sdcard_wait_ok
(
void
)
{
rt_uint32_t
tick_start
=
0
;
tick_start
=
rt_tick_get
();
while
((
rt_tick_get
()
-
tick_start
)
<
SD_TIMEOUT
)
{
if
(
HAL_SD_GetCardState
(
&
SDCARD_Handler
)
==
HAL_SD_CARD_TRANSFER
)
{
return
HAL_OK
;
}
}
return
HAL_ERROR
;
}
void
HAL_SD_DriveTransceiver_1_8V_Callback
(
FlagStatus
status
)
{
if
(
status
==
SET
)
{
rt_pin_write
(
LDO_PIN
,
PIN_HIGH
);
}
else
{
rt_pin_write
(
LDO_PIN
,
PIN_LOW
);
}
}
static
rt_err_t
rt_sdcard_init
(
rt_device_t
dev
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
struct
stm32_sd
*
sd
=
(
struct
stm32_sd
*
)
dev
;
if
(
rt_sem_init
(
&
sd
->
sd_lock
,
"sdlock"
,
1
,
RT_IPC_FLAG_FIFO
)
!=
RT_EOK
)
{
LOG_E
(
"init sd lock semaphore failed
\n
"
);
}
return
RT_EOK
;
}
static
rt_err_t
rt_sdcard_open
(
rt_device_t
dev
,
rt_uint16_t
oflag
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
return
RT_EOK
;
}
static
rt_err_t
rt_sdcard_close
(
rt_device_t
dev
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
return
RT_EOK
;
}
/**
* @brief Reads Sector(s)
* @param dev : sd dev
* @param sector: Sector address (LBA) Data buffer to store read data
* @param *buffer: Data buffer to store read data
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
static
rt_size_t
rt_sdcard_read
(
rt_device_t
dev
,
rt_off_t
sector
,
void
*
buffer
,
rt_size_t
count
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
struct
stm32_sd
*
sd
=
(
struct
stm32_sd
*
)
dev
;
rt_uint8_t
ret
=
RT_EOK
;
volatile
uint32_t
tickstart
=
0
;
sd
->
read_flage
=
0
;
rt_memset
(
cache_buf
,
0x00
,
BLOCKSIZE
*
count
);
ret
=
sdcard_wait_ok
();
if
(
ret
!=
RT_EOK
)
{
LOG_D
(
"sdmmc busy!"
);
return
0
;
}
rt_sem_take
(
&
sd
->
sd_lock
,
RT_WAITING_FOREVER
);
ret
=
HAL_SD_ReadBlocks_DMA
(
&
SDCARD_Handler
,
(
rt_uint8_t
*
)
cache_buf
,
(
uint32_t
)
sector
,
count
);
rt_sem_release
(
&
sd
->
sd_lock
);
/* Wait that writing process is completed or a timeout occurs */
tickstart
=
rt_tick_get
();
if
(
ret
==
HAL_OK
)
{
while
((
sd
->
read_flage
==
0
)
&&
(
rt_tick_get
()
-
tickstart
)
<
SD_TIMEOUT
)
{
}
/* over time */
if
(
sd
->
read_flage
==
0
)
{
return
0
;
}
else
{
sd
->
read_flage
=
0
;
tickstart
=
rt_tick_get
();
while
((
rt_tick_get
()
-
tickstart
)
<
SD_TIMEOUT
)
{
if
(
sdcard_wait_ok
()
==
RT_EOK
)
{
sd
->
level
=
rt_hw_interrupt_disable
();
rt_memcpy
((
rt_uint8_t
*
)(
buffer
),
cache_buf
,
BLOCKSIZE
*
count
);
rt_hw_interrupt_enable
(
sd
->
level
);
#if defined(SDMMC_RX_DUMP)
rt_kprintf
(
"
\n
sd rx:
\n
"
);
dump_hex
(
cache_buf
,
BLOCKSIZE
*
count
);
#endif
return
count
;
}
}
}
}
return
0
;
}
/**
* @brief Writes block(s) to a specified address in an SD card, in DMA mode.
* @param dev SD device
* @param sector Block index from where data is to be written P
* @param *buffer Pointer to the buffer that will contain the data to transmit
* @param count Number of SD blocks to write
* @retval BSP status
*/
static
rt_size_t
rt_sdcard_write
(
rt_device_t
dev
,
rt_off_t
sector
,
const
void
*
buffer
,
rt_size_t
count
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
struct
stm32_sd
*
sd
=
(
struct
stm32_sd
*
)
dev
;
rt_uint32_t
i
=
0
;
rt_uint8_t
ret
=
RT_EOK
;
for
(
i
=
0
;
i
<
count
;
i
++
)
{
sd
->
level
=
rt_hw_interrupt_disable
();
rt_memset
(
cache_buf
,
0x00
,
BLOCKSIZE
);
rt_memcpy
(
cache_buf
,
(
rt_uint32_t
*
)((
uintptr_t
)
buffer
+
BLOCKSIZE
*
i
),
BLOCKSIZE
);
rt_hw_interrupt_enable
(
sd
->
level
);
#if defined(SDMMC_TX_DUMP)
rt_kprintf
(
"
\n
sd tx:
\n
"
);
dump_hex
(
cache_buf
,
BLOCKSIZE
);
#endif
ret
=
sdcard_wait_ok
();
if
(
ret
!=
RT_EOK
)
{
LOG_D
(
"sdmmc busy!"
);
return
0
;
}
rt_completion_init
(
&
tx_comp
);
ret
=
HAL_SD_WriteBlocks_DMA
(
&
SDCARD_Handler
,
(
rt_uint8_t
*
)
cache_buf
,
(
rt_uint32_t
)(
sector
+
i
),
1
);
if
(
ret
!=
HAL_OK
)
{
rt_kprintf
(
"sd write error!
\n
"
);
return
0
;
}
rt_completion_wait
(
&
tx_comp
,
RT_WAITING_FOREVER
);
}
return
count
;
}
static
rt_err_t
rt_sdcard_control
(
rt_device_t
dev
,
int
cmd
,
void
*
args
)
{
RT_ASSERT
(
dev
!=
RT_NULL
);
if
(
cmd
==
RT_DEVICE_CTRL_BLK_GETGEOME
)
{
struct
rt_device_blk_geometry
*
geometry
;
geometry
=
(
struct
rt_device_blk_geometry
*
)
args
;
geometry
->
bytes_per_sector
=
512
;
geometry
->
block_size
=
SDCARD_Handler
.
SdCard
.
BlockSize
;
geometry
->
sector_count
=
SDCARD_Handler
.
SdCard
.
BlockNbr
;
}
return
RT_EOK
;
}
void
SDMMC1_IRQHandler
(
void
)
{
rt_interrupt_enter
();
HAL_SD_IRQHandler
(
&
SDCARD_Handler
);
rt_interrupt_leave
();
}
void
HAL_SD_RxCpltCallback
(
SD_HandleTypeDef
*
hsd
)
{
if
(
hsd
->
Instance
==
SDCARD_Handler
.
Instance
)
{
sd_device
.
read_flage
=
1
;
}
}
void
HAL_SD_TxCpltCallback
(
SD_HandleTypeDef
*
hsd
)
{
if
(
hsd
->
Instance
==
SDCARD_Handler
.
Instance
)
{
rt_completion_done
(
&
tx_comp
);
}
}
int
rt_hw_sdcard_init
(
void
)
{
if
(
rt_hw_sd_init
()
!=
RT_EOK
)
{
rt_hw_sd_deinit
();
LOG_E
(
"sdcard init failed"
);
return
RT_ERROR
;
}
/* register sdcard device */
sd_device
.
sdcard
.
type
=
RT_Device_Class_Block
;
sd_device
.
sdcard
.
init
=
rt_sdcard_init
;
sd_device
.
sdcard
.
open
=
rt_sdcard_open
;
sd_device
.
sdcard
.
close
=
rt_sdcard_close
;
sd_device
.
sdcard
.
read
=
rt_sdcard_read
;
sd_device
.
sdcard
.
write
=
rt_sdcard_write
;
sd_device
.
sdcard
.
control
=
rt_sdcard_control
;
/* no private */
sd_device
.
sdcard
.
user_data
=
&
SDCardInfo
;
rt_device_register
(
&
sd_device
.
sdcard
,
"sd_card"
,
RT_DEVICE_FLAG_RDWR
|
RT_DEVICE_FLAG_REMOVABLE
|
RT_DEVICE_FLAG_STANDALONE
);
LOG_I
(
"sd card init success!"
);
return
RT_EOK
;
}
INIT_DEVICE_EXPORT
(
rt_hw_sdcard_init
);
#if defined(SD_USING_DFS)
int
mnt_init
(
void
)
{
rt_device_t
sd_dev
=
RT_NULL
;
LOG_I
(
"init sd card file system."
);
#if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
rt_thread_delay
(
3000
);
#else
rt_thread_delay
(
RT_TICK_PER_SECOND
);
#endif
sd_dev
=
rt_device_find
(
"sd_card"
);
if
(
sd_dev
==
RT_NULL
)
{
LOG_E
(
"can't find sd deivce name!"
);
return
RT_ERROR
;
}
if
(
dfs_mount
(
"sd_card"
,
"/"
,
"elm"
,
0
,
0
)
!=
0
)
{
rt_kprintf
(
"file system mount failed!
\n
"
);
}
else
{
rt_kprintf
(
"file system mount success!
\n
"
);
}
return
0
;
}
INIT_APP_EXPORT
(
mnt_init
);
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录