Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
宁楠萍
rt-thread
提交
74812c0f
R
rt-thread
项目概览
宁楠萍
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
74812c0f
编写于
10月 27, 2020
作者:
B
bigmagic
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add raspi4 sdio driver
上级
8cf83694
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
1003 addition
and
3 deletion
+1003
-3
bsp/raspberry-pi/raspi4-32/.config
bsp/raspberry-pi/raspi4-32/.config
+26
-3
bsp/raspberry-pi/raspi4-32/applications/mnt.c
bsp/raspberry-pi/raspi4-32/applications/mnt.c
+27
-0
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
+656
-0
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.h
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.h
+253
-0
bsp/raspberry-pi/raspi4-32/driver/raspi4.h
bsp/raspberry-pi/raspi4-32/driver/raspi4.h
+21
-0
bsp/raspberry-pi/raspi4-32/rtconfig.h
bsp/raspberry-pi/raspi4-32/rtconfig.h
+20
-0
未找到文件。
bsp/raspberry-pi/raspi4-32/.config
浏览文件 @
74812c0f
...
@@ -112,7 +112,23 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
...
@@ -112,7 +112,23 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX
=
2
CONFIG_DFS_FILESYSTEM_TYPES_MAX
=
2
CONFIG_DFS_FD_MAX
=
16
CONFIG_DFS_FD_MAX
=
16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_ELMFAT
=
y
#
# elm-chan's FatFs, Generic FAT Filesystem Module
#
CONFIG_RT_DFS_ELM_CODE_PAGE
=
437
CONFIG_RT_DFS_ELM_WORD_ACCESS
=
y
# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
CONFIG_RT_DFS_ELM_USE_LFN_3
=
y
CONFIG_RT_DFS_ELM_USE_LFN
=
3
CONFIG_RT_DFS_ELM_MAX_LFN
=
255
CONFIG_RT_DFS_ELM_DRIVES
=
2
CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE
=
512
# CONFIG_RT_DFS_ELM_USE_ERASE is not set
CONFIG_RT_DFS_ELM_REENTRANT
=
y
CONFIG_RT_USING_DFS_DEVFS
=
y
CONFIG_RT_USING_DFS_DEVFS
=
y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
...
@@ -140,7 +156,13 @@ CONFIG_RT_USING_PIN=y
...
@@ -140,7 +156,13 @@ CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_RTC is not set
# CONFIG_RT_USING_SDIO is not set
CONFIG_RT_USING_SDIO
=
y
CONFIG_RT_SDIO_STACK_SIZE
=
512
CONFIG_RT_SDIO_THREAD_PRIORITY
=
15
CONFIG_RT_MMCSD_STACK_SIZE
=
1024
CONFIG_RT_MMCSD_THREAD_PREORITY
=
22
CONFIG_RT_MMCSD_MAX_PARTITION
=
16
# CONFIG_RT_SDIO_DEBUG is not set
CONFIG_RT_USING_SPI
=
y
CONFIG_RT_USING_SPI
=
y
# CONFIG_RT_USING_QSPI is not set
# CONFIG_RT_USING_QSPI is not set
# CONFIG_RT_USING_SPI_MSD is not set
# CONFIG_RT_USING_SPI_MSD is not set
...
@@ -525,7 +547,8 @@ CONFIG_BSP_USING_CORETIMER=y
...
@@ -525,7 +547,8 @@ CONFIG_BSP_USING_CORETIMER=y
# CONFIG_BSP_USING_SYSTIMER is not set
# CONFIG_BSP_USING_SYSTIMER is not set
CONFIG_BSP_USING_WDT
=
y
CONFIG_BSP_USING_WDT
=
y
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_RTC is not set
# CONFIG_BSP_USING_SDIO is not set
CONFIG_BSP_USING_SDIO
=
y
CONFIG_BSP_USING_SDIO0
=
y
#
#
# Board Peripheral Drivers
# Board Peripheral Drivers
...
...
bsp/raspberry-pi/raspi4-32/applications/mnt.c
0 → 100644
浏览文件 @
74812c0f
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-5-30 bernard the first version
*/
#include <rtthread.h>
#ifdef BSP_USING_SDIO0
#include <dfs_fs.h>
int
mnt_init
(
void
)
{
rt_thread_delay
(
RT_TICK_PER_SECOND
);
if
(
dfs_mount
(
"sd0"
,
"/"
,
"elm"
,
0
,
0
)
==
0
)
{
rt_kprintf
(
"file system initialization done!
\n
"
);
}
return
0
;
}
INIT_ENV_EXPORT
(
mnt_init
);
#endif
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.c
0 → 100644
浏览文件 @
74812c0f
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-27 bigmagic first version
*/
#include "mbox.h"
#include "raspi4.h"
#include "drv_sdio.h"
static
rt_uint32_t
mmc_base_clock
=
0
;
static
rt_uint32_t
sdCommandTable
[]
=
{
SD_CMD_INDEX
(
0
),
SD_CMD_RESERVED
(
1
),
SD_CMD_INDEX
(
2
)
|
SD_RESP_R2
,
SD_CMD_INDEX
(
3
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
4
),
SD_CMD_RESERVED
(
5
),
//SD_CMD_INDEX(5) | SD_RESP_R4,
SD_CMD_INDEX
(
6
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
7
)
|
SD_RESP_R1b
,
SD_CMD_INDEX
(
8
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
9
)
|
SD_RESP_R2
,
SD_CMD_INDEX
(
10
)
|
SD_RESP_R2
,
SD_CMD_INDEX
(
11
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
12
)
|
SD_RESP_R1b
|
SD_CMD_TYPE_ABORT
,
SD_CMD_INDEX
(
13
)
|
SD_RESP_R1
,
SD_CMD_RESERVED
(
14
),
SD_CMD_INDEX
(
15
),
SD_CMD_INDEX
(
16
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
17
)
|
SD_RESP_R1
|
SD_DATA_READ
,
SD_CMD_INDEX
(
18
)
|
SD_RESP_R1
|
SD_DATA_READ
|
SD_CMD_MULTI_BLOCK
|
SD_CMD_BLKCNT_EN
,
SD_CMD_INDEX
(
19
)
|
SD_RESP_R1
|
SD_DATA_READ
,
SD_CMD_INDEX
(
20
)
|
SD_RESP_R1b
,
SD_CMD_RESERVED
(
21
),
SD_CMD_RESERVED
(
22
),
SD_CMD_INDEX
(
23
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
24
)
|
SD_RESP_R1
|
SD_DATA_WRITE
,
SD_CMD_INDEX
(
25
)
|
SD_RESP_R1
|
SD_DATA_WRITE
|
SD_CMD_MULTI_BLOCK
|
SD_CMD_BLKCNT_EN
,
SD_CMD_INDEX
(
26
)
|
SD_RESP_R1
|
SD_DATA_WRITE
,
//add
SD_CMD_INDEX
(
27
)
|
SD_RESP_R1
|
SD_DATA_WRITE
,
SD_CMD_INDEX
(
28
)
|
SD_RESP_R1b
,
SD_CMD_INDEX
(
29
)
|
SD_RESP_R1b
,
SD_CMD_INDEX
(
30
)
|
SD_RESP_R1
|
SD_DATA_READ
,
SD_CMD_RESERVED
(
31
),
SD_CMD_INDEX
(
32
)
|
SD_RESP_R1
,
SD_CMD_INDEX
(
33
)
|
SD_RESP_R1
,
SD_CMD_RESERVED
(
34
),
SD_CMD_INDEX
(
35
)
|
SD_RESP_R1
,
//add
SD_CMD_INDEX
(
36
)
|
SD_RESP_R1
,
//add
SD_CMD_RESERVED
(
37
),
SD_CMD_INDEX
(
38
)
|
SD_RESP_R1b
,
SD_CMD_INDEX
(
39
)
|
SD_RESP_R4
,
//add
SD_CMD_INDEX
(
40
)
|
SD_RESP_R5
,
//add
SD_CMD_INDEX
(
41
)
|
SD_RESP_R3
,
//add, mov from harbote
SD_CMD_RESERVED
(
42
)
|
SD_RESP_R1
,
SD_CMD_RESERVED
(
43
),
SD_CMD_RESERVED
(
44
),
SD_CMD_RESERVED
(
45
),
SD_CMD_RESERVED
(
46
),
SD_CMD_RESERVED
(
47
),
SD_CMD_RESERVED
(
48
),
SD_CMD_RESERVED
(
49
),
SD_CMD_RESERVED
(
50
),
SD_CMD_INDEX
(
51
)
|
SD_RESP_R1
|
SD_DATA_READ
,
SD_CMD_RESERVED
(
52
),
SD_CMD_RESERVED
(
53
),
SD_CMD_RESERVED
(
54
),
SD_CMD_INDEX
(
55
)
|
SD_RESP_R3
,
SD_CMD_INDEX
(
56
)
|
SD_RESP_R1
|
SD_CMD_ISDATA
,
SD_CMD_RESERVED
(
57
),
SD_CMD_RESERVED
(
58
),
SD_CMD_RESERVED
(
59
),
SD_CMD_RESERVED
(
60
),
SD_CMD_RESERVED
(
61
),
SD_CMD_RESERVED
(
62
),
SD_CMD_RESERVED
(
63
)
};
static
inline
rt_uint32_t
read32
(
rt_uint32_t
addr
)
{
return
(
*
((
volatile
unsigned
int
*
)(
addr
)));
}
static
inline
void
write32
(
rt_uint32_t
addr
,
rt_uint32_t
value
)
{
(
*
((
volatile
unsigned
int
*
)(
addr
)))
=
value
;
}
rt_err_t
sd_int
(
struct
sdhci_pdata_t
*
pdat
,
rt_uint32_t
mask
)
{
rt_uint32_t
r
;
rt_uint32_t
m
=
mask
|
INT_ERROR_MASK
;
int
cnt
=
1000000
;
while
(
!
(
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
)
&
(
m
|
INT_ERROR_MASK
))
&&
cnt
--
)
DELAY_MICROS
(
1
);
r
=
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
);
if
(
cnt
<=
0
||
(
r
&
INT_CMD_TIMEOUT
)
||
(
r
&
INT_DATA_TIMEOUT
))
{
write32
(
pdat
->
virt
+
EMMC_INTERRUPT
,
r
);
//qemu maybe can not use sdcard
//rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
//return -RT_ETIMEOUT;
}
else
if
(
r
&
INT_ERROR_MASK
)
{
write32
(
pdat
->
virt
+
EMMC_INTERRUPT
,
r
);
rt_kprintf
(
"send cmd/data error %x -> %x
\n
"
,
r
,
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
));
return
-
RT_ERROR
;
}
write32
(
pdat
->
virt
+
EMMC_INTERRUPT
,
mask
);
return
RT_EOK
;
}
rt_err_t
sd_status
(
struct
sdhci_pdata_t
*
pdat
,
unsigned
int
mask
)
{
int
cnt
=
500000
;
while
((
read32
(
pdat
->
virt
+
EMMC_STATUS
)
&
mask
)
&&
!
(
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
)
&
INT_ERROR_MASK
)
&&
cnt
--
)
DELAY_MICROS
(
1
);
if
(
cnt
<=
0
)
{
return
-
RT_ETIMEOUT
;
}
else
if
(
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
)
&
INT_ERROR_MASK
)
{
return
-
RT_ERROR
;
}
return
RT_EOK
;
}
static
rt_err_t
raspi_transfer_command
(
struct
sdhci_pdata_t
*
pdat
,
struct
sdhci_cmd_t
*
cmd
)
{
rt_uint32_t
cmdidx
;
rt_err_t
ret
=
RT_EOK
;
ret
=
sd_status
(
pdat
,
SR_CMD_INHIBIT
);
if
(
ret
)
{
rt_kprintf
(
"ERROR: EMMC busy %d
\n
"
,
ret
);
return
ret
;
}
cmdidx
=
sdCommandTable
[
cmd
->
cmdidx
];
if
(
cmdidx
==
0xFFFFFFFF
)
return
-
RT_EINVAL
;
if
(
cmd
->
datarw
==
DATA_READ
)
cmdidx
|=
SD_DATA_READ
;
if
(
cmd
->
datarw
==
DATA_WRITE
)
cmdidx
|=
SD_DATA_WRITE
;
mmcsd_dbg
(
"transfer cmd %x(%d) %x %x
\n
"
,
cmdidx
,
cmd
->
cmdidx
,
cmd
->
cmdarg
,
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
));
write32
(
pdat
->
virt
+
EMMC_INTERRUPT
,
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
));
write32
(
pdat
->
virt
+
EMMC_ARG1
,
cmd
->
cmdarg
);
write32
(
pdat
->
virt
+
EMMC_CMDTM
,
cmdidx
);
if
(
cmd
->
cmdidx
==
SD_APP_OP_COND
)
DELAY_MICROS
(
1000
);
else
if
((
cmd
->
cmdidx
==
SD_SEND_IF_COND
)
||
(
cmd
->
cmdidx
==
APP_CMD
))
DELAY_MICROS
(
100
);
ret
=
sd_int
(
pdat
,
INT_CMD_DONE
);
if
(
ret
)
{
return
ret
;
}
if
(
cmd
->
resptype
&
RESP_MASK
)
{
if
(
cmd
->
resptype
&
RESP_R2
)
{
rt_uint32_t
resp
[
4
];
resp
[
0
]
=
read32
(
pdat
->
virt
+
EMMC_RESP0
);
resp
[
1
]
=
read32
(
pdat
->
virt
+
EMMC_RESP1
);
resp
[
2
]
=
read32
(
pdat
->
virt
+
EMMC_RESP2
);
resp
[
3
]
=
read32
(
pdat
->
virt
+
EMMC_RESP3
);
if
(
cmd
->
resptype
==
RESP_R2
)
{
cmd
->
response
[
0
]
=
resp
[
3
]
<<
8
|
((
resp
[
2
]
>>
24
)
&
0xff
);
cmd
->
response
[
1
]
=
resp
[
2
]
<<
8
|
((
resp
[
1
]
>>
24
)
&
0xff
);
cmd
->
response
[
2
]
=
resp
[
1
]
<<
8
|
((
resp
[
0
]
>>
24
)
&
0xff
);
cmd
->
response
[
3
]
=
resp
[
0
]
<<
8
;
}
else
{
cmd
->
response
[
0
]
=
resp
[
0
];
cmd
->
response
[
1
]
=
resp
[
1
];
cmd
->
response
[
2
]
=
resp
[
2
];
cmd
->
response
[
3
]
=
resp
[
3
];
}
}
else
cmd
->
response
[
0
]
=
read32
(
pdat
->
virt
+
EMMC_RESP0
);
}
mmcsd_dbg
(
"response: %x: %x %x %x %x (%x, %x)
\n
"
,
cmd
->
resptype
,
cmd
->
response
[
0
],
cmd
->
response
[
1
],
cmd
->
response
[
2
],
cmd
->
response
[
3
],
read32
(
pdat
->
virt
+
EMMC_STATUS
),
read32
(
pdat
->
virt
+
EMMC_INTERRUPT
));
return
ret
;
}
static
rt_err_t
read_bytes
(
struct
sdhci_pdata_t
*
pdat
,
rt_uint32_t
*
buf
,
rt_uint32_t
blkcount
,
rt_uint32_t
blksize
)
{
int
c
=
0
;
rt_err_t
ret
;
int
d
;
while
(
c
<
blkcount
)
{
if
((
ret
=
sd_int
(
pdat
,
INT_READ_RDY
)))
{
rt_kprintf
(
"timeout happens when reading block %d
\n
"
,
c
);
return
ret
;
}
for
(
d
=
0
;
d
<
blksize
/
4
;
d
++
)
if
(
read32
(
pdat
->
virt
+
EMMC_STATUS
)
&
SR_READ_AVAILABLE
)
buf
[
d
]
=
read32
(
pdat
->
virt
+
EMMC_DATA
);
c
++
;
buf
+=
blksize
/
4
;
}
return
RT_EOK
;
}
static
rt_err_t
write_bytes
(
struct
sdhci_pdata_t
*
pdat
,
rt_uint32_t
*
buf
,
rt_uint32_t
blkcount
,
rt_uint32_t
blksize
)
{
int
c
=
0
;
rt_err_t
ret
;
int
d
;
while
(
c
<
blkcount
)
{
if
((
ret
=
sd_int
(
pdat
,
INT_WRITE_RDY
)))
{
return
ret
;
}
for
(
d
=
0
;
d
<
blksize
/
4
;
d
++
)
write32
(
pdat
->
virt
+
EMMC_DATA
,
buf
[
d
]);
c
++
;
buf
+=
blksize
/
4
;
}
if
((
ret
=
sd_int
(
pdat
,
INT_DATA_DONE
)))
{
return
ret
;
}
return
RT_EOK
;
}
static
rt_err_t
raspi_transfer_data
(
struct
sdhci_pdata_t
*
pdat
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
)
{
rt_uint32_t
dlen
=
(
rt_uint32_t
)(
dat
->
blkcnt
*
dat
->
blksz
);
rt_err_t
ret
=
sd_status
(
pdat
,
SR_DAT_INHIBIT
);
if
(
ret
)
{
rt_kprintf
(
"ERROR: EMMC busy
\n
"
);
return
ret
;
}
if
(
dat
->
blkcnt
>
1
)
{
struct
sdhci_cmd_t
newcmd
;
newcmd
.
cmdidx
=
SET_BLOCK_COUNT
;
newcmd
.
cmdarg
=
dat
->
blkcnt
;
newcmd
.
resptype
=
RESP_R1
;
ret
=
raspi_transfer_command
(
pdat
,
&
newcmd
);
if
(
ret
)
return
ret
;
}
if
(
dlen
<
512
)
{
write32
(
pdat
->
virt
+
EMMC_BLKSIZECNT
,
dlen
|
1
<<
16
);
}
else
{
write32
(
pdat
->
virt
+
EMMC_BLKSIZECNT
,
512
|
(
dat
->
blkcnt
)
<<
16
);
}
if
(
dat
->
flag
&
DATA_DIR_READ
)
{
cmd
->
datarw
=
DATA_READ
;
ret
=
raspi_transfer_command
(
pdat
,
cmd
);
if
(
ret
)
return
ret
;
mmcsd_dbg
(
"read_block %d, %d
\n
"
,
dat
->
blkcnt
,
dat
->
blksz
);
ret
=
read_bytes
(
pdat
,
(
rt_uint32_t
*
)
dat
->
buf
,
dat
->
blkcnt
,
dat
->
blksz
);
}
else
if
(
dat
->
flag
&
DATA_DIR_WRITE
)
{
cmd
->
datarw
=
DATA_WRITE
;
ret
=
raspi_transfer_command
(
pdat
,
cmd
);
if
(
ret
)
return
ret
;
mmcsd_dbg
(
"write_block %d, %d"
,
dat
->
blkcnt
,
dat
->
blksz
);
ret
=
write_bytes
(
pdat
,
(
rt_uint32_t
*
)
dat
->
buf
,
dat
->
blkcnt
,
dat
->
blksz
);
}
return
ret
;
}
static
rt_err_t
sdhci_transfer
(
struct
sdhci_t
*
sdhci
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
)
{
struct
sdhci_pdata_t
*
pdat
=
(
struct
sdhci_pdata_t
*
)
sdhci
->
priv
;
if
(
!
dat
)
return
raspi_transfer_command
(
pdat
,
cmd
);
return
raspi_transfer_data
(
pdat
,
cmd
,
dat
);
}
static
void
mmc_request_send
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_req
*
req
)
{
struct
sdhci_t
*
sdhci
=
(
struct
sdhci_t
*
)
host
->
private_data
;
struct
sdhci_cmd_t
cmd
;
struct
sdhci_cmd_t
stop
;
struct
sdhci_data_t
dat
;
rt_memset
(
&
cmd
,
0
,
sizeof
(
struct
sdhci_cmd_t
));
rt_memset
(
&
stop
,
0
,
sizeof
(
struct
sdhci_cmd_t
));
rt_memset
(
&
dat
,
0
,
sizeof
(
struct
sdhci_data_t
));
cmd
.
cmdidx
=
req
->
cmd
->
cmd_code
;
cmd
.
cmdarg
=
req
->
cmd
->
arg
;
cmd
.
resptype
=
resp_type
(
req
->
cmd
);
if
(
req
->
data
)
{
dat
.
buf
=
(
rt_uint8_t
*
)
req
->
data
->
buf
;
dat
.
flag
=
req
->
data
->
flags
;
dat
.
blksz
=
req
->
data
->
blksize
;
dat
.
blkcnt
=
req
->
data
->
blks
;
req
->
cmd
->
err
=
sdhci_transfer
(
sdhci
,
&
cmd
,
&
dat
);
}
else
{
req
->
cmd
->
err
=
sdhci_transfer
(
sdhci
,
&
cmd
,
RT_NULL
);
}
req
->
cmd
->
resp
[
3
]
=
cmd
.
response
[
3
];
req
->
cmd
->
resp
[
2
]
=
cmd
.
response
[
2
];
req
->
cmd
->
resp
[
1
]
=
cmd
.
response
[
1
];
req
->
cmd
->
resp
[
0
]
=
cmd
.
response
[
0
];
if
(
req
->
stop
)
{
stop
.
cmdidx
=
req
->
stop
->
cmd_code
;
stop
.
cmdarg
=
req
->
stop
->
arg
;
cmd
.
resptype
=
resp_type
(
req
->
stop
);
req
->
stop
->
err
=
sdhci_transfer
(
sdhci
,
&
stop
,
RT_NULL
);
}
mmcsd_req_complete
(
host
);
}
rt_int32_t
mmc_card_status
(
struct
rt_mmcsd_host
*
host
)
{
return
0
;
}
static
rt_err_t
sdhci_detect
(
struct
sdhci_t
*
sdhci
)
{
return
RT_EOK
;
}
static
rt_err_t
sdhci_setwidth
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
width
)
{
rt_uint32_t
temp
=
0
;
struct
sdhci_pdata_t
*
pdat
=
(
struct
sdhci_pdata_t
*
)
sdhci
->
priv
;
if
(
width
==
MMCSD_BUS_WIDTH_4
)
{
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL0
));
temp
|=
C0_HCTL_HS_EN
;
temp
|=
C0_HCTL_DWITDH
;
// always use 4 data lines:
write32
((
pdat
->
virt
+
EMMC_CONTROL0
),
temp
);
}
return
RT_EOK
;
}
static
uint32_t
sd_get_clock_divider
(
rt_uint32_t
sdHostVer
,
rt_uint32_t
base_clock
,
rt_uint32_t
target_rate
)
{
rt_uint32_t
targetted_divisor
=
0
;
rt_uint32_t
freq_select
=
0
;
rt_uint32_t
upper_bits
=
0
;
rt_uint32_t
ret
=
0
;
if
(
target_rate
>
base_clock
)
targetted_divisor
=
1
;
else
{
targetted_divisor
=
base_clock
/
target_rate
;
rt_uint32_t
mod
=
base_clock
%
target_rate
;
if
(
mod
)
targetted_divisor
--
;
}
// Decide on the clock mode to use
// Currently only 10-bit divided clock mode is supported
// HCI version 3 or greater supports 10-bit divided clock mode
// This requires a power-of-two divider
// Find the first bit set
int
divisor
=
-
1
;
for
(
int
first_bit
=
31
;
first_bit
>=
0
;
first_bit
--
)
{
rt_uint32_t
bit_test
=
(
1
<<
first_bit
);
if
(
targetted_divisor
&
bit_test
)
{
divisor
=
first_bit
;
targetted_divisor
&=
~
bit_test
;
if
(
targetted_divisor
)
{
// The divisor is not a power-of-two, increase it
divisor
++
;
}
break
;
}
}
if
(
divisor
==
-
1
)
divisor
=
31
;
if
(
divisor
>=
32
)
divisor
=
31
;
if
(
divisor
!=
0
)
divisor
=
(
1
<<
(
divisor
-
1
));
if
(
divisor
>=
0x400
)
divisor
=
0x3ff
;
freq_select
=
divisor
&
0xff
;
upper_bits
=
(
divisor
>>
8
)
&
0x3
;
ret
=
(
freq_select
<<
8
)
|
(
upper_bits
<<
6
)
|
(
0
<<
5
);
return
ret
;
}
static
rt_err_t
sdhci_setclock
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
clock
)
{
rt_uint32_t
temp
=
0
;
rt_uint32_t
sdHostVer
=
0
;
int
count
=
100000
;
struct
sdhci_pdata_t
*
pdat
=
(
struct
sdhci_pdata_t
*
)(
sdhci
->
priv
);
while
((
read32
(
pdat
->
virt
+
EMMC_STATUS
)
&
(
SR_CMD_INHIBIT
|
SR_DAT_INHIBIT
))
&&
(
--
count
))
DELAY_MICROS
(
1
);
if
(
count
<=
0
)
{
rt_kprintf
(
"EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.
\n
"
,
read32
(
pdat
->
virt
+
EMMC_STATUS
));
return
RT_ERROR
;
}
// Switch clock off.
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
temp
&=
~
C1_CLK_EN
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
DELAY_MICROS
(
10
);
// Request the new clock setting and enable the clock
temp
=
read32
(
pdat
->
virt
+
EMMC_SLOTISR_VER
);
sdHostVer
=
(
temp
&
HOST_SPEC_NUM
)
>>
HOST_SPEC_NUM_SHIFT
;
int
cdiv
=
sd_get_clock_divider
(
sdHostVer
,
mmc_base_clock
,
clock
);
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
temp
|=
1
;
temp
|=
cdiv
;
temp
|=
(
7
<<
16
);
temp
=
(
temp
&
0xffff003f
)
|
cdiv
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
DELAY_MICROS
(
10
);
// Enable the clock.
temp
=
read32
(
pdat
->
virt
+
EMMC_CONTROL1
);
temp
|=
C1_CLK_EN
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
DELAY_MICROS
(
10
);
// Wait for clock to be stable.
count
=
10000
;
while
(
!
(
read32
(
pdat
->
virt
+
EMMC_CONTROL1
)
&
C1_CLK_STABLE
)
&&
count
--
)
DELAY_MICROS
(
10
);
if
(
count
<=
0
)
{
rt_kprintf
(
"EMMC: ERROR: failed to get stable clock %d.
\n
"
,
clock
);
return
RT_ERROR
;
}
mmcsd_dbg
(
"set stable clock %d.
\n
"
,
clock
);
return
RT_EOK
;
}
static
void
mmc_set_iocfg
(
struct
rt_mmcsd_host
*
host
,
struct
rt_mmcsd_io_cfg
*
io_cfg
)
{
struct
sdhci_t
*
sdhci
=
(
struct
sdhci_t
*
)
host
->
private_data
;
sdhci_setclock
(
sdhci
,
io_cfg
->
clock
);
sdhci_setwidth
(
sdhci
,
io_cfg
->
bus_width
);
}
static
const
struct
rt_mmcsd_host_ops
ops
=
{
mmc_request_send
,
mmc_set_iocfg
,
RT_NULL
,
RT_NULL
,
};
static
rt_err_t
reset_emmc
(
struct
sdhci_pdata_t
*
pdat
)
{
rt_uint32_t
control1
;
//Reset the controller
control1
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
control1
|=
(
1
<<
24
);
// Disable clock
control1
&=
~
(
1
<<
2
);
control1
&=
~
(
1
<<
0
);
//temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
control1
);
int
cnt
=
10000
;
do
{
DELAY_MICROS
(
10
);
cnt
=
cnt
-
1
;
if
(
cnt
==
0
)
{
break
;
}
}
while
((
read32
(
pdat
->
virt
+
EMMC_CONTROL1
)
&
(
0x7
<<
24
))
!=
0
);
// Enable SD Bus Power VDD1 at 3.3V
rt_uint32_t
control0
=
read32
(
pdat
->
virt
+
EMMC_CONTROL0
);
control0
|=
0x0F
<<
8
;
write32
(
pdat
->
virt
+
EMMC_CONTROL0
,
control0
);
rt_thread_delay
(
100
);
//usleep(2000);
// Check for a valid card
mmcsd_dbg
(
"EMMC: checking for an inserted card
\n
"
);
cnt
=
10000
;
do
{
DELAY_MICROS
(
10
);
cnt
=
cnt
-
1
;
if
(
cnt
==
0
)
{
break
;
}
}
while
((
read32
(
pdat
->
virt
+
EMMC_STATUS
)
&
(
0x1
<<
16
))
==
0
);
rt_uint32_t
status_reg
=
read32
(
pdat
->
virt
+
EMMC_STATUS
);
if
((
status_reg
&
(
1
<<
16
))
==
0
)
{
rt_kprintf
(
"EMMC: no card inserted
\n
"
);
return
-
1
;
}
else
{
mmcsd_dbg
(
"EMMC: status: %08x
\n
"
,
status_reg
);
}
// Clear control2
write32
(
pdat
->
virt
+
EMMC_CONTROL2
,
0
);
// Get the base clock rate
mmc_base_clock
=
bcm271x_mbox_clock_get_rate
(
12
);
if
(
mmc_base_clock
==
0
)
{
rt_kprintf
(
"EMMC: assuming clock rate to be 100MHz
\n
"
);
mmc_base_clock
=
100000000
;
}
mmcsd_dbg
(
"EMMC: setting clock rate is %d
\n
"
,
mmc_base_clock
);
return
RT_EOK
;
}
#ifdef RT_MMCSD_DBG
void
dump_registers
(
struct
sdhci_pdata_t
*
pdat
)
{
rt_kprintf
(
"EMMC registers:"
);
int
i
=
EMMC_ARG2
;
for
(;
i
<=
EMMC_CONTROL2
;
i
+=
4
)
rt_kprintf
(
"
\t
%x:%x
\n
"
,
i
,
read32
(
pdat
->
virt
+
i
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x50
,
read32
(
pdat
->
virt
+
0x50
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x70
,
read32
(
pdat
->
virt
+
0x70
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x74
,
read32
(
pdat
->
virt
+
0x74
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x80
,
read32
(
pdat
->
virt
+
0x80
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x84
,
read32
(
pdat
->
virt
+
0x84
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x88
,
read32
(
pdat
->
virt
+
0x88
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x8c
,
read32
(
pdat
->
virt
+
0x8c
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0x90
,
read32
(
pdat
->
virt
+
0x90
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0xf0
,
read32
(
pdat
->
virt
+
0xf0
));
rt_kprintf
(
"
\t
%x:%x
\n
"
,
0xfc
,
read32
(
pdat
->
virt
+
0xfc
));
}
#endif
int
raspi_sdmmc_init
(
void
)
{
rt_uint32_t
virt
;
struct
rt_mmcsd_host
*
host
=
RT_NULL
;
struct
sdhci_pdata_t
*
pdat
=
RT_NULL
;
struct
sdhci_t
*
sdhci
=
RT_NULL
;
#ifdef BSP_USING_SDIO0
host
=
mmcsd_alloc_host
();
if
(
!
host
)
{
rt_kprintf
(
"alloc host failed"
);
goto
err
;
}
sdhci
=
rt_malloc
(
sizeof
(
struct
sdhci_t
));
if
(
!
sdhci
)
{
rt_kprintf
(
"alloc sdhci failed"
);
goto
err
;
}
rt_memset
(
sdhci
,
0
,
sizeof
(
struct
sdhci_t
));
virt
=
MMC2_BASE_ADDR
;
pdat
=
(
struct
sdhci_pdata_t
*
)
rt_malloc
(
sizeof
(
struct
sdhci_pdata_t
));
RT_ASSERT
(
pdat
!=
RT_NULL
);
pdat
->
virt
=
(
rt_uint32_t
)
virt
;
reset_emmc
(
pdat
);
sdhci
->
name
=
"sd0"
;
sdhci
->
voltages
=
VDD_33_34
;
sdhci
->
width
=
MMCSD_BUSWIDTH_4
;
sdhci
->
clock
=
250
*
1000
*
1000
;
sdhci
->
removeable
=
RT_TRUE
;
sdhci
->
detect
=
sdhci_detect
;
sdhci
->
setwidth
=
sdhci_setwidth
;
sdhci
->
setclock
=
sdhci_setclock
;
sdhci
->
transfer
=
sdhci_transfer
;
sdhci
->
priv
=
pdat
;
host
->
ops
=
&
ops
;
host
->
freq_min
=
400000
;
host
->
freq_max
=
50000000
;
host
->
valid_ocr
=
VDD_32_33
|
VDD_33_34
;
host
->
flags
=
MMCSD_MUTBLKWRITE
|
MMCSD_SUP_HIGHSPEED
|
MMCSD_SUP_SDIO_IRQ
|
MMCSD_BUSWIDTH_4
;
host
->
max_seg_size
=
2048
;
host
->
max_dma_segs
=
10
;
host
->
max_blk_size
=
512
;
host
->
max_blk_count
=
4096
;
host
->
private_data
=
sdhci
;
write32
((
pdat
->
virt
+
EMMC_IRPT_EN
),
0xffffffff
);
write32
((
pdat
->
virt
+
EMMC_IRPT_MASK
),
0xffffffff
);
#ifdef RT_MMCSD_DBG
dump_registers
(
pdat
);
#endif
mmcsd_change
(
host
);
#endif
return
RT_EOK
;
err:
if
(
host
)
rt_free
(
host
);
if
(
sdhci
)
rt_free
(
sdhci
);
return
-
RT_EIO
;
}
INIT_DEVICE_EXPORT
(
raspi_sdmmc_init
);
bsp/raspberry-pi/raspi4-32/driver/drv_sdio.h
0 → 100644
浏览文件 @
74812c0f
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-27 bigmagic first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#include "board.h"
#include "raspi4.h"
/* Struct for Intrrrupt Information */
#define SDXC_CmdDone BIT(0)
#define SDXC_DataDone BIT(1)
#define SDXC_BlockGap BIT(2)
#define SDXC_WriteRdy BIT(4)
#define SDXC_ReadRdy BIT(5)
#define SDXC_Card BIT(8)
#define SDXC_Retune BIT(12)
#define SDXC_BootAck BIT(13)
#define SDXC_EndBoot BIT(14)
#define SDXC_Err BIT(15)
#define SDXC_CTOErr BIT(16)
#define SDXC_CCRCErr BIT(17)
#define SDXC_CENDErr BIT(18)
#define SDXC_CBADErr BIT(19)
#define SDXC_DTOErr BIT(20)
#define SDXC_DCRCErr BIT(21)
#define SDXC_DENDErr BIT(22)
#define SDXC_ACMDErr BIT(24)
#define SDXC_BLKCNT_EN BIT(1)
#define SDXC_AUTO_CMD12_EN BIT(2)
#define SDXC_AUTO_CMD23_EN BIT(3)
#define SDXC_DAT_DIR BIT(4) //from card to host
#define SDXC_MULTI_BLOCK BIT(5)
#define SDXC_CMD_RSPNS_136 BIT(16)
#define SDXC_CMD_RSPNS_48 BIT(17)
#define SDXC_CMD_RSPNS_48busy BIT(16)|BIT(17)
#define SDXC_CHECK_CRC_CMD BIT(19)
#define SDXC_CMD_IXCHK_EN BIT(20)
#define SDXC_CMD_ISDATA BIT(21)
#define SDXC_CMD_SUSPEND BIT(22)
#define SDXC_CMD_RESUME BIT(23)
#define SDXC_CMD_ABORT BIT(23)|BIT(22)
#define SDXC_CMD_INHIBIT BIT(0)
#define SDXC_DAT_INHIBIT BIT(1)
#define SDXC_DAT_ACTIVE BIT(2)
#define SDXC_WRITE_TRANSFER BIT(8)
#define SDXC_READ_TRANSFER BIT(9)
struct
sdhci_cmd_t
{
rt_uint32_t
cmdidx
;
rt_uint32_t
cmdarg
;
rt_uint32_t
resptype
;
rt_uint32_t
datarw
;
#define DATA_READ 1
#define DATA_WRITE 2
rt_uint32_t
response
[
4
];
};
struct
sdhci_data_t
{
rt_uint8_t
*
buf
;
rt_uint32_t
flag
;
rt_uint32_t
blksz
;
rt_uint32_t
blkcnt
;
};
struct
sdhci_t
{
char
*
name
;
rt_uint32_t
voltages
;
rt_uint32_t
width
;
rt_uint32_t
clock
;
rt_err_t
removeable
;
void
*
sdcard
;
rt_err_t
(
*
detect
)(
struct
sdhci_t
*
sdhci
);
rt_err_t
(
*
setwidth
)(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
width
);
rt_err_t
(
*
setclock
)(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
clock
);
rt_err_t
(
*
transfer
)(
struct
sdhci_t
*
sdhci
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
);
void
*
priv
;
};
struct
sdhci_pdata_t
{
rt_uint32_t
virt
;
};
// EMMC command flags
#define CMD_TYPE_NORMAL (0x00000000)
#define CMD_TYPE_SUSPEND (0x00400000)
#define CMD_TYPE_RESUME (0x00800000)
#define CMD_TYPE_ABORT (0x00c00000)
#define CMD_IS_DATA (0x00200000)
#define CMD_IXCHK_EN (0x00100000)
#define CMD_CRCCHK_EN (0x00080000)
#define CMD_RSPNS_NO (0x00000000)
#define CMD_RSPNS_136 (0x00010000)
#define CMD_RSPNS_48 (0x00020000)
#define CMD_RSPNS_48B (0x00030000)
#define TM_MULTI_BLOCK (0x00000020)
#define TM_DAT_DIR_HC (0x00000000)
#define TM_DAT_DIR_CH (0x00000010)
#define TM_AUTO_CMD23 (0x00000008)
#define TM_AUTO_CMD12 (0x00000004)
#define TM_BLKCNT_EN (0x00000002)
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
#define RCA_NO (1)
#define RCA_YES (2)
// INTERRUPT register settings
#define INT_AUTO_ERROR (0x01000000)
#define INT_DATA_END_ERR (0x00400000)
#define INT_DATA_CRC_ERR (0x00200000)
#define INT_DATA_TIMEOUT (0x00100000)
#define INT_INDEX_ERROR (0x00080000)
#define INT_END_ERROR (0x00040000)
#define INT_CRC_ERROR (0x00020000)
#define INT_CMD_TIMEOUT (0x00010000)
#define INT_ERR (0x00008000)
#define INT_ENDBOOT (0x00004000)
#define INT_BOOTACK (0x00002000)
#define INT_RETUNE (0x00001000)
#define INT_CARD (0x00000100)
#define INT_READ_RDY (0x00000020)
#define INT_WRITE_RDY (0x00000010)
#define INT_BLOCK_GAP (0x00000004)
#define INT_DATA_DONE (0x00000002)
#define INT_CMD_DONE (0x00000001)
#define INT_ERROR_MASK (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \
INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \
INT_ERR|INT_AUTO_ERROR)
#define INT_ALL_MASK (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK)
#define EMMC_ARG2 (0x00)
#define EMMC_BLKSIZECNT (0x04)
#define EMMC_ARG1 (0x08)
#define EMMC_CMDTM (0x0c)
#define EMMC_RESP0 (0x10)
#define EMMC_RESP1 (0x14)
#define EMMC_RESP2 (0x18)
#define EMMC_RESP3 (0x1c)
#define EMMC_DATA (0x20)
#define EMMC_STATUS (0x24)
#define EMMC_CONTROL0 (0x28)
#define EMMC_CONTROL1 (0x2c)
#define EMMC_INTERRUPT (0x30)
#define EMMC_IRPT_MASK (0x34)
#define EMMC_IRPT_EN (0x38)
#define EMMC_CONTROL2 (0x3c)
#define EMMC_CAPABILITIES_0 (0x40)
#define EMMC_CAPABILITIES_1 (0x44)
#define EMMC_BOOT_TIMEOUT (0x70)
#define EMMC_EXRDFIFO_EN (0x84)
#define EMMC_SPI_INT_SPT (0xf0)
#define EMMC_SLOTISR_VER (0xfc)
// CONTROL register settings
#define C0_SPI_MODE_EN (0x00100000)
#define C0_HCTL_HS_EN (0x00000004)
#define C0_HCTL_DWITDH (0x00000002)
#define C1_SRST_DATA (0x04000000)
#define C1_SRST_CMD (0x02000000)
#define C1_SRST_HC (0x01000000)
#define C1_TOUNIT_DIS (0x000f0000)
#define C1_TOUNIT_MAX (0x000e0000)
#define C1_CLK_GENSEL (0x00000020)
#define C1_CLK_EN (0x00000004)
#define C1_CLK_STABLE (0x00000002)
#define C1_CLK_INTLEN (0x00000001)
#define FREQ_SETUP (400000) // 400 Khz
#define FREQ_NORMAL (25000000) // 25 Mhz
// SLOTISR_VER values
#define HOST_SPEC_NUM 0x00ff0000
#define HOST_SPEC_NUM_SHIFT 16
#define HOST_SPEC_V3 2
#define HOST_SPEC_V2 1
#define HOST_SPEC_V1 0
// STATUS register settings
#define SR_DAT_LEVEL1 (0x1e000000)
#define SR_CMD_LEVEL (0x01000000)
#define SR_DAT_LEVEL0 (0x00f00000)
#define SR_DAT3 (0x00800000)
#define SR_DAT2 (0x00400000)
#define SR_DAT1 (0x00200000)
#define SR_DAT0 (0x00100000)
#define SR_WRITE_PROT (0x00080000) // From SDHC spec v2, BCM says reserved
#define SR_READ_AVAILABLE (0x00000800) // ???? undocumented
#define SR_WRITE_AVAILABLE (0x00000400) // ???? undocumented
#define SR_READ_TRANSFER (0x00000200)
#define SR_WRITE_TRANSFER (0x00000100)
#define SR_DAT_ACTIVE (0x00000004)
#define SR_DAT_INHIBIT (0x00000002)
#define SR_CMD_INHIBIT (0x00000001)
#define CONFIG_MMC_USE_DMA
#define DMA_ALIGN (32U)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_RESERVED(a) (0xffffffff)
#define SD_CMD_INDEX(a) ((a) << 24)
#define SD_CMD_TYPE_NORMAL (0x0)
#define SD_CMD_TYPE_SUSPEND (1 << 22)
#define SD_CMD_TYPE_RESUME (2 << 22)
#define SD_CMD_TYPE_ABORT (3 << 22)
#define SD_CMD_TYPE_MASK (3 << 22)
#define SD_CMD_ISDATA (1 << 21)
#define SD_CMD_IXCHK_EN (1 << 20)
#define SD_CMD_CRCCHK_EN (1 << 19)
#define SD_CMD_RSPNS_TYPE_NONE (0) // For no response
#define SD_CMD_RSPNS_TYPE_136 (1 << 16) // For response R2 (with CRC), R3,4 (no CRC)
#define SD_CMD_RSPNS_TYPE_48 (2 << 16) // For responses R1, R5, R6, R7 (with CRC)
#define SD_CMD_RSPNS_TYPE_48B (3 << 16) // For responses R1b, R5b (with CRC)
#define SD_CMD_RSPNS_TYPE_MASK (3 << 16)
#define SD_CMD_MULTI_BLOCK (1 << 5)
#define SD_CMD_DAT_DIR_HC (0)
#define SD_CMD_DAT_DIR_CH (1 << 4)
#define SD_CMD_AUTO_CMD_EN_NONE (0)
#define SD_CMD_AUTO_CMD_EN_CMD12 (1 << 2)
#define SD_CMD_AUTO_CMD_EN_CMD23 (2 << 2)
#define SD_CMD_BLKCNT_EN (1 << 1)
#define SD_CMD_DMA (1)
#define SD_RESP_NONE SD_CMD_RSPNS_TYPE_NONE
#define SD_RESP_R1 (SD_CMD_RSPNS_TYPE_48) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136) // | SD_CMD_CRCCHK_EN)
#define SD_RESP_R3 SD_CMD_RSPNS_TYPE_48
#define SD_RESP_R4 SD_CMD_RSPNS_TYPE_136
#define SD_RESP_R5 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
#define SD_RESP_R5b (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
#define SD_RESP_R6 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
#define SD_RESP_R7 (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
#define SD_DATA_READ (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
#define SD_DATA_WRITE (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
#endif
bsp/raspberry-pi/raspi4-32/driver/raspi4.h
浏览文件 @
74812c0f
...
@@ -131,6 +131,27 @@ typedef enum {
...
@@ -131,6 +131,27 @@ typedef enum {
#define PM_RSTC_WRCFG_CLR (0xffffffcf)
#define PM_RSTC_WRCFG_CLR (0xffffffcf)
#define PM_RSTC_RESET (0x00000102)
#define PM_RSTC_RESET (0x00000102)
//timer
#define ST_BASE_OFFSET (0x003000)
#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET)
#define STIMER_CS __REG32(STIMER_BASE + 0x0000)
#define STIMER_CLO __REG32(STIMER_BASE + 0x0004)
#define STIMER_CHI __REG32(STIMER_BASE + 0x0008)
#define STIMER_C0 __REG32(STIMER_BASE + 0x000C)
#define STIMER_C1 __REG32(STIMER_BASE + 0x0010)
#define STIMER_C2 __REG32(STIMER_BASE + 0x0014)
#define STIMER_C3 __REG32(STIMER_BASE + 0x0018)
#define DELAY_MICROS(micros) \
do{ \
rt_uint32_t compare = STIMER_CLO + micros * 25; \
while (STIMER_CLO < compare); \
} while (0) \
//External Mass Media Controller (SD Card)
#define MMC0_BASE_ADDR (PER_BASE+0x300000)
#define MMC2_BASE_ADDR (PER_BASE+0x340000)
/* the basic constants and interfaces needed by gic */
/* the basic constants and interfaces needed by gic */
rt_inline
rt_uint32_t
platform_get_gic_dist_base
(
void
)
rt_inline
rt_uint32_t
platform_get_gic_dist_base
(
void
)
{
{
...
...
bsp/raspberry-pi/raspi4-32/rtconfig.h
浏览文件 @
74812c0f
...
@@ -76,6 +76,18 @@
...
@@ -76,6 +76,18 @@
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 16
#define DFS_FD_MAX 16
#define RT_USING_DFS_ELMFAT
/* elm-chan's FatFs, Generic FAT Filesystem Module */
#define RT_DFS_ELM_CODE_PAGE 437
#define RT_DFS_ELM_WORD_ACCESS
#define RT_DFS_ELM_USE_LFN_3
#define RT_DFS_ELM_USE_LFN 3
#define RT_DFS_ELM_MAX_LFN 255
#define RT_DFS_ELM_DRIVES 2
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
#define RT_DFS_ELM_REENTRANT
#define RT_USING_DFS_DEVFS
#define RT_USING_DFS_DEVFS
/* Device Drivers */
/* Device Drivers */
...
@@ -86,6 +98,12 @@
...
@@ -86,6 +98,12 @@
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
#define RT_USING_PIN
#define RT_USING_SDIO
#define RT_SDIO_STACK_SIZE 512
#define RT_SDIO_THREAD_PRIORITY 15
#define RT_MMCSD_STACK_SIZE 1024
#define RT_MMCSD_THREAD_PREORITY 22
#define RT_MMCSD_MAX_PARTITION 16
#define RT_USING_SPI
#define RT_USING_SPI
#define RT_USING_WDT
#define RT_USING_WDT
...
@@ -180,6 +198,8 @@
...
@@ -180,6 +198,8 @@
#define BSP_USING_SPI0_DEVICE0
#define BSP_USING_SPI0_DEVICE0
#define BSP_USING_CORETIMER
#define BSP_USING_CORETIMER
#define BSP_USING_WDT
#define BSP_USING_WDT
#define BSP_USING_SDIO
#define BSP_USING_SDIO0
/* Board Peripheral Drivers */
/* Board Peripheral Drivers */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录