Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
e09c99fc
R
rt-thread
项目概览
BaiXuePrincess
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
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,发现更多精彩内容 >>
提交
e09c99fc
编写于
2月 28, 2020
作者:
B
bigmagic
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix raspi3-64 sdio driver
上级
7b71c0e4
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
459 addition
and
429 deletion
+459
-429
bsp/raspberry-pi/raspi3-64/.config
bsp/raspberry-pi/raspi3-64/.config
+28
-5
bsp/raspberry-pi/raspi3-64/applications/mnt.c
bsp/raspberry-pi/raspi3-64/applications/mnt.c
+12
-0
bsp/raspberry-pi/raspi3-64/driver/board.c
bsp/raspberry-pi/raspi3-64/driver/board.c
+3
-2
bsp/raspberry-pi/raspi3-64/driver/board.h
bsp/raspberry-pi/raspi3-64/driver/board.h
+1
-1
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c
+332
-276
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h
+46
-138
bsp/raspberry-pi/raspi3-64/driver/raspi.h
bsp/raspberry-pi/raspi3-64/driver/raspi.h
+6
-0
bsp/raspberry-pi/raspi3-64/qemu-64.bat
bsp/raspberry-pi/raspi3-64/qemu-64.bat
+4
-1
bsp/raspberry-pi/raspi3-64/rtconfig.h
bsp/raspberry-pi/raspi3-64/rtconfig.h
+23
-2
components/drivers/sdio/mmcsd_core.c
components/drivers/sdio/mmcsd_core.c
+4
-4
未找到文件。
bsp/raspberry-pi/raspi3-64/.config
浏览文件 @
e09c99fc
...
...
@@ -65,7 +65,7 @@ CONFIG_RT_USING_DEVICE=y
CONFIG_RT_USING_DEVICE_OPS
=
y
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_CONSOLE
=
y
CONFIG_RT_CONSOLEBUF_SIZE
=
128
CONFIG_RT_CONSOLEBUF_SIZE
=
512
CONFIG_RT_CONSOLE_DEVICE_NAME
=
"uart1"
CONFIG_RT_VER_NUM
=
0
x40003
CONFIG_ARCH_CPU_64BIT
=
y
...
...
@@ -77,7 +77,7 @@ CONFIG_ARCH_CPU_64BIT=y
#
CONFIG_RT_USING_COMPONENTS_INIT
=
y
CONFIG_RT_USING_USER_MAIN
=
y
CONFIG_RT_MAIN_THREAD_STACK_SIZE
=
2048
CONFIG_RT_MAIN_THREAD_STACK_SIZE
=
4096
CONFIG_RT_MAIN_THREAD_PRIORITY
=
10
#
...
...
@@ -113,7 +113,23 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX
=
2
CONFIG_DFS_FD_MAX
=
16
# 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_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
...
...
@@ -140,7 +156,13 @@ CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM 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
=
2048
CONFIG_RT_SDIO_THREAD_PRIORITY
=
15
CONFIG_RT_MMCSD_STACK_SIZE
=
4096
CONFIG_RT_MMCSD_THREAD_PREORITY
=
22
CONFIG_RT_MMCSD_MAX_PARTITION
=
16
CONFIG_RT_SDIO_DEBUG
=
y
# CONFIG_RT_USING_SPI is not set
# CONFIG_RT_USING_WDT is not set
# CONFIG_RT_USING_AUDIO is not set
...
...
@@ -448,7 +470,8 @@ CONFIG_BSP_USING_CORETIMER=y
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_WDT 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
...
...
bsp/raspberry-pi/raspi3-64/applications/mnt.c
浏览文件 @
e09c99fc
...
...
@@ -10,7 +10,19 @@
#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/raspi3-64/driver/board.c
浏览文件 @
e09c99fc
...
...
@@ -93,10 +93,11 @@ void idle_wfi(void)
void
rt_hw_board_init
(
void
)
{
mmu_init
();
armv8_map
(
0
,
0
,
0x
8
00000
,
MEM_ATTR_MEMORY
);
armv8_map
(
0x3f00
B000
,
0x3f00B000
,
0x1
000
,
MEM_ATTR_IO
);
//timer
armv8_map
(
0
,
0
,
0x
64
00000
,
MEM_ATTR_MEMORY
);
armv8_map
(
0x3f00
0000
,
0x3f000000
,
0x200
000
,
MEM_ATTR_IO
);
//timer
armv8_map
(
0x3f200000
,
0x3f200000
,
0x16000
,
MEM_ATTR_IO
);
//uart
armv8_map
(
0x40000000
,
0x40000000
,
0x1000
,
MEM_ATTR_IO
);
//core timer
armv8_map
(
0x3F300000
,
0x3F300000
,
0x1000
,
MEM_ATTR_IO
);
//sdio
mmu_enable
();
/* initialize hardware interrupt */
...
...
bsp/raspberry-pi/raspi3-64/driver/board.h
浏览文件 @
e09c99fc
...
...
@@ -21,7 +21,7 @@ extern unsigned char __bss_start;
extern
unsigned
char
__bss_end
;
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN + 4 * 1024 * 1024)
#define RT_HW_HEAP_END (void*)(RT_HW_HEAP_BEGIN +
6
4 * 1024 * 1024)
void
rt_hw_board_init
(
void
);
...
...
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.c
浏览文件 @
e09c99fc
...
...
@@ -9,264 +9,306 @@
* 2019-07-29 zdzn first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include <string.h>
#include "drv_sdio.h"
#include "interrupt.h"
#include "drv_gpio.h"
#include "bcm283x.h"
#include <drivers/mmcsd_core.h>
#include "bcm283x.h"
#include <rtdbg.h>
#ifdef RT_USING_SDIO
#define CONFIG_MMC_USE_DMA
#define DMA_ALIGN (32U)
typedef
struct
EMMCCommand
{
const
char
*
name
;
unsigned
int
code
;
unsigned
char
resp
;
unsigned
char
rca
;
int
delay
;
}
EMMCCommand
;
static
EMMCCommand
sdCommandTable
[]
=
{
{
"GO_IDLE_STATE"
,
0x00000000
|
CMD_RSPNS_NO
,
RESP_NO
,
RCA_NO
,
0
},
{
"ALL_SEND_CID"
,
0x02000000
|
CMD_RSPNS_136
,
RESP_R2I
,
RCA_NO
,
0
},
{
"SEND_REL_ADDR"
,
0x03000000
|
CMD_RSPNS_48
,
RESP_R6
,
RCA_NO
,
0
},
{
"SET_DSR"
,
0x04000000
|
CMD_RSPNS_NO
,
RESP_NO
,
RCA_NO
,
0
},
{
"SWITCH_FUNC"
,
0x06000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"CARD_SELECT"
,
0x07000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_YES
,
0
},
{
"SEND_IF_COND"
,
0x08000000
|
CMD_RSPNS_48
,
RESP_R7
,
RCA_NO
,
100
},
{
"SEND_CSD"
,
0x09000000
|
CMD_RSPNS_136
,
RESP_R2S
,
RCA_YES
,
0
},
{
"SEND_CID"
,
0x0A000000
|
CMD_RSPNS_136
,
RESP_R2I
,
RCA_YES
,
0
},
{
"VOLT_SWITCH"
,
0x0B000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"STOP_TRANS"
,
0x0C000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_NO
,
0
},
{
"SEND_STATUS"
,
0x0D000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_YES
,
0
},
{
"GO_INACTIVE"
,
0x0F000000
|
CMD_RSPNS_NO
,
RESP_NO
,
RCA_YES
,
0
},
{
"SET_BLOCKLEN"
,
0x10000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"READ_SINGLE"
,
0x11000000
|
CMD_RSPNS_48
|
CMD_IS_DATA
|
TM_DAT_DIR_CH
,
RESP_R1
,
RCA_NO
,
0
},
{
"READ_MULTI"
,
0x12000000
|
CMD_RSPNS_48
|
TM_MULTI_DATA
|
TM_DAT_DIR_CH
,
RESP_R1
,
RCA_NO
,
0
},
{
"SEND_TUNING"
,
0x13000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SPEED_CLASS"
,
0x14000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_NO
,
0
},
{
"SET_BLOCKCNT"
,
0x17000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"WRITE_SINGLE"
,
0x18000000
|
CMD_RSPNS_48
|
CMD_IS_DATA
|
TM_DAT_DIR_HC
,
RESP_R1
,
RCA_NO
,
0
},
{
"WRITE_MULTI"
,
0x19000000
|
CMD_RSPNS_48
|
TM_MULTI_DATA
|
TM_DAT_DIR_HC
,
RESP_R1
,
RCA_NO
,
0
},
{
"PROGRAM_CSD"
,
0x1B000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SET_WRITE_PR"
,
0x1C000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_NO
,
0
},
{
"CLR_WRITE_PR"
,
0x1D000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_NO
,
0
},
{
"SND_WRITE_PR"
,
0x1E000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"ERASE_WR_ST"
,
0x20000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"ERASE_WR_END"
,
0x21000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"ERASE"
,
0x26000000
|
CMD_RSPNS_48B
,
RESP_R1b
,
RCA_NO
,
0
},
{
"LOCK_UNLOCK"
,
0x2A000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"APP_CMD"
,
0x37000000
|
CMD_RSPNS_NO
,
RESP_NO
,
RCA_NO
,
100
},
{
"APP_CMD"
,
0x37000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_YES
,
0
},
{
"GEN_CMD"
,
0x38000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
// APP commands must be prefixed by an APP_CMD.
{
"SET_BUS_WIDTH"
,
0x06000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SD_STATUS"
,
0x0D000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_YES
,
0
},
// RCA???
{
"SEND_NUM_WRBL"
,
0x16000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SEND_NUM_ERS"
,
0x17000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SD_SENDOPCOND"
,
0x29000000
|
CMD_RSPNS_48
,
RESP_R3
,
RCA_NO
,
1000
},
{
"SET_CLR_DET"
,
0x2A000000
|
CMD_RSPNS_48
,
RESP_R1
,
RCA_NO
,
0
},
{
"SEND_SCR"
,
0x33000000
|
CMD_RSPNS_48
|
CMD_IS_DATA
|
TM_DAT_DIR_CH
,
RESP_R1
,
RCA_NO
,
0
},
#include "raspi.h"
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
rt_err_t
sdhci_setwidth
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
width
);
static
rt_err_t
sdhci_setclock
(
struct
sdhci_t
*
sdhci
,
rt_uint32_t
clock
);
static
rt_err_t
sdhci_transfer
(
struct
sdhci_t
*
sdhci
,
struct
sdhci_cmd_t
*
cmd
,
struct
sdhci_data_t
*
dat
);
static
inline
rt_uint32_t
read32
(
rt_uint32_t
addr
)
{
return
(
*
((
volatile
rt_uint32_t
*
)(
addr
))
);
return
(
*
((
volatile
unsigned
int
*
)((
rt_uint64_t
)
addr
)));
//return (*((volatile rt_uint64_t *)(((long))addr)));
}
static
inline
void
write32
(
rt_uint32_t
addr
,
rt_uint32_t
value
)
{
*
((
volatile
rt_uint32_t
*
)(
addr
))
=
value
;
(
*
((
volatile
unsigned
int
*
)((
rt_uint64_t
)
addr
)))
=
value
;
//*((volatile rt_uint64_t *)(((long))addr)) = value;
}
static
rt_err_t
raspi_transfer_command
(
struct
sdhci_pdata_t
*
pdat
,
struct
sdhci_cmd_t
*
cmd
)
rt_err_t
sd_int
(
struct
sdhci_pdata_t
*
pdat
,
unsigned
int
mask
)
{
rt_uint32_t
cmdidx
;
rt_uint32_t
status
;
rt_err_t
ret
=
RT_EOK
;
unsigned
int
r
;
unsigned
int
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
;
}
if
(
read32
(
pdat
->
virt
+
EMMC_STATUS
)
&
SR_CMD_INHIBIT
)
write32
(
pdat
->
virt
+
EMMC_CMDTM
,
0x0
);
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
;
}
EMMCCommand
*
cmdtab
=
&
sdCommandTable
[
cmd
->
cmdidx
];
return
RT_EOK
;
}
cmdidx
=
cmdtab
->
code
;
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
)
{
do
{
status
=
read32
(
pdat
->
virt
+
EMMC_STATUS
);
}
while
(
!
(
status
&
SR_CMD_INHIBIT
));
if
(
cmd
->
resptype
&
RESP_MASK
)
if
(
cmd
->
resptype
&
RESP_R2
)
{
cmd
->
response
[
0
]
=
read32
(
pdat
->
virt
+
EMMC_RESP0
);
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
[
1
]
=
read32
(
pdat
->
virt
+
EMMC_RESP1
);
cmd
->
response
[
2
]
=
read32
(
pdat
->
virt
+
EMMC_RESP2
);
cmd
->
response
[
3
]
=
read32
(
pdat
->
virt
+
EMMC_RESP3
);
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
)
{
rt_uint32_t
*
tmp
=
buf
;
rt_uint32_t
count
=
blkcount
*
blksize
;
rt_uint32_t
status
,
err
;
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN);
// while((!err) && (count >= sizeof(rt_uint32_t)))
// {
// if(status & PL180_STAT_RX_FIFO_AVL)
// {
// *(tmp) = read32(pdat->virt + PL180_FIFO);
// tmp++;
// count -= sizeof(rt_uint32_t);
// }
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN);
// }
//
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN);
// while(!err)
// {
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END | PL180_STAT_RX_OVERRUN);
// }
//
// if(status & PL180_STAT_DAT_TIME_OUT)
// return -RT_ERROR;
// else if (status & PL180_STAT_DAT_CRC_FAIL)
// return -RT_ERROR;
// else if (status & PL180_STAT_RX_OVERRUN)
// return -RT_ERROR;
// write32(pdat->virt + PL180_CLEAR, 0x1DC007FF);
//
// if(count)
// return -RT_ERROR;
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
)
{
rt_uint32_t
*
tmp
=
buf
;
rt_uint32_t
count
=
blkcount
*
blksize
;
rt_uint32_t
status
,
err
;
int
i
;
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT);
// while(!err && count)
// {
// if(status & PL180_STAT_TX_FIFO_HALF)
// {
// if(count >= 8 * sizeof(rt_uint32_t))
// {
// for(i = 0; i < 8; i++)
// write32(pdat->virt + PL180_FIFO, *(tmp + i));
// tmp += 8;
// count -= 8 * sizeof(rt_uint32_t);
// }
// else
// {
// while(count >= sizeof(rt_uint32_t))
// {
// write32(pdat->virt + PL180_FIFO, *tmp);
// tmp++;
// count -= sizeof(rt_uint32_t);
// }
// }
// }
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT);
// }
//
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END);
// while(!err)
// {
// status = read32(pdat->virt + PL180_STATUS);
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_DAT_BLK_END);
// }
//
// if(status & PL180_STAT_DAT_TIME_OUT)
// return -RT_ERROR;
// else if (status & PL180_STAT_DAT_CRC_FAIL)
// return -RT_ERROR;
// write32(pdat->virt + PL180_CLEAR, 0x1DC007FF);
//
// if(count)
// return -RT_ERROR;
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_uint32_t
blksz_bits
=
dat
->
blksz
-
1
;
rt_err_t
ret
=
-
RT_ERROR
;
write32
(
pdat
->
virt
+
EMMC_BLKSIZECNT
,
dlen
);
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
(
dat
->
flag
&
DATA_DIR_READ
)
if
(
dlen
<
512
)
{
write32
(
pdat
->
virt
+
EMMC_BLKSIZECNT
,
dlen
|
1
<<
16
);
}
else
{
write32
(
pdat
->
virt
+
EMMC_STATUS
,
SR_READ_TRANSFER
);
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
<
0
)
return
ret
;
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
)
else
if
(
dat
->
flag
&
DATA_DIR_WRITE
)
{
cmd
->
datarw
=
DATA_WRITE
;
ret
=
raspi_transfer_command
(
pdat
,
cmd
);
if
(
ret
<
0
)
return
ret
;
write32
(
pdat
->
virt
+
EMMC_STATUS
,
SR_WRITE_TRANSFER
);
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
;
EMMCCommand
*
cmdtab
=
&
sdCommandTable
[
cmd
.
cmdidx
];
cmd
.
cmdarg
=
req
->
cmd
->
arg
;
cmd
.
resptype
=
cmdtab
->
resp
;
if
(
req
->
data
)
cmd
.
resptype
=
resp_type
(
req
->
cmd
);
if
(
req
->
data
)
{
dat
.
buf
=
(
rt_uint8_t
*
)
req
->
data
->
buf
;
dat
.
flag
=
req
->
data
->
flags
;
...
...
@@ -288,43 +330,14 @@ static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *re
if
(
req
->
stop
)
{
stop
.
cmdidx
=
req
->
stop
->
cmd_code
;
cmdtab
=
&
sdCommandTable
[
cmd
.
cmdidx
];
stop
.
cmdarg
=
req
->
stop
->
arg
;
cmd
.
resptype
=
cmdtab
->
resp
;
cmd
.
resptype
=
resp_type
(
req
->
stop
);
req
->
stop
->
err
=
sdhci_transfer
(
sdhci
,
&
stop
,
RT_NULL
);
}
mmcsd_req_complete
(
host
);
}
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
);
}
//#ifdef CONFIG_MMC_USE_DMA
//#ifdef BSP_USING_SDIO0
////ALIGN(32) static rt_uint8_t dma_buffer[64 * 1024];
//static rt_uint8_t dma_buffer[64 * 1024];
//#endif
//#endif
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
);
}
rt_int32_t
mmc_card_status
(
struct
rt_mmcsd_host
*
host
)
{
return
0
;
...
...
@@ -344,15 +357,17 @@ 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
rt_uint32_t
sdhci_getdivider
(
rt_uint32_t
sdHostVer
,
rt_uint32_t
freq
)
static
rt_uint32_t
sdhci_getdivider
(
rt_uint32_t
sdHostVer
,
rt_uint32_t
freq
)
{
rt_uint32_t
divisor
;
rt_uint32_t
closest
=
41666666
/
freq
;
...
...
@@ -366,7 +381,8 @@ static rt_uint32_t sdhci_getdivider( rt_uint32_t sdHostVer, rt_uint32_t freq )
else
divisor
=
(
1
<<
shiftcount
);
if
(
divisor
<=
2
)
{
if
(
divisor
<=
2
)
{
divisor
=
2
;
shiftcount
=
0
;
}
...
...
@@ -384,56 +400,55 @@ 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
;
struct
sdhci_pdata_t
*
pdat
=
(
struct
sdhci_pdata_t
*
)
(
sdhci
->
priv
)
;
temp
=
read32
(
pdat
->
virt
+
EMMC_STATUS
);
while
((
temp
&
(
SR_CMD_INHIBIT
|
SR_DAT_INHIBIT
))
&&
(
--
count
))
bcm283x_clo_delayMicros
(
1
);
if
(
count
<=
0
)
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
"
,
temp
);
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
;
temp
&
=
~
C1_CLK_EN
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
bcm283x_clo_delayMicros
(
10
);
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
=
sdhci_getdivider
(
sdHostVer
,
clock
);
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
temp
=
(
temp
&
0xffff003f
)
|
cdiv
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
bcm283x_clo_delayMicros
(
10
);
DELAY_MICROS
(
10
);
// Enable the clock.
temp
=
read32
(
pdat
->
virt
+
EMMC_CONTROL1
);
temp
|=
C1_CLK_EN
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
bcm283x_clo_delayMicros
(
10
);
DELAY_MICROS
(
10
);
// Wait for clock to be stable.
count
=
10000
;
temp
=
read32
(
pdat
->
virt
+
EMMC_CONTROL1
);
while
(
!
(
temp
&
C1_CLK_STABLE
)
&&
count
--
)
bcm283x_clo_delayMicros
(
10
);
if
(
count
<=
0
)
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
.
\n
"
);
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
,
...
...
@@ -444,27 +459,67 @@ static const struct rt_mmcsd_host_ops ops =
static
void
sdmmc_gpio_init
()
{
int
pin
;
// int pin;
// bcm283x_gpio_fsel(47,BCM283X_GPIO_FSEL_INPT);
// bcm283x_gpio_set_pud(47, BCM283X_GPIO_PUD_UP);
// bcm283x_peri_set_bits(BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN1, 1<<15, 1<<15);
// for (pin = 53; pin >= 48; pin--)
// {
// bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3);
// bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
// }
}
for
(
pin
=
BCM_GPIO_PIN_48
;
pin
<=
BCM_GPIO_PIN_53
;
pin
++
)
static
rt_err_t
reset_emmc
(
struct
sdhci_pdata_t
*
pdat
){
rt_uint32_t
temp
;
int
cnt
;
write32
((
pdat
->
virt
+
EMMC_CONTROL0
),
0
);
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
temp
|=
C1_SRST_HC
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
cnt
=
10000
;
do
{
bcm283x_gpio_set_pud
(
pin
,
BCM283X_GPIO_PUD_UP
);
bcm283x_gpio_fsel
(
pin
,
BCM283X_GPIO_FSEL_ALT3
);
DELAY_MICROS
(
10
);
}
while
((
read32
((
pdat
->
virt
+
EMMC_CONTROL1
))
&
C1_SRST_HC
)
&&
cnt
--
);
if
(
cnt
<=
0
)
{
rt_kprintf
(
"ERROR: failed to reset EMMC
\n
"
);
return
RT_ERROR
;
}
bcm283x_gpio_set_pud
(
pin
,
BCM283X_GPIO_PUD_UP
);
bcm283x_gpio_fsel
(
pin
,
BCM283X_GPIO_FSEL_INPT
);
temp
=
read32
((
pdat
->
virt
+
EMMC_CONTROL1
));
temp
|=
C1_CLK_INTLEN
|
C1_TOUNIT_MAX
;
write32
((
pdat
->
virt
+
EMMC_CONTROL1
),
temp
);
DELAY_MICROS
(
10
);
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
;
rt_uint32_t
id
;
struct
rt_mmcsd_host
*
host
=
RT_NULL
;
struct
sdhci_pdata_t
*
pdat
=
RT_NULL
;
struct
sdhci_t
*
sdhci
=
RT_NULL
;
rt_kprintf
(
"raspi_sdmmc_init start
\n
"
);
#ifdef BSP_USING_SDIO0
host
=
mmcsd_alloc_host
();
if
(
!
host
)
...
...
@@ -481,21 +536,19 @@ int raspi_sdmmc_init(void)
}
rt_memset
(
sdhci
,
0
,
sizeof
(
struct
sdhci_t
));
rt_kprintf
(
">> sdmmc_gpio_init
\n
"
);
sdmmc_gpio_init
();
rt_kprintf
(
"<< sdmmc_gpio_init
\n
"
);
virt
=
MMC0_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
=
2
6
*
1000
*
1000
;
sdhci
->
clock
=
2
00
*
1000
*
1000
;
sdhci
->
removeable
=
RT_TRUE
;
sdhci
->
detect
=
sdhci_detect
;
...
...
@@ -503,7 +556,6 @@ int raspi_sdmmc_init(void)
sdhci
->
setclock
=
sdhci_setclock
;
sdhci
->
transfer
=
sdhci_transfer
;
sdhci
->
priv
=
pdat
;
//write32(pdat->virt + PL180_POWER, 0xbf);
host
->
ops
=
&
ops
;
host
->
freq_min
=
400000
;
...
...
@@ -517,16 +569,20 @@ int raspi_sdmmc_init(void)
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
);
if
(
host
)
rt_free
(
host
);
if
(
sdhci
)
rt_free
(
sdhci
);
return
-
RT_EIO
;
#endif
}
INIT_APP_EXPORT
(
raspi_sdmmc_init
);
#endif
INIT_DEVICE_EXPORT
(
raspi_sdmmc_init
);
bsp/raspberry-pi/raspi3-64/driver/drv_sdio.h
浏览文件 @
e09c99fc
...
...
@@ -13,50 +13,12 @@
#define __DRV_SDIO_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#define MMC0_BASE_ADDR 0x20300000
struct
raspi_mmc
{
volatile
rt_uint32_t
arg2_reg
;
/* (0x000) */
volatile
rt_uint32_t
blksizecnt_reg
;
/* (0x004) */
volatile
rt_uint32_t
arg1_reg
;
/* (0x008) */
volatile
rt_uint32_t
cmdtm_reg
;
/* (0x00C) */
volatile
rt_uint32_t
resp0_reg
;
/* (0x010) */
volatile
rt_uint32_t
resp1_reg
;
/* (0x014) */
volatile
rt_uint32_t
resp2_reg
;
/* (0x018) */
volatile
rt_uint32_t
resp3_reg
;
/* (0x01C) */
volatile
rt_uint32_t
data_reg
;
/* (0x020) */
volatile
rt_uint32_t
status_reg
;
/* (0x024) */
volatile
rt_uint32_t
control0_reg
;
/* (0x028) */
volatile
rt_uint32_t
control1_reg
;
/* (0x02C) */
volatile
rt_uint32_t
interrupt_reg
;
/* (0x030) */
volatile
rt_uint32_t
irpt_mask_reg
;
/* (0x034) */
volatile
rt_uint32_t
irpt_en_reg
;
/* (0x038) */
volatile
rt_uint32_t
control2_reg
;
/* (0x03C) */
volatile
rt_uint32_t
reserved1
[
4
];
/* (0x040) */
volatile
rt_uint32_t
force_irpt_reg
;
/* (0x050) */
volatile
rt_uint32_t
reserved2
[
7
];
/* (0x054) */
volatile
rt_uint32_t
boot_timeout_reg
;
/* (0x070) */
volatile
rt_uint32_t
deg_sel_reg
;
/* (0x074) */
volatile
rt_uint32_t
reserved3
[
2
];
/* (0x078) */
volatile
rt_uint32_t
exrdfifo_cfg_reg
;
/* (0x080) */
volatile
rt_uint32_t
exrdfifo_cn_reg
;
/* (0x084) */
volatile
rt_uint32_t
tune_step_reg
;
/* (0x088) */
volatile
rt_uint32_t
tune_step_std_reg
;
/* (0x08C) */
volatile
rt_uint32_t
tune_step_ddr_reg
;
/* (0x090) */
volatile
rt_uint32_t
reserved4
[
23
];
/* (0x094) */
volatile
rt_uint32_t
spi_int_reg
;
/* (0x0f0) */
volatile
rt_uint32_t
reserved5
[
2
];
/* (0x0f4) */
volatile
rt_uint32_t
slotisr_ver_reg
;
/* (0x0fC) */
};
typedef
struct
raspi_mmc
*
raspi_mmc_t
;
#define MMC0 ((tina_mmc_t)MMC0_BASE_ADDR)
#include "board.h"
#define BIT(x) (1<<(x))
#define MMC0_BASE_ADDR 0x3F300000
/* Struct for Intrrrupt Information */
#define SDXC_CmdDone BIT(0)
...
...
@@ -78,25 +40,6 @@ typedef struct raspi_mmc *raspi_mmc_t;
#define SDXC_DENDErr BIT(22)
#define SDXC_ACMDErr BIT(24)
/*
SD CMD reg
REG[0-5] : Cmd ID
REG[6] : Has response
REG[7] : Long response
REG[8] : Check response CRC
REG[9] : Has data
REG[10] : Write
REG[11] : Steam mode
REG[12] : Auto stop
REG[13] : Wait previous over
REG[14] : About cmd
REG[15] : Send initialization
REG[21] : Update clock
REG[31] : Load cmd
*/
#define SDXC_BLKCNT_EN BIT(1)
#define SDXC_AUTO_CMD12_EN BIT(2)
#define SDXC_AUTO_CMD23_EN BIT(3)
...
...
@@ -112,82 +55,20 @@ REG[31] : Load cmd
#define SDXC_CMD_RESUME BIT(23)
#define SDXC_CMD_ABORT BIT(23)|BIT(22)
//#define SDXC_CHECK_CRC_CMD BIT(19)
//
//#define SDXC_RESPONSE_CMD BIT(6)
//#define SDXC_LONG_RESPONSE_CMD BIT(7)
//#define SDXC_CHECK_CRC_CMD BIT(8)
//#define SDXC_HAS_DATA_CMD BIT(9)
//#define SDXC_WRITE_CMD BIT(10)
//#define SDXC_STEAM_CMD BIT(11)
//#define SDXC_AUTO_STOP_CMD BIT(12)
//#define SDXC_WAIT_OVER_CMD BIT(13)
//#define SDXC_ABOUT_CMD BIT(14)
//#define SDXC_SEND_INIT_CMD BIT(15)
//#define SDXC_UPDATE_CLOCK_CMD BIT(21)
//#define SDXC_LOAD_CMD BIT(31)
/*
SD status reg
REG[0] : FIFO_RX_LEVEL
REG[1] : FIFO_TX_LEVEL
REG[2] : FIFO_EMPTY
REG[3] : FIFO_FULL
REG[4-7] : FSM_STA
REG[8] : CARD_PRESENT
REG[9] : CARD_BUSY
REG[10] : FSM_BUSY
REG[11-16]: RESP_IDX
REG[17-21]: FIFO_LEVEL
REG[31] : DMA_REQ
*/
#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)
//
//
//#define SDXC_FIFO_RX_LEVEL BIT(0)
//#define SDXC_FIFO_TX_LEVEL BIT(1)
//#define SDXC_FIFO_EMPTY BIT(2)
//#define SDXC_FIFO_FULL BIT(3)
//#define SDXC_CARD_PRESENT BIT(8)
//#define SDXC_CARD_BUSY BIT(9)
//#define SDXC_FSM_BUSY BIT(10)
//#define SDXC_DMA_REQ BIT(31)
struct
mmc_des_v4p1
{
rt_uint32_t
:
1
,
dic
:
1
,
/* disable interrupt on completion */
last_des
:
1
,
/* 1-this data buffer is the last buffer */
first_des
:
1
,
/* 1-data buffer is the first buffer,0-data buffer contained in the next descriptor is 1st buffer */
des_chain
:
1
,
/* 1-the 2nd address in the descriptor is the next descriptor address */
end_of_ring
:
1
,
/* 1-last descriptor flag when using dual data buffer in descriptor */
:
24
,
card_err_sum
:
1
,
/* transfer error flag */
own
:
1
;
/* des owner:1-idma owns it, 0-host owns it */
#define SDXC_DES_NUM_SHIFT 12
/* smhc2!! */
#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT)
rt_uint32_t
data_buf1_sz
:
16
,
data_buf2_sz
:
16
;
rt_uint32_t
buf_addr_ptr1
;
rt_uint32_t
buf_addr_ptr2
;
};
struct
sdhci_cmd_t
{
rt_uint32_t
cmdidx
;
rt_uint32_t
cmdarg
;
//const char* name;
// rt_uint32_t code;
rt_uint32_t
resptype
;
// rt_uint8_t rca;
// rt_uint32_t delay;
rt_uint32_t
datarw
;
#define DATA_READ 1
#define DATA_WRITE 2
rt_uint32_t
response
[
4
];
};
...
...
@@ -240,17 +121,6 @@ struct sdhci_pdata_t
#define TM_BLKCNT_EN 0x00000002
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
// Response types.
// Note that on the PI, the index and CRC are dropped, leaving 32 bits in RESP0.
#define RESP_NO 0 // No response
//#define RESP_R1 1 // 48 RESP0 contains card status
#define RESP_R1b 11 // 48 RESP0 contains card status, data line indicates busy
#define RESP_R2I 2 // 136 RESP0..3 contains 128 bit CID shifted down by 8 bits as no CRC
#define RESP_R2S 12 // 136 RESP0..3 contains 128 bit CSD shifted down by 8 bits as no CRC
//#define RESP_R3 3 // 48 RESP0 contains OCR register
//#define RESP_R6 6 // 48 RESP0 contains RCA and status bits 23,22,19,12:0
//#define RESP_R7 7 // 48 RESP0 contains voltage acceptance and check pattern
#define RCA_NO 1
#define RCA_YES 2
...
...
@@ -341,5 +211,43 @@ struct sdhci_pdata_t
#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/raspi3-64/driver/raspi.h
浏览文件 @
e09c99fc
...
...
@@ -67,4 +67,10 @@ enum rpi_pin_name
RPI_GPIO_PIN_NUM
,
};
#define DELAY_MICROS(micros) \
do{ \
rt_uint32_t compare = STIMER_CLO + micros * 25; \
while (STIMER_CLO < compare); \
} while (0) \
#endif
bsp/raspberry-pi/raspi3-64/qemu-64.bat
100644 → 100755
浏览文件 @
e09c99fc
qemu
-system-aarch
64
-M
raspi3
-kernel
kernel8
.img
-serial
null
-serial
stdio
\ No newline at end of file
if
[
!
-f
"sd.bin"
];
then
dd
if
=
/dev/zero
of
=
sd
.bin
bs
=
1024
count
=
65536
fi
qemu
-system-aarch
64
-M
raspi3
-kernel
kernel8
.img
-serial
null
-serial
stdio
-sd
sd
.bin
-nographic -monitor
pty
\ No newline at end of file
bsp/raspberry-pi/raspi3-64/rtconfig.h
浏览文件 @
e09c99fc
...
...
@@ -43,7 +43,7 @@
#define RT_USING_DEVICE
#define RT_USING_DEVICE_OPS
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE
128
#define RT_CONSOLEBUF_SIZE
512
#define RT_CONSOLE_DEVICE_NAME "uart1"
#define RT_VER_NUM 0x40003
#define ARCH_CPU_64BIT
...
...
@@ -52,7 +52,7 @@
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE
2048
#define RT_MAIN_THREAD_STACK_SIZE
4096
#define RT_MAIN_THREAD_PRIORITY 10
/* C++ features */
...
...
@@ -81,6 +81,18 @@
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#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
/* Device Drivers */
...
...
@@ -90,6 +102,13 @@
#define RT_USING_SERIAL
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_PIN
#define RT_USING_SDIO
#define RT_SDIO_STACK_SIZE 2048
#define RT_SDIO_THREAD_PRIORITY 15
#define RT_MMCSD_STACK_SIZE 4096
#define RT_MMCSD_THREAD_PREORITY 22
#define RT_MMCSD_MAX_PARTITION 16
#define RT_SDIO_DEBUG
/* Using USB */
...
...
@@ -174,6 +193,8 @@
#define RT_USING_UART1
#define BSP_USING_PIN
#define BSP_USING_CORETIMER
#define BSP_USING_SDIO
#define BSP_USING_SDIO0
/* Board Peripheral Drivers */
...
...
components/drivers/sdio/mmcsd_core.c
浏览文件 @
e09c99fc
...
...
@@ -610,7 +610,7 @@ RTM_EXPORT(mmcsd_wait_cd_changed);
void
mmcsd_change
(
struct
rt_mmcsd_host
*
host
)
{
rt_mb_send
(
&
mmcsd_detect_mb
,
(
rt_u
int32
_t
)
host
);
rt_mb_send
(
&
mmcsd_detect_mb
,
(
rt_u
base
_t
)
host
);
}
void
mmcsd_detect
(
void
*
param
)
...
...
@@ -649,7 +649,7 @@ void mmcsd_detect(void *param)
if
(
init_sd
(
host
,
ocr
))
mmcsd_power_off
(
host
);
mmcsd_host_unlock
(
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
int32
_t
)
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
base
_t
)
host
);
continue
;
}
...
...
@@ -662,7 +662,7 @@ void mmcsd_detect(void *param)
if
(
init_mmc
(
host
,
ocr
))
mmcsd_power_off
(
host
);
mmcsd_host_unlock
(
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
int32
_t
)
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
base
_t
)
host
);
continue
;
}
mmcsd_host_unlock
(
host
);
...
...
@@ -683,7 +683,7 @@ void mmcsd_detect(void *param)
host
->
card
=
RT_NULL
;
}
mmcsd_host_unlock
(
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
int32
_t
)
host
);
rt_mb_send
(
&
mmcsd_hotpluge_mb
,
(
rt_u
base
_t
)
host
);
}
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录