Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Richard 祝发兴 - -IT
rt-thread
提交
7d0155ee
R
rt-thread
项目概览
Richard 祝发兴 - -IT
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7d0155ee
编写于
1月 20, 2021
作者:
G
greedyhao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[bsp][bluetrum] add sdio support
上级
afd57510
变更
16
展开全部
隐藏空白更改
内联
并排
Showing
16 changed file
with
1402 addition
and
226 deletion
+1402
-226
bsp/bluetrum/ab32vg1-ab-prougen/.config
bsp/bluetrum/ab32vg1-ab-prougen/.config
+7
-0
bsp/bluetrum/ab32vg1-ab-prougen/.cproject
bsp/bluetrum/ab32vg1-ab-prougen/.cproject
+155
-152
bsp/bluetrum/ab32vg1-ab-prougen/README.md
bsp/bluetrum/ab32vg1-ab-prougen/README.md
+6
-6
bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c
bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c
+54
-1
bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c
bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c
+1
-1
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig
+28
-0
bsp/bluetrum/ab32vg1-ab-prougen/makefile.targets
bsp/bluetrum/ab32vg1-ab-prougen/makefile.targets
+2
-5
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h
+2
-0
bsp/bluetrum/libraries/hal_drivers/SConscript
bsp/bluetrum/libraries/hal_drivers/SConscript
+6
-2
bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
+9
-0
bsp/bluetrum/libraries/hal_drivers/drv_sdio.c
bsp/bluetrum/libraries/hal_drivers/drv_sdio.c
+658
-0
bsp/bluetrum/libraries/hal_drivers/drv_sdio.h
bsp/bluetrum/libraries/hal_drivers/drv_sdio.h
+140
-0
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h
...ries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h
+1
-1
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_sd.h
...raries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_sd.h
+50
-12
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_ll_sdio.h
...aries/hal_libraries/ab32vg1_hal/include/ab32vg1_ll_sdio.h
+21
-1
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal_sd.c
...braries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal_sd.c
+262
-45
未找到文件。
bsp/bluetrum/ab32vg1-ab-prougen/.config
浏览文件 @
7d0155ee
...
...
@@ -381,6 +381,7 @@ CONFIG_RT_USING_LIBC=y
# CONFIG_PKG_USING_UC_MODBUS is not set
# CONFIG_PKG_USING_PPOOL is not set
# CONFIG_PKG_USING_OPENAMP is not set
# CONFIG_PKG_USING_RT_PRINTF is not set
#
# peripheral libraries and drivers
...
...
@@ -501,11 +502,17 @@ CONFIG_RT_USING_LIBC=y
CONFIG_BSP_USING_USB_TO_USART
=
y
CONFIG_BSP_USING_AUDIO
=
y
CONFIG_BSP_USING_AUDIO_PLAY
=
y
# CONFIG_BSP_USING_SDCARD is not set
#
# On-chip Peripheral Drivers
#
CONFIG_BSP_USING_UART0
=
y
# CONFIG_BSP_USING_SDIO is not set
#
# On-chip Peripheral Drivers
#
#
# Board extended module Drivers
...
...
bsp/bluetrum/ab32vg1-ab-prougen/.cproject
浏览文件 @
7d0155ee
此差异已折叠。
点击以展开。
bsp/bluetrum/ab32vg1-ab-prougen/README.md
浏览文件 @
7d0155ee
...
...
@@ -12,7 +12,7 @@
## 开发板介绍
ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核的开发板,最高主频为 120Mhz,该开发板芯片为 AB
5301A
。
ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核的开发板,最高主频为 120Mhz,该开发板芯片为 AB
32VG1
。
开发板外观如下图所示:
...
...
@@ -20,7 +20,7 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
该开发板常用
**板载资源**
如下:
-
MCU:AB
5301A,主频 120MHz,可超频至 192MHz,4
Mbit FLASH ,192KB RAM。
-
MCU:AB
32VG1,主频 120MHz,可超频至 192MHz,8
Mbit FLASH ,192KB RAM。
-
常用外设
-
LED: RGB灯
-
按键: 3 个, USER(s2,s3) and RESET(s1)
...
...
@@ -33,9 +33,9 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
|
**板载外设**
|
**支持情况**
|
**备注**
|
| :----------- | :----------: | :---------- |
| USB 转串口 | 支持 | |
| SD卡 |
即将支持
| |
| SD卡 |
支持
| |
| IRDA | 即将支持 | |
| 音频接口 |
即将支持
| |
| 音频接口 |
支持
| |
|
**片上外设**
|
**支持情况**
|
**备注**
|
| GPIO | 支持 | PA PB PE PF |
| UART | 支持 | UART0/1/2 |
...
...
@@ -73,11 +73,11 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
#### 编译下载
运行
`scons`
编译得到
`.dcf`
固件,通过
`d
ownloader`
进行下载
通过
`RT-Thread Studio`
或者
`scons`
编译得到
`.dcf`
固件,通过
`D
ownloader`
进行下载
#### 运行结果
下载程序成功之后,系统会自动运行,观察开发板上 LED 的运行效果,红色 LED
常亮、绿色 LED
会周期性闪烁。
下载程序成功之后,系统会自动运行,观察开发板上 LED 的运行效果,红色 LED 会周期性闪烁。
连接开发板对应串口到 PC , 在终端工具里打开相应的串口(115200-8-1-N),复位设备后,可以看到 RT-Thread 的输出信息:
...
...
bsp/bluetrum/ab32vg1-ab-prougen/applications/mnt.c
浏览文件 @
7d0155ee
#include <rtthread.h>
#ifdef RT_USING_DFS
#if 1
#ifdef BSP_USING_SDIO
#include <dfs_elm.h>
#include <dfs_fs.h>
#include <dfs_posix.h>
#include "drv_gpio.h"
// #define DRV_DEBUG
#define DBG_TAG "app.card"
#include <rtdbg.h>
void
sd_mount
(
void
*
parameter
)
{
while
(
1
)
{
rt_thread_mdelay
(
500
);
if
(
rt_device_find
(
"sd0"
)
!=
RT_NULL
)
{
if
(
dfs_mount
(
"sd0"
,
"/"
,
"elm"
,
0
,
0
)
==
RT_EOK
)
{
LOG_I
(
"sd card mount to '/'"
);
break
;
}
else
{
LOG_W
(
"sd card mount to '/' failed!"
);
}
}
}
}
int
ab32_sdcard_mount
(
void
)
{
rt_thread_t
tid
;
tid
=
rt_thread_create
(
"sd_mount"
,
sd_mount
,
RT_NULL
,
1024
,
RT_THREAD_PRIORITY_MAX
-
2
,
20
);
if
(
tid
!=
RT_NULL
)
{
rt_thread_startup
(
tid
);
}
else
{
LOG_E
(
"create sd_mount thread err!"
);
}
return
RT_EOK
;
}
INIT_APP_EXPORT
(
ab32_sdcard_mount
);
#endif
#else
#include <dfs_fs.h>
#include "dfs_romfs.h"
...
...
bsp/bluetrum/ab32vg1-ab-prougen/applications/romfs.c
浏览文件 @
7d0155ee
/* Generated by mkromfs. Edit with caution. */
#include <rtthread.h>
#ifdef RT_USING_DFS
#ifdef RT_USING_DFS
_ROMFS
#include <dfs_romfs.h>
...
...
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig
浏览文件 @
7d0155ee
...
...
@@ -19,6 +19,34 @@ menu "Onboard Peripheral Drivers"
default y
endif
config BSP_USING_SDCARD
bool "Enable SDCARD"
select BSP_USING_SDIO
default n
if BSP_USING_SDCARD
config SDIO_MAX_FREQ
int "sdio max freq"
range 0 24000000
default 24000000
endif
endmenu
menu "On-chip Peripheral Drivers"
menuconfig BSP_USING_UART0
bool "Enable UART0"
select RT_USING_SERIAL
default y
config BSP_USING_SDIO
bool "Enable SDIO"
select RT_USING_SDIO
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
default n
endmenu
menu "On-chip Peripheral Drivers"
...
...
bsp/bluetrum/ab32vg1-ab-prougen/makefile.targets
浏览文件 @
7d0155ee
rtthread.siz
:
riscv64-unknown-elf-size
--format
=
berkeley
"rtthread.elf"
all2
:
all
sh ../pre_build.sh
riscv32-elf-xmaker
-b
rtthread.xm
riscv32-elf-xmaker
-b
download.xm
clean2
:
-
$(RM)
$(CC_DEPS)
$
(
C++_DEPS
)
$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS)
-
$(RM)
$(OBJS)
*
.elf
-
@echo
' '
*.elf
:
$(wildcard D:/Softwares/RT-ThreadStudio/workspace/ab32vg1/link.lds)
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h
浏览文件 @
7d0155ee
...
...
@@ -176,6 +176,8 @@
#define BSP_USING_UART0
/* On-chip Peripheral Drivers */
/* Board extended module Drivers */
#define BOARD_BLUETRUM_EVB
...
...
bsp/bluetrum/libraries/hal_drivers/SConscript
浏览文件 @
7d0155ee
...
...
@@ -4,7 +4,8 @@ from building import *
cwd
=
GetCurrentDir
()
src
=
[]
CPPPATH
=
[
cwd
]
path
=
[
cwd
]
path
+=
[
cwd
+
'/config'
]
if
GetDepend
(
'RT_USING_PIN'
):
src
+=
[
'drv_gpio.c'
]
...
...
@@ -12,7 +13,10 @@ if GetDepend('RT_USING_PIN'):
if
GetDepend
(
'RT_USING_SERIAL'
):
src
+=
[
'drv_usart.c'
]
group
=
DefineGroup
(
'Drivers'
,
src
,
depend
=
[
''
],
CPPPATH
=
CPPPATH
)
if
GetDepend
(
'RT_USING_SDIO'
):
src
+=
[
'drv_sdio.c'
]
group
=
DefineGroup
(
'Drivers'
,
src
,
depend
=
[
''
],
CPPPATH
=
path
)
objs
=
[
group
]
...
...
bsp/bluetrum/libraries/hal_drivers/config/pwm_config.h
0 → 100644
浏览文件 @
7d0155ee
/*
* Copyright (c) 2020-2021, Bluetrum Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021/01/18 greedyhao The first version
*/
bsp/bluetrum/libraries/hal_drivers/drv_sdio.c
0 → 100644
浏览文件 @
7d0155ee
/*
* Copyright (c) 2006-2021, Bluetrum Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-20 greedyhao first version
*/
#include "drv_sdio.h"
#include "interrupt.h"
#include <rthw.h>
#ifdef BSP_USING_SDIO
// #define DRV_DEBUG
#define LOG_TAG "drv.sdio"
#include <drv_log.h>
#define SDIO_USING_1_BIT
static
struct
ab32_sdio_config
sdio_config
[]
=
{
{.
instance
=
SDMMC0_BASE
,
},
};
static
struct
rt_mmcsd_host
*
host
=
RT_NULL
;
#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
;
rt_uint32_t
xfer_blks
;
};
struct
rthw_sdio
{
struct
rt_mmcsd_host
*
host
;
struct
ab32_sdio_des
sdio_des
;
struct
rt_event
event
;
struct
rt_mutex
mutex
;
struct
sdio_pkg
*
pkg
;
};
ALIGN
(
SDIO_ALIGN_LEN
)
static
rt_uint8_t
cache_buf
[
SDIO_BUFF_SIZE
];
static
uint8_t
sd_baud
=
119
;
uint8_t
sysclk_update_baud
(
uint8_t
baud
);
static
rt_uint32_t
ab32_sdio_clk_get
(
hal_sfr_t
hw_sdio
)
{
return
(
get_sysclk_nhz
()
/
(
sd_baud
+
1
));
}
/**
* @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 completed.
* @param sdio rthw_sdio
* @retval None
*/
static
void
rthw_sdio_wait_completed
(
struct
rthw_sdio
*
sdio
)
{
rt_uint32_t
status
=
0
;
struct
rt_mmcsd_cmd
*
cmd
=
sdio
->
pkg
->
cmd
;
struct
rt_mmcsd_data
*
data
=
cmd
->
data
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
rt_err_t
tx_finish
=
-
RT_ERROR
;
if
(
rt_event_recv
(
&
sdio
->
event
,
0xFFFFFFFF
&
~
HW_SDIO_CON_DFLAG
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
rt_tick_from_millisecond
(
5000
),
&
status
)
!=
RT_EOK
)
{
LOG_E
(
"wait completed timeout"
);
cmd
->
err
=
-
RT_ETIMEOUT
;
return
;
}
if
(
sdio
->
pkg
==
RT_NULL
)
{
return
;
}
cmd
->
resp
[
0
]
=
hw_sdio
[
SDARG3
];
cmd
->
resp
[
1
]
=
hw_sdio
[
SDARG2
];
cmd
->
resp
[
2
]
=
hw_sdio
[
SDARG1
];
cmd
->
resp
[
3
]
=
hw_sdio
[
SDARG0
];
if
(
!
(
status
&
HW_SDIO_CON_NRPS
))
{
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
{
cmd
->
err
=
-
RT_ERROR
;
}
}
/**
* @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
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
if
((
RT_NULL
==
pkg
)
||
(
RT_NULL
==
sdio
))
{
LOG_E
(
"rthw_sdio_transfer_by_dma invalid args"
);
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
)
{
LOG_D
(
"DATA_DIR_WRITE %d"
,
pkg
->
xfer_blks
);
sdio
->
sdio_des
.
txconfig
((
rt_uint32_t
*
)((
rt_uint8_t
*
)
buff
+
(
pkg
->
xfer_blks
*
data
->
blksize
)),
512
);
}
else
if
(
data
->
flags
&
DATA_DIR_READ
)
{
LOG_D
(
"DATA_DIR_WRITE %d"
,
pkg
->
xfer_blks
);
sdio
->
sdio_des
.
rxconfig
((
rt_uint32_t
*
)((
rt_uint8_t
*
)
buff
+
(
pkg
->
xfer_blks
*
data
->
blksize
)),
data
->
blksize
);
}
}
/**
* @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
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
rt_uint32_t
reg_cmd
=
0
;
rt_uint32_t
data_flag
=
0
;
/* save pkg */
sdio
->
pkg
=
pkg
;
#define CK8E BIT(11) //在命令/数据包后加上8CLK
#define CBUSY BIT(10) //Busy Check
#define CLRSP BIT(9) //17Byte Long Rsp
#define CRSP BIT(8) //Need Rsp
/* config cmd reg */
if
(
cmd
->
cmd_code
!=
18
)
{
reg_cmd
=
cmd
->
cmd_code
|
0x40
|
CK8E
;
}
else
{
reg_cmd
=
cmd
->
cmd_code
|
0x40
;
}
switch
(
resp_type
(
cmd
))
{
case
RESP_R1B
:
reg_cmd
|=
CBUSY
|
CRSP
;
break
;
case
RESP_R2
:
reg_cmd
|=
CLRSP
|
CRSP
;
break
;
default:
reg_cmd
|=
CRSP
;
break
;
}
LOG_D
(
"CMD:%d 0x%04X ARG:0x%08x RES:%s%s%s%s%s%s%s%s%s rw:%c len:%d blksize:%d"
,
cmd
->
cmd_code
,
reg_cmd
,
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 data reg */
if
(
data
!=
RT_NULL
)
{
rt_uint32_t
dir
=
0
;
rt_uint32_t
size
=
data
->
blks
*
data
->
blksize
;
int
order
;
order
=
get_order
(
data
->
blksize
);
dir
=
(
data
->
flags
&
DATA_DIR_READ
)
?
HW_SDIO_TO_HOST
:
0
;
data_flag
=
data
->
flags
;
}
/* transfer config */
if
(
data_flag
&
DATA_DIR_READ
)
{
rthw_sdio_transfer_by_dma
(
sdio
,
pkg
);
}
/* send cmd */
hw_sdio
[
SDARG3
]
=
cmd
->
arg
;
hw_sdio
[
SDCMD
]
=
reg_cmd
;
/* wait cmd completed */
rthw_sdio_wait_completed
(
sdio
);
/* transfer config */
if
(
data
!=
RT_NULL
)
{
do
{
if
((
data_flag
&
DATA_DIR_WRITE
)
||
((
data_flag
&
DATA_DIR_READ
)
&&
(
pkg
->
xfer_blks
!=
0
)))
{
rthw_sdio_transfer_by_dma
(
sdio
,
pkg
);
}
rt_uint32_t
status
=
0
;
if
(
rt_event_recv
(
&
sdio
->
event
,
0xFFFFFFFF
&
~
HW_SDIO_CON_DFLAG
,
RT_EVENT_FLAG_OR
|
RT_EVENT_FLAG_CLEAR
,
rt_tick_from_millisecond
(
5000
),
&
status
)
!=
RT_EOK
)
{
LOG_E
(
"wait completed timeout"
);
LOG_E
(
"SDCON=0x%X SDCMD=0x%X
\n
"
,
hw_sdio
[
SDCON
],
hw_sdio
[
SDCMD
]);
cmd
->
err
=
-
RT_ETIMEOUT
;
}
if
(
data_flag
&
DATA_DIR_WRITE
)
{
if
(((
hw_sdio
[
SDCON
]
&
HW_SDIO_CON_CRCS
)
>>
17
)
!=
2
)
{
LOG_E
(
"Write CRC error!"
);
cmd
->
err
=
-
RT_ERROR
;
hw_sdio
[
SDCPND
]
=
HW_SDIO_CON_DFLAG
;
}
}
}
while
(
++
pkg
->
xfer_blks
!=
data
->
blks
);
}
/* clear pkg */
sdio
->
pkg
=
RT_NULL
;
}
/**
* @brief This function send sdio request.
* @param host rt_mmcsd_host
* @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
);
pkg
.
buff
=
data
->
buf
;
if
((
rt_uint32_t
)
data
->
buf
&
(
SDIO_ALIGN_LEN
-
1
))
{
pkg
.
buff
=
cache_buf
;
if
(
data
->
flags
&
DATA_DIR_WRITE
)
{
rt_memcpy
(
cache_buf
,
data
->
buf
,
size
);
}
}
}
rthw_sdio_send_command
(
sdio
,
&
pkg
);
if
((
data
!=
RT_NULL
)
&&
(
data
->
flags
&
DATA_DIR_READ
)
&&
((
rt_uint32_t
)
data
->
buf
&
(
SDIO_ALIGN_LEN
-
1
)))
{
rt_memcpy
(
data
->
buf
,
cache_buf
,
data
->
blksize
*
data
->
blks
);
}
}
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 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
clkcr
,
div
,
clk_src
;
rt_uint32_t
clk
=
io_cfg
->
clock
;
struct
rthw_sdio
*
sdio
=
host
->
private_data
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
clk_src
=
sdio
->
sdio_des
.
clk_get
(
sdio
->
sdio_des
.
hw_sdio
);
if
(
clk_src
<
240
*
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(%d) is greater than clock source rate(%d).", clk, clk_src);
// 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_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
);
switch
(
io_cfg
->
power_mode
)
{
case
MMCSD_POWER_OFF
:
hw_sdio
[
SDCON
]
&=
~
BIT
(
0
);
break
;
case
MMCSD_POWER_UP
:
sd_baud
=
199
;
hw_sdio
[
SDCON
]
=
0
;
rt_thread_mdelay
(
1
);
hw_sdio
[
SDCON
]
|=
BIT
(
0
);
/* SD control enable */
hw_sdio
[
SDBAUD
]
=
sysclk_update_baud
(
sd_baud
);
hw_sdio
[
SDCON
]
|=
BIT
(
3
);
/* Keep clock output */
hw_sdio
[
SDCON
]
|=
BIT
(
4
);
hw_sdio
[
SDCON
]
|=
BIT
(
5
);
/* Data interrupt enable */
hal_mdelay
(
40
);
break
;
case
MMCSD_POWER_ON
:
if
(
clk
==
SDIO_MAX_FREQ
)
{
hw_sdio
[
SDCON
]
&=
~
BIT
(
3
);
sd_baud
=
3
;
hw_sdio
[
SDBAUD
]
=
sysclk_update_baud
(
sd_baud
);
}
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
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
if
(
enable
)
{
LOG_D
(
"enable sdio irq"
);
rt_hw_irq_enable
(
IRQ_SD_VECTOR
);
}
else
{
LOG_D
(
"disable sdio irq"
);
rt_hw_irq_disable
(
IRQ_SD_VECTOR
);
}
}
/**
* @brief This function detect sdcard.
* @param host rt_mmcsd_host
* @retval 0x01
*/
static
rt_int32_t
rthw_sd_detect
(
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
;
hal_sfr_t
hw_sdio
=
sdio
->
sdio_des
.
hw_sdio
;
rt_uint32_t
intstatus
=
hw_sdio
[
SDCON
];
/* clear flag */
if
(
intstatus
&
HW_SDIO_CON_CFLAG
)
{
complete
=
1
;
hw_sdio
[
SDCPND
]
=
HW_SDIO_CON_CFLAG
;
}
if
(
intstatus
&
HW_SDIO_CON_DFLAG
)
{
complete
=
1
;
hw_sdio
[
SDCPND
]
=
HW_SDIO_CON_DFLAG
;
}
if
(
complete
)
{
rt_event_send
(
&
sdio
->
event
,
intstatus
);
}
}
static
const
struct
rt_mmcsd_host_ops
ab32_sdio_ops
=
{
rthw_sdio_request
,
rthw_sdio_iocfg
,
rthw_sd_detect
,
rthw_sdio_irq_update
,
};
/**
* @brief This function create mmcsd host.
* @param sdio_des ab32_sdio_des
* @retval rt_mmcsd_host
*/
struct
rt_mmcsd_host
*
sdio_host_create
(
struct
ab32_sdio_des
*
sdio_des
)
{
struct
rt_mmcsd_host
*
host
;
struct
rthw_sdio
*
sdio
=
RT_NULL
;
if
((
sdio_des
==
RT_NULL
)
||
(
sdio_des
->
txconfig
==
RT_NULL
)
||
(
sdio_des
->
rxconfig
==
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
;
}
sdio
=
rt_malloc
(
sizeof
(
struct
rthw_sdio
));
if
(
sdio
==
RT_NULL
)
{
LOG_E
(
"L:%d F:%s 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
(
"L:%d F:%s mmcsd alloc host fail"
);
rt_free
(
sdio
);
return
RT_NULL
;
}
rt_memcpy
(
&
sdio
->
sdio_des
,
sdio_des
,
sizeof
(
struct
ab32_sdio_des
));
sdio
->
sdio_des
.
hw_sdio
=
(
sdio_des
->
hw_sdio
==
RT_NULL
?
SDMMC0_BASE
:
sdio_des
->
hw_sdio
);
sdio
->
sdio_des
.
clk_get
=
(
sdio_des
->
clk_get
==
RT_NULL
?
ab32_sdio_clk_get
:
sdio_des
->
clk_get
);
rt_event_init
(
&
sdio
->
event
,
"sdio"
,
RT_IPC_FLAG_FIFO
);
rt_mutex_init
(
&
sdio
->
mutex
,
"sdio"
,
RT_IPC_FLAG_FIFO
);
/* set host defautl attributes */
host
->
ops
=
&
ab32_sdio_ops
;
host
->
freq_min
=
240
*
1000
;
host
->
freq_max
=
SDIO_MAX_FREQ
;
host
->
valid_ocr
=
0X00FFFF80
;
/* The voltage range supported is 1.65v-3.6v */
#ifndef SDIO_USING_1_BIT
host
->
flags
=
MMCSD_BUSWIDTH_4
|
MMCSD_MUTBLKWRITE
|
MMCSD_SUP_SDIO_IRQ
;
#else
host
->
flags
=
MMCSD_MUTBLKWRITE
|
MMCSD_SUP_SDIO_IRQ
;
#endif
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
;
rthw_sdio_irq_update
(
host
,
1
);
/* ready to change */
mmcsd_change
(
host
);
return
host
;
}
static
rt_err_t
_dma_txconfig
(
rt_uint32_t
*
src
,
int
Size
)
{
hal_sfr_t
sdiox
=
sdio_config
->
instance
;
sdiox
[
SDDMAADR
]
=
DMA_ADR
(
src
);
sdiox
[
SDDMACNT
]
=
BIT
(
18
)
|
BIT
(
17
)
|
BIT
(
16
)
|
Size
;
return
RT_EOK
;
}
static
rt_err_t
_dma_rxconfig
(
rt_uint32_t
*
dst
,
int
Size
)
{
hal_sfr_t
sdiox
=
sdio_config
->
instance
;
sdiox
[
SDDMAADR
]
=
DMA_ADR
(
dst
);
sdiox
[
SDDMACNT
]
=
(
Size
);
return
RT_EOK
;
}
void
sdio_isr
(
int
vector
,
void
*
param
)
{
/* enter interrupt */
rt_interrupt_enter
();
/* Process All SDIO Interrupt Sources */
rthw_sdio_irq_process
(
host
);
/* leave interrupt */
rt_interrupt_leave
();
}
int
rt_hw_sdio_init
(
void
)
{
struct
ab32_sdio_des
sdio_des
=
{
0
};
struct
sd_handle
hsd
=
{
0
};
uint8_t
param
=
0
;
hsd
.
instance
=
SDMMC0_BASE
;
hal_rcu_periph_clk_enable
(
RCU_SD0
);
hal_sd_mspinit
(
&
hsd
);
rt_hw_interrupt_install
(
IRQ_SD_VECTOR
,
sdio_isr
,
&
param
,
"sd_isr"
);
sdio_des
.
clk_get
=
ab32_sdio_clk_get
;
sdio_des
.
hw_sdio
=
SDMMC0_BASE
;
sdio_des
.
rxconfig
=
_dma_rxconfig
;
sdio_des
.
txconfig
=
_dma_txconfig
;
host
=
sdio_host_create
(
&
sdio_des
);
return
0
;
}
INIT_DEVICE_EXPORT
(
rt_hw_sdio_init
);
void
ab32_mmcsd_change
(
void
)
{
mmcsd_change
(
host
);
}
#endif // 0
bsp/bluetrum/libraries/hal_drivers/drv_sdio.h
0 → 100644
浏览文件 @
7d0155ee
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-11-30 greedyhao first version
*/
#ifndef DEV_SDIO_H__
#define DEV_SDIO_H__
#include "drv_common.h"
#include "board.h"
#include "drivers/mmcsd_core.h"
#include "drivers/sdio.h"
#define SDIO_BUFF_SIZE 1024
#define SDIO_ALIGN_LEN 32
#ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (1000000)
#endif
#ifndef SDIO_BASE_ADDRESS
#define SDIO_BASE_ADDRESS (0x40012800U)
#endif
#ifndef SDIO_CLOCK_FREQ
#define SDIO_CLOCK_FREQ (48U * 1000 * 1000)
#endif
#ifndef SDIO_BUFF_SIZE
#define SDIO_BUFF_SIZE (4096)
#endif
#ifndef SDIO_ALIGN_LEN
#define SDIO_ALIGN_LEN (32)
#endif
#ifndef SDIO_MAX_FREQ
#define SDIO_MAX_FREQ (24 * 1000 * 1000)
#endif
#define HW_SDIO_CON_
#define HW_SDIO_CON_CFLAG (0x01u << 12)
/*!< 0:send command or received response not finish \
1:send command or received response finish */
#define HW_SDIO_CON_DFLAG (0x01u << 13)
/*!< 0:send or received data not finish \
1:send or received data finish */
#define HW_SDIO_CON_CCRCE (0x01u << 14)
/*!< 0:command crc no error \
1:command crc error detected */
#define HW_SDIO_CON_NRPS (0x01u << 15)
/*!< 0:response received 1:no response received */
#define HW_SDIO_CON_DCRCE (0x01u << 16)
/*!< 0:read data crc no error \
1:read data crc error detected */
#define HW_SDIO_CON_CRCS (0x07u << 17)
/*!< 101:error transmission \
010:non-erroneous transmission \
111:flash error */
#define HW_SDIO_CON_BUSY (0x01u << 20)
/*!< 0:device busy 1:device not busy */
#define HW_SDIO_ERRORS \
(0)
#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 ab32_sdio
// {};
typedef
rt_err_t
(
*
dma_txconfig
)(
rt_uint32_t
*
src
,
int
size
);
typedef
rt_err_t
(
*
dma_rxconfig
)(
rt_uint32_t
*
dst
,
int
size
);
typedef
rt_uint32_t
(
*
sdio_clk_get
)(
hal_sfr_t
hw_sdio
);
struct
ab32_sdio_des
{
hal_sfr_t
hw_sdio
;
dma_txconfig
txconfig
;
dma_rxconfig
rxconfig
;
sdio_clk_get
clk_get
;
};
struct
ab32_sdio_config
{
hal_sfr_t
instance
;
// struct dma_config dma_rx, dma_tx;
};
struct
ab32_sdio_class
{
const
struct
ab32_sdio_config
*
cfg
;
struct
rt_mmcsd_host
host
;
};
#endif
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h
浏览文件 @
7d0155ee
...
...
@@ -13,7 +13,7 @@
#define HAL_RCU_MODULE_ENABLED
#define HAL_WDT_MODULE_ENABLED
// #define HAL_DAC_MODULE_ENABLED
//
#define HAL_SD_MODULE_ENABLED
#define HAL_SD_MODULE_ENABLED
/* Includes */
#ifdef HAL_GPIO_MODULE_ENABLED
...
...
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_sd.h
浏览文件 @
7d0155ee
...
...
@@ -8,35 +8,73 @@
#define AB32VG1_HAL_SD_H__
#include "ab32vg1_hal_def.h"
#include "ab32vg1_ll_sdio.h"
#include <stdbool.h>
struct
sd_
init
struct
sd_
card_info
{
// uint8_t
uint32_t
rca
;
/*!< Specifies the Relative Card Address */
uint32_t
capacity
;
/*!< Specifies the capacity of the card */
uint8_t
abend
;
/*!< Specifies if the card is abnormal end */
uint8_t
flag_sdhc
;
/*!< Specifies if the card is SDHC card */
uint8_t
type
;
/*!< Specifies the card type */
uint8_t
state
;
/*!< Specifies the card state */
uint8_t
rw_state
;
/*!< Specifies the last r/w state of the card */
};
typedef
struct
sd_card_info
*
sd_card_info_t
;
struct
sd_c
ard_info
struct
sd_c
fg
{
uint32_t
rca
;
/*!< Specifies the Relative Card Address */
uint8_t
type
;
/*!< Specifies the card type */
uint16_t
go_ready_retry
;
uint8_t
identification_retry
;
uint8_t
rw_retry
;
uint8_t
rw_init_retry
;
uint8_t
stop_retry
;
uint8_t
rw_need_stop
;
};
typedef
struct
sd_card_info
*
sd_card_info_t
;
struct
sd_handle
{
hal_sfr_t
instance
;
struct
sd
_init
init
;
struct
sd
io_init
init
;
struct
sd_card_info
sdcard
;
struct
sd_cfg
cfg
;
};
typedef
struct
sd_handle
*
sd_handle_t
;
#define SD0N (0x00u)
#define SD0N (0x00u)
// #define CARD_SDSC (0x00u)
// #define CARD_SDHC (0x01u)
// #define CARD_SECURED (0x03u)
enum
{
CARD_INVAL
=
0x00
,
CARD_V1
,
CARD_V2
,
CARD_MMC
};
enum
{
HAL_SD_RW_STATE_IDLE
=
0x00
,
HAL_SD_RW_STATE_READ
,
HAL_SD_RW_STATE_WRITE
,
};
#define CARD_V1 (0x01u)
#define CARD_V2 (0x02u)
#define CARD_MMC (0x03u)
enum
{
HAL_SD_STATE_RESET
=
0x00
,
HAL_SD_STATE_NEW
,
HAL_SD_STATE_OK
,
HAL_SD_STATE_INVAL
,
};
#define SDMMC_CHECK_PATTERM (0x000001AAu)
#define SDMMC0_BASE ((hal_sfr_t)&SD0CON)
/* Initialization functions */
hal_error_t
hal_sd_init
(
sd_handle_t
hsd
);
void
hal_sd_deinit
(
uint32_t
sdx
);
...
...
@@ -44,7 +82,7 @@ void hal_sd_mspinit(sd_handle_t hsd);
hal_error_t
hal_sd_control
(
uint32_t
control
,
uint32_t
arg
);
void
hal_sd_write
(
uint32_t
sdx
,
uint32_t
data
);
uint32_t
hal_sd_read
(
uint32_t
sdx
);
bool
hal_sd_read
(
sd_handle_t
hsd
,
void
*
buf
,
uint32_t
lba
);
// void hal_uart_write_it(uint32_t uartx, uint8_t data);
// uint8_t hal_uart_read_it(uint32_t uartx);
...
...
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_ll_sdio.h
浏览文件 @
7d0155ee
...
...
@@ -11,8 +11,28 @@
struct
sdio_init
{
uint32_t
tmp
;
uint32_t
clock_power_save
;
/*!< Specifies whether SDMMC Clock output is enabled or
disabled when the bus is idle. */
uint32_t
clock_div
;
/*!< Specifies the clock frequency of the SDMMC controller.
This parameter can be a value between Min_Data = 0 and Max_Data = 255 */
};
typedef
struct
sdio_init
*
sdio_init_t
;
#define SDMMC_CLOCK_POWER_SAVE_DISABLE (0x00u)
#define SDMMC_CLOCK_POWER_SAVE_ENABLE (0x01u)
enum
{
SDCON
=
0
,
/* [20]:BUSY [19:17]:CRCS [16]:DCRCE [15]:NRPS [1]:Data bus width [0]:SD enable */
SDCPND
,
SDBAUD
,
SDCMD
,
SDARG3
,
SDARG2
,
SDARG1
,
SDARG0
,
SDDMAADR
,
SDDMACNT
,
};
#endif
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/source/ab32vg1_hal_sd.c
浏览文件 @
7d0155ee
#include "ab32vg1_hal.h"
#include "ab32vg1_ll_sdio.h"
#undef HAL_SD_MODULE_ENABLED
#ifdef HAL_SD_MODULE_ENABLED
#include <stdbool.h>
#define HAL_LOG(...) hal_printf(__VA_ARGS__)
/************************* LL ************************************/
...
...
@@ -27,20 +25,6 @@
#define RSP_BUSY_TIMEOUT 2400000 //大约2s
#define RSP_TIMEOUT 6000 //大约5ms
enum
{
SDCON
=
0
,
/* [20]:BUSY [19:17]:CRCS [16]:DCRCE [15]:NRPS [1]:Data bus width [0]:SD enable */
SDCPND
,
SDBAUD
,
SDCMD
,
SDARG3
,
SDARG2
,
SDARG1
,
SDARG0
,
SDDMAADR
,
SDDMACNT
,
};
uint8_t
sysclk_update_baud
(
uint8_t
baud
);
void
sdio_setbaud
(
hal_sfr_t
sdiox
,
uint8_t
baud
)
...
...
@@ -50,14 +34,18 @@ void sdio_setbaud(hal_sfr_t sdiox, uint8_t baud)
void
sdio_init
(
hal_sfr_t
sdiox
,
sdio_init_t
init
)
{
/* Set clock */
sdio_setbaud
(
sdiox
,
199
);
sdiox
[
SDCON
]
=
0
;
hal_udelay
(
20
);
sdiox
[
SDCON
]
|=
BIT
(
0
);
/* SD control enable */
sdiox
[
SDCON
]
|=
BIT
(
3
);
/* Keep clock output */
sdiox
[
SDCON
]
|=
BIT
(
5
);
/* Data interrupt enable */
sdiox
[
SDCON
]
|=
BIT
(
0
);
/* SD control enable */
sdio_setbaud
(
sdiox
,
init
->
clock_div
);
/* Set clock */
if
(
init
->
clock_power_save
==
SDMMC_CLOCK_POWER_SAVE_DISABLE
)
{
sdiox
[
SDCON
]
|=
BIT
(
3
);
/* Keep clock output */
}
else
{
sdiox
[
SDCON
]
&=
~
BIT
(
3
);
/* Keep clock output */
}
sdiox
[
SDCON
]
|=
BIT
(
5
);
/* Data interrupt enable */
hal_mdelay
(
40
);
}
...
...
@@ -89,16 +77,18 @@ bool sdio_check_rsp(hal_sfr_t sdiox)
return
!
(
sdiox
[
SDCON
]
&
BIT
(
15
));
}
bool
sdio_send_cmd
(
hal_sfr_t
sdiox
,
uint32_t
cmd
,
uint32_t
arg
)
bool
sdio_send_cmd
(
hal_sfr_t
sdiox
,
uint32_t
cmd
,
uint32_t
arg
,
uint8_t
*
abend
)
{
uint32_t
time_out
=
(
cmd
&
CBUSY
)
?
RSP_BUSY_TIMEOUT
:
RSP_TIMEOUT
;
sdiox
[
SDCMD
]
=
cmd
;
sdiox
[
SDARG3
]
=
arg
;
sdiox
[
SDCMD
]
=
cmd
;
while
(
sdio_check_finish
(
sdiox
)
==
false
)
{
if
(
--
time_out
==
0
)
{
HAL_LOG
(
"cmd time out
\n
"
);
// card.abend = 1;
if
(
abend
!=
HAL_NULL
)
{
*
abend
=
1
;
}
return
false
;
}
}
...
...
@@ -108,57 +98,258 @@ bool sdio_send_cmd(hal_sfr_t sdiox, uint32_t cmd, uint32_t arg)
uint8_t
sdio_get_cmd_rsp
(
hal_sfr_t
sdiox
)
{
return
-
1
;
return
sdiox
[
SDCMD
]
;
}
uint32_t
sdio_get_rsp
(
hal_sfr_t
sdiox
,
uint32_t
rsp
)
uint32_t
sdio_get_rsp
(
hal_sfr_t
sdiox
,
uint32_t
rsp
_reg
)
{
return
-
1
;
return
sdiox
[
rsp_reg
]
;
}
void
sdio_read_kick
(
hal_sfr_t
sdiox
,
void
*
buf
)
{}
{
sdiox
[
SDDMAADR
]
=
DMA_ADR
(
buf
);
sdiox
[
SDDMACNT
]
=
512
;
}
void
sdio_write_kick
(
hal_sfr_t
sdiox
,
void
*
buf
)
{}
{
sdiox
[
SDDMAADR
]
=
DMA_ADR
(
buf
);
sdiox
[
SDDMACNT
]
=
BIT
(
18
)
|
BIT
(
17
)
|
BIT
(
16
)
|
512
;
}
bool
sdio_isbusy
(
hal_sfr_t
sdiox
)
{
return
false
;
}
void
sdmmc_go_idle_state
(
hal_sfr_t
sdiox
)
bool
sdmmc_cmd_go_idle_state
(
sd_handle_t
hsd
)
{
return
sdio_send_cmd
(
hsd
->
instance
,
0
|
RSP_NO
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
}
bool
sdmmc_cmd_send_if_cond
(
sd_handle_t
hsd
)
{
return
sdio_send_cmd
(
hsd
->
instance
,
8
|
RSP_7
,
SDMMC_CHECK_PATTERM
,
&
(
hsd
->
sdcard
.
abend
));
}
bool
sdmmc_cmd_all_send_cid
(
sd_handle_t
hsd
)
{
return
sdio_send_cmd
(
hsd
->
instance
,
2
|
RSP_2
,
0
,
&
(
hsd
->
sdcard
.
abend
));
}
void
sdmmc_cmd_set_rel_addr
(
sd_handle_t
hsd
)
{
hal_sfr_t
sdiox
=
hsd
->
instance
;
if
(
hsd
->
sdcard
.
type
==
CARD_MMC
)
{
hsd
->
sdcard
.
rca
=
0x00010000
;
sdio_send_cmd
(
sdiox
,
3
|
RSP_1
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
}
else
{
sdio_send_cmd
(
sdiox
,
3
|
RSP_6
,
0
,
&
(
hsd
->
sdcard
.
abend
));
hsd
->
sdcard
.
rca
=
sdio_get_rsp
(
sdiox
,
SDARG3
)
&
0xffff0000
;
}
}
void
sdmmc_cmd_send_csd
(
sd_handle_t
hsd
)
{
hal_sfr_t
sdiox
=
hsd
->
instance
;
sdio_send_cmd
(
sdiox
,
9
|
RSP_2
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
if
(
hsd
->
sdcard
.
type
==
CARD_MMC
)
{
//
}
else
{
if
(
hsd
->
sdcard
.
flag_sdhc
==
1
)
{
hsd
->
sdcard
.
capacity
=
(
sdio_get_rsp
(
sdiox
,
SDARG2
)
<<
24
)
&
0x00ff0000
;
/* rspbuf[8] */
hsd
->
sdcard
.
capacity
|=
((
sdio_get_rsp
(
sdiox
,
SDARG1
)
>>
16
)
&
0x0000ffff
);
/* rspbuf[9] rspbuf[10] */
hsd
->
sdcard
.
capacity
+=
1
;
hsd
->
sdcard
.
capacity
<<=
10
;
}
}
HAL_LOG
(
"sd capacity=%d
\n
"
,
hsd
->
sdcard
.
capacity
);
}
void
sdmmc_cmd_select_card
(
sd_handle_t
hsd
)
{
sdio_send_cmd
(
hsd
->
instance
,
7
|
RSP_1B
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
}
bool
sdmmc_cmd_read_multiblock
(
sd_handle_t
hsd
)
{
return
sdio_send_cmd
(
hsd
->
instance
,
REQ_MULTREAD
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
}
bool
sdmmc_cmd_app
(
sd_handle_t
hsd
)
{
// hal_sfr_t sdiox = hsd->instance;
sdio_send_cmd
(
sdiox
,
0x00
|
RSP_NO
,
0
);
return
sdio_send_cmd
(
hsd
->
instance
,
55
|
RSP_1
,
hsd
->
sdcard
.
rca
,
&
(
hsd
->
sdcard
.
abend
));
}
void
sdmmc_send_if_cond
(
hal_sfr_t
sdiox
)
bool
sdmmc_acmd_op_cond
(
sd_handle_t
hsd
,
uint32_t
voltage
)
{
// hal_sfr_t sdiox = hsd->instance;
sdio_send_cmd
(
sdiox
,
0x08
|
RSP_7
,
SDMMC_CHECK_PATTERM
);
/* SEND CMD55 APP_CMD with RCA */
if
(
sdmmc_cmd_app
(
hsd
))
{
/* Send CMD41 */
if
(
sdio_send_cmd
(
hsd
->
instance
,
41
|
RSP_3
,
voltage
,
&
(
hsd
->
sdcard
.
abend
)))
{
return
true
;
}
}
return
false
;
}
/************************* HAL ************************************/
static
bool
sd_type_identification
(
sd_handle_t
hsd
)
{
uint8_t
retry
=
hsd
->
cfg
.
identification_retry
;
while
(
retry
--
>
0
)
{
/* CMD0: GO_IDLE_STATE */
sdmmc_cmd_go_idle_state
(
hsd
);
/* CMD8: SEND_IF_COND: Command available only on V2.0 cards */
if
(
sdmmc_cmd_send_if_cond
(
hsd
))
{
if
(
sdio_get_cmd_rsp
(
hsd
->
instance
)
==
0x08
)
{
hsd
->
sdcard
.
type
=
CARD_V2
;
HAL_LOG
(
"SD 2.0
\n
"
);
return
true
;
}
continue
;
}
if
(
sdmmc_acmd_op_cond
(
hsd
,
0x00ff8000
))
{
hsd
->
sdcard
.
type
=
CARD_V1
;
HAL_LOG
(
"SD 1.0
\n
"
);
return
true
;
}
hal_mdelay
(
20
);
}
return
false
;
}
static
void
sd_poweron
(
sd_handle_t
hsd
)
static
bool
sd_go_ready_try
(
sd_handle_t
hsd
)
{
sdmmc_go_idle_state
(
hsd
->
instance
);
sdmmc_send_if_cond
(
hsd
->
instance
);
if
(
hsd
->
instance
[
SDCMD
]
==
0x08
)
{
hsd
->
sdcard
.
type
=
CARD_V2
;
HAL_LOG
(
"SD 2.0
\n
"
);
uint32_t
tmp
=
0
;
switch
(
hsd
->
sdcard
.
type
)
{
case
CARD_V1
:
sdmmc_acmd_op_cond
(
hsd
,
0x00ff8000
);
break
;
case
CARD_V2
:
sdmmc_acmd_op_cond
(
hsd
,
0x40ff8000
);
break
;
default:
break
;
}
if
(
0
==
(
hsd
->
instance
[
SDARG3
]
&
BIT
(
31
)))
{
return
false
;
// no ready
}
if
((
hsd
->
sdcard
.
type
==
CARD_V2
)
&&
(
hsd
->
instance
[
SDARG3
]
&
BIT
(
30
)))
{
HAL_LOG
(
"SDHC
\n
"
);
hsd
->
sdcard
.
flag_sdhc
=
1
;
}
return
true
;
}
static
bool
sd_go_ready
(
sd_handle_t
hsd
)
{
if
(
hsd
->
sdcard
.
type
==
CARD_INVAL
)
{
return
false
;
}
uint8_t
retry
=
hsd
->
cfg
.
go_ready_retry
;
while
(
retry
--
>
0
)
{
if
(
sd_go_ready_try
(
hsd
)
==
true
)
{
return
true
;
}
hal_mdelay
(
20
);
}
return
false
;
}
static
bool
sd_poweron
(
sd_handle_t
hsd
)
{
if
(
sd_type_identification
(
hsd
)
==
false
)
{
HAL_LOG
(
"card invalid
\n
"
);
return
false
;
}
if
(
sd_go_ready
(
hsd
)
==
false
)
{
HAL_LOG
(
"no ready
\n
"
);
return
false
;
}
return
true
;
}
static
void
sd_init_card
(
sd_handle_t
hsd
)
{
/* Send CMD2 ALL_SEND_CID */
sdmmc_cmd_all_send_cid
(
hsd
);
/* Send CMD3 SET_REL_ADDR */
sdmmc_cmd_set_rel_addr
(
hsd
);
/* Send CMD9 SEND_CSD */
sdmmc_cmd_send_csd
(
hsd
);
/* Select the Card */
sdmmc_cmd_select_card
(
hsd
);
hsd
->
init
.
clock_div
=
3
;
hsd
->
init
.
clock_power_save
=
SDMMC_CLOCK_POWER_SAVE_ENABLE
;
sdio_init
(
hsd
->
instance
,
&
(
hsd
->
init
));
}
static
bool
sd_read_wait
(
sd_handle_t
hsd
)
{
bool
ret
=
false
;
hal_sfr_t
sdiox
=
hsd
->
instance
;
return
ret
;
}
static
void
sd_read_start
(
sd_handle_t
hsd
,
void
*
buf
,
uint32_t
lba
)
{
if
(
hsd
->
sdcard
.
rw_state
==
HAL_SD_RW_STATE_READ
)
{
}
else
{
if
(
hsd
->
sdcard
.
rw_state
==
HAL_SD_RW_STATE_WRITE
)
{
}
sdio_read_kick
(
hsd
->
instance
,
buf
);
sdmmc_cmd_read_multiblock
(
hsd
);
}
hsd
->
sdcard
.
rw_state
=
HAL_SD_RW_STATE_READ
;
// hsd->sdcard.rw_lba
}
static
bool
sd_read_try
(
sd_handle_t
hsd
,
void
*
buf
,
uint32_t
lba
)
{
HAL_LOG
(
"read: %08x
\n
"
,
lba
);
if
(
hsd
->
sdcard
.
capacity
<
lba
)
{
lba
=
hsd
->
sdcard
.
capacity
-
1
;
}
sd_read_start
(
hsd
,
buf
,
lba
);
return
0
;
}
void
hal_sd_initcard
(
sd_handle_t
hsd
)
{
struct
sdio_init
init
=
{
0
};
hal_sfr_t
sdiox
=
hsd
->
instance
;
sdio_init
(
sdiox
,
&
init
);
hsd
->
init
.
clock_div
=
119
;
/* SD clk 240KHz when system clk is 48MHz */
hsd
->
init
.
clock_power_save
=
SDMMC_CLOCK_POWER_SAVE_DISABLE
;
sdio_init
(
sdiox
,
&
(
hsd
->
init
));
sd_poweron
(
hsd
);
sd_init_card
(
hsd
);
}
WEAK
void
hal_sd_mspinit
(
sd_handle_t
hsd
)
...
...
@@ -171,6 +362,11 @@ hal_error_t hal_sd_init(sd_handle_t hsd)
return
-
HAL_ERROR
;
}
hsd
->
cfg
.
go_ready_retry
=
200
;
hsd
->
cfg
.
identification_retry
=
5
;
hsd
->
cfg
.
rw_init_retry
=
3
;
hsd
->
cfg
.
rw_retry
=
3
;
hal_sd_mspinit
(
hsd
);
hal_sd_initcard
(
hsd
);
...
...
@@ -181,4 +377,25 @@ void hal_sd_deinit(uint32_t sdx)
{
}
bool
hal_sd_read
(
sd_handle_t
hsd
,
void
*
buf
,
uint32_t
lba
)
{
uint8_t
init_retry
=
hsd
->
cfg
.
rw_init_retry
;
while
(
init_retry
--
>
0
)
{
uint8_t
retry
=
hsd
->
cfg
.
rw_retry
;
while
(
retry
--
>
0
)
{
if
(
sd_read_try
(
hsd
,
buf
,
lba
))
{
return
true
;
}
}
hsd
->
sdcard
.
state
=
HAL_SD_STATE_INVAL
;
hal_mdelay
(
20
);
}
return
false
;
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录