fix raspi3-64 sdio driver
This commit is contained in:
parent
7b71c0e4ad
commit
e09c99fcfb
|
@ -65,7 +65,7 @@ CONFIG_RT_USING_DEVICE=y
|
||||||
CONFIG_RT_USING_DEVICE_OPS=y
|
CONFIG_RT_USING_DEVICE_OPS=y
|
||||||
# CONFIG_RT_USING_INTERRUPT_INFO is not set
|
# CONFIG_RT_USING_INTERRUPT_INFO is not set
|
||||||
CONFIG_RT_USING_CONSOLE=y
|
CONFIG_RT_USING_CONSOLE=y
|
||||||
CONFIG_RT_CONSOLEBUF_SIZE=128
|
CONFIG_RT_CONSOLEBUF_SIZE=512
|
||||||
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
|
CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
|
||||||
CONFIG_RT_VER_NUM=0x40003
|
CONFIG_RT_VER_NUM=0x40003
|
||||||
CONFIG_ARCH_CPU_64BIT=y
|
CONFIG_ARCH_CPU_64BIT=y
|
||||||
|
@ -77,7 +77,7 @@ CONFIG_ARCH_CPU_64BIT=y
|
||||||
#
|
#
|
||||||
CONFIG_RT_USING_COMPONENTS_INIT=y
|
CONFIG_RT_USING_COMPONENTS_INIT=y
|
||||||
CONFIG_RT_USING_USER_MAIN=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
|
CONFIG_RT_MAIN_THREAD_PRIORITY=10
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -113,7 +113,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
|
||||||
# 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=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_SPI is not set
|
||||||
# CONFIG_RT_USING_WDT is not set
|
# CONFIG_RT_USING_WDT is not set
|
||||||
# CONFIG_RT_USING_AUDIO is not set
|
# CONFIG_RT_USING_AUDIO is not set
|
||||||
|
@ -448,7 +470,8 @@ CONFIG_BSP_USING_CORETIMER=y
|
||||||
# CONFIG_BSP_USING_SPI is not set
|
# CONFIG_BSP_USING_SPI is not set
|
||||||
# CONFIG_BSP_USING_WDT is not set
|
# CONFIG_BSP_USING_WDT is not set
|
||||||
# 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
|
||||||
|
|
|
@ -10,7 +10,19 @@
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
|
||||||
|
#ifdef BSP_USING_SDIO0
|
||||||
|
#include <dfs_fs.h>
|
||||||
|
|
||||||
int mnt_init(void)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
INIT_ENV_EXPORT(mnt_init);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -93,10 +93,11 @@ void idle_wfi(void)
|
||||||
void rt_hw_board_init(void)
|
void rt_hw_board_init(void)
|
||||||
{
|
{
|
||||||
mmu_init();
|
mmu_init();
|
||||||
armv8_map(0, 0, 0x800000, MEM_ATTR_MEMORY);
|
armv8_map(0, 0, 0x6400000, MEM_ATTR_MEMORY);
|
||||||
armv8_map(0x3f00B000, 0x3f00B000, 0x1000, MEM_ATTR_IO);//timer
|
armv8_map(0x3f000000, 0x3f000000, 0x200000, MEM_ATTR_IO);//timer
|
||||||
armv8_map(0x3f200000, 0x3f200000, 0x16000, MEM_ATTR_IO);//uart
|
armv8_map(0x3f200000, 0x3f200000, 0x16000, MEM_ATTR_IO);//uart
|
||||||
armv8_map(0x40000000, 0x40000000, 0x1000, MEM_ATTR_IO);//core timer
|
armv8_map(0x40000000, 0x40000000, 0x1000, MEM_ATTR_IO);//core timer
|
||||||
|
armv8_map(0x3F300000, 0x3F300000, 0x1000, MEM_ATTR_IO);//sdio
|
||||||
mmu_enable();
|
mmu_enable();
|
||||||
|
|
||||||
/* initialize hardware interrupt */
|
/* initialize hardware interrupt */
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern unsigned char __bss_start;
|
||||||
extern unsigned char __bss_end;
|
extern unsigned char __bss_end;
|
||||||
|
|
||||||
#define RT_HW_HEAP_BEGIN (void*)&__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 + 64 * 1024 * 1024)
|
||||||
|
|
||||||
void rt_hw_board_init(void);
|
void rt_hw_board_init(void);
|
||||||
|
|
||||||
|
|
|
@ -9,264 +9,306 @@
|
||||||
* 2019-07-29 zdzn first version
|
* 2019-07-29 zdzn first version
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
|
||||||
#include <rthw.h>
|
|
||||||
#include <rtdevice.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "drv_sdio.h"
|
#include "drv_sdio.h"
|
||||||
#include "interrupt.h"
|
#include "raspi.h"
|
||||||
#include "drv_gpio.h"
|
|
||||||
|
|
||||||
#include "bcm283x.h"
|
static rt_uint32_t sdCommandTable[] = {
|
||||||
#include <drivers/mmcsd_core.h>
|
SD_CMD_INDEX(0),
|
||||||
#include "bcm283x.h"
|
SD_CMD_RESERVED(1),
|
||||||
|
SD_CMD_INDEX(2) | SD_RESP_R2,
|
||||||
|
SD_CMD_INDEX(3) | SD_RESP_R1,
|
||||||
#include <rtdbg.h>
|
SD_CMD_INDEX(4),
|
||||||
|
SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
|
||||||
#ifdef RT_USING_SDIO
|
SD_CMD_INDEX(6) | SD_RESP_R1,
|
||||||
#define CONFIG_MMC_USE_DMA
|
SD_CMD_INDEX(7) | SD_RESP_R1b,
|
||||||
#define DMA_ALIGN (32U)
|
SD_CMD_INDEX(8) | SD_RESP_R1,
|
||||||
|
SD_CMD_INDEX(9) | SD_RESP_R2,
|
||||||
typedef struct EMMCCommand
|
SD_CMD_INDEX(10) | SD_RESP_R2,
|
||||||
{
|
SD_CMD_INDEX(11) | SD_RESP_R1,
|
||||||
const char* name;
|
SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT,
|
||||||
unsigned int code;
|
SD_CMD_INDEX(13) | SD_RESP_R1,
|
||||||
unsigned char resp;
|
SD_CMD_RESERVED(14),
|
||||||
unsigned char rca;
|
SD_CMD_INDEX(15),
|
||||||
int delay;
|
SD_CMD_INDEX(16) | SD_RESP_R1,
|
||||||
} EMMCCommand;
|
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,
|
||||||
static EMMCCommand sdCommandTable[] =
|
SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ,
|
||||||
{
|
SD_CMD_INDEX(20) | SD_RESP_R1b,
|
||||||
{"GO_IDLE_STATE", 0x00000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,0},
|
SD_CMD_RESERVED(21),
|
||||||
{"ALL_SEND_CID" , 0x02000000 | CMD_RSPNS_136 , RESP_R2I, RCA_NO ,0},
|
SD_CMD_RESERVED(22),
|
||||||
{"SEND_REL_ADDR", 0x03000000 | CMD_RSPNS_48 , RESP_R6 , RCA_NO ,0},
|
SD_CMD_INDEX(23) | SD_RESP_R1,
|
||||||
{"SET_DSR" , 0x04000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,0},
|
SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
|
||||||
{"SWITCH_FUNC" , 0x06000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
|
||||||
{"CARD_SELECT" , 0x07000000 | CMD_RSPNS_48B , RESP_R1b, RCA_YES ,0},
|
SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add
|
||||||
{"SEND_IF_COND" , 0x08000000 | CMD_RSPNS_48 , RESP_R7 , RCA_NO ,100},
|
SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
|
||||||
{"SEND_CSD" , 0x09000000 | CMD_RSPNS_136 , RESP_R2S, RCA_YES ,0},
|
SD_CMD_INDEX(28) | SD_RESP_R1b,
|
||||||
{"SEND_CID" , 0x0A000000 | CMD_RSPNS_136 , RESP_R2I, RCA_YES ,0},
|
SD_CMD_INDEX(29) | SD_RESP_R1b,
|
||||||
{"VOLT_SWITCH" , 0x0B000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ,
|
||||||
{"STOP_TRANS" , 0x0C000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0},
|
SD_CMD_RESERVED(31),
|
||||||
{"SEND_STATUS" , 0x0D000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0},
|
SD_CMD_INDEX(32) | SD_RESP_R1,
|
||||||
{"GO_INACTIVE" , 0x0F000000 | CMD_RSPNS_NO , RESP_NO , RCA_YES ,0},
|
SD_CMD_INDEX(33) | SD_RESP_R1,
|
||||||
{"SET_BLOCKLEN" , 0x10000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(34),
|
||||||
{"READ_SINGLE" , 0x11000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_CH, RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(35) | SD_RESP_R1, //add
|
||||||
{"READ_MULTI" , 0x12000000 | CMD_RSPNS_48 | TM_MULTI_DATA | TM_DAT_DIR_CH, RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(36) | SD_RESP_R1, //add
|
||||||
{"SEND_TUNING" , 0x13000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(37),
|
||||||
{"SPEED_CLASS" , 0x14000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0},
|
SD_CMD_INDEX(38) | SD_RESP_R1b,
|
||||||
{"SET_BLOCKCNT" , 0x17000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(39) | SD_RESP_R4, //add
|
||||||
{"WRITE_SINGLE" , 0x18000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_HC, RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(40) | SD_RESP_R5, //add
|
||||||
{"WRITE_MULTI" , 0x19000000 | CMD_RSPNS_48 | TM_MULTI_DATA | TM_DAT_DIR_HC, RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote
|
||||||
{"PROGRAM_CSD" , 0x1B000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(42) | SD_RESP_R1,
|
||||||
{"SET_WRITE_PR" , 0x1C000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0},
|
SD_CMD_RESERVED(43),
|
||||||
{"CLR_WRITE_PR" , 0x1D000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0},
|
SD_CMD_RESERVED(44),
|
||||||
{"SND_WRITE_PR" , 0x1E000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(45),
|
||||||
{"ERASE_WR_ST" , 0x20000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(46),
|
||||||
{"ERASE_WR_END" , 0x21000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(47),
|
||||||
{"ERASE" , 0x26000000 | CMD_RSPNS_48B , RESP_R1b, RCA_NO ,0},
|
SD_CMD_RESERVED(48),
|
||||||
{"LOCK_UNLOCK" , 0x2A000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(49),
|
||||||
{"APP_CMD" , 0x37000000 | CMD_RSPNS_NO , RESP_NO , RCA_NO ,100},
|
SD_CMD_RESERVED(50),
|
||||||
{"APP_CMD" , 0x37000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0},
|
SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ,
|
||||||
{"GEN_CMD" , 0x38000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(52),
|
||||||
|
SD_CMD_RESERVED(53),
|
||||||
// APP commands must be prefixed by an APP_CMD.
|
SD_CMD_RESERVED(54),
|
||||||
{"SET_BUS_WIDTH", 0x06000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_INDEX(55) | SD_RESP_R3,
|
||||||
{"SD_STATUS" , 0x0D000000 | CMD_RSPNS_48 , RESP_R1 , RCA_YES ,0}, // RCA???
|
SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA,
|
||||||
{"SEND_NUM_WRBL", 0x16000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(57),
|
||||||
{"SEND_NUM_ERS" , 0x17000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(58),
|
||||||
{"SD_SENDOPCOND", 0x29000000 | CMD_RSPNS_48 , RESP_R3 , RCA_NO ,1000},
|
SD_CMD_RESERVED(59),
|
||||||
{"SET_CLR_DET" , 0x2A000000 | CMD_RSPNS_48 , RESP_R1 , RCA_NO ,0},
|
SD_CMD_RESERVED(60),
|
||||||
{"SEND_SCR" , 0x33000000 | CMD_RSPNS_48 | CMD_IS_DATA | TM_DAT_DIR_CH , RESP_R1 , RCA_NO ,0},
|
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)
|
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)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
rt_err_t sd_int(struct sdhci_pdata_t * pdat, unsigned int mask)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd)
|
||||||
{
|
{
|
||||||
rt_uint32_t cmdidx;
|
rt_uint32_t cmdidx;
|
||||||
rt_uint32_t status;
|
|
||||||
rt_err_t ret = RT_EOK;
|
rt_err_t ret = RT_EOK;
|
||||||
|
ret = sd_status(pdat, SR_CMD_INHIBIT);
|
||||||
if(read32(pdat->virt + EMMC_STATUS) & SR_CMD_INHIBIT)
|
if (ret)
|
||||||
write32(pdat->virt + EMMC_CMDTM, 0x0);
|
|
||||||
|
|
||||||
EMMCCommand* cmdtab = &sdCommandTable[cmd->cmdidx];
|
|
||||||
|
|
||||||
cmdidx = cmdtab->code;
|
|
||||||
|
|
||||||
write32(pdat->virt + EMMC_ARG1, cmd->cmdarg);
|
|
||||||
write32(pdat->virt + EMMC_CMDTM, cmdidx);
|
|
||||||
|
|
||||||
do {
|
|
||||||
status = read32(pdat->virt + EMMC_STATUS);
|
|
||||||
} while(!(status & SR_CMD_INHIBIT));
|
|
||||||
|
|
||||||
if(cmd->resptype & RESP_MASK)
|
|
||||||
{
|
{
|
||||||
cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
|
rt_kprintf("ERROR: EMMC busy %d\n", ret);
|
||||||
if(cmd->resptype & RESP_R2)
|
return ret;
|
||||||
{
|
|
||||||
cmd->response[1] = read32(pdat->virt + EMMC_RESP1);
|
|
||||||
cmd->response[2] = read32(pdat->virt + EMMC_RESP2);
|
|
||||||
cmd->response[3] = read32(pdat->virt + EMMC_RESP3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
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)
|
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;
|
int c = 0;
|
||||||
rt_uint32_t count = blkcount * blksize;
|
rt_err_t ret;
|
||||||
rt_uint32_t status, err;
|
int d;
|
||||||
|
while (c < blkcount)
|
||||||
// status = read32(pdat->virt + PL180_STATUS);
|
{
|
||||||
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT | PL180_STAT_RX_OVERRUN);
|
if ((ret = sd_int(pdat, INT_READ_RDY)))
|
||||||
// while((!err) && (count >= sizeof(rt_uint32_t)))
|
{
|
||||||
// {
|
rt_kprintf("timeout happens when reading block %d\n",c);
|
||||||
// if(status & PL180_STAT_RX_FIFO_AVL)
|
return ret;
|
||||||
// {
|
}
|
||||||
// *(tmp) = read32(pdat->virt + PL180_FIFO);
|
for (d=0; d < blksize / 4; d++)
|
||||||
// tmp++;
|
if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
|
||||||
// count -= sizeof(rt_uint32_t);
|
buf[d] = read32(pdat->virt + EMMC_DATA);
|
||||||
// }
|
c++;
|
||||||
// status = read32(pdat->virt + PL180_STATUS);
|
buf += blksize / 4;
|
||||||
// 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;
|
|
||||||
|
|
||||||
return RT_EOK;
|
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)
|
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;
|
int c = 0;
|
||||||
rt_uint32_t count = blkcount * blksize;
|
rt_err_t ret;
|
||||||
rt_uint32_t status, err;
|
int d;
|
||||||
int i;
|
while (c < blkcount)
|
||||||
|
{
|
||||||
// status = read32(pdat->virt + PL180_STATUS);
|
if ((ret = sd_int(pdat, INT_WRITE_RDY)))
|
||||||
// err = status & (PL180_STAT_DAT_CRC_FAIL | PL180_STAT_DAT_TIME_OUT);
|
{
|
||||||
// while(!err && count)
|
return ret;
|
||||||
// {
|
}
|
||||||
// if(status & PL180_STAT_TX_FIFO_HALF)
|
for (d=0; d < blksize / 4; d++)
|
||||||
// {
|
write32(pdat->virt + EMMC_DATA, buf[d]);
|
||||||
// if(count >= 8 * sizeof(rt_uint32_t))
|
c++;
|
||||||
// {
|
buf += blksize / 4;
|
||||||
// for(i = 0; i < 8; i++)
|
}
|
||||||
// write32(pdat->virt + PL180_FIFO, *(tmp + i));
|
if ((ret = sd_int(pdat, INT_DATA_DONE)))
|
||||||
// tmp += 8;
|
{
|
||||||
// count -= 8 * sizeof(rt_uint32_t);
|
return ret;
|
||||||
// }
|
}
|
||||||
// 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;
|
|
||||||
return RT_EOK;
|
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)
|
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 dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
|
||||||
rt_uint32_t blksz_bits = dat->blksz - 1;
|
rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
|
||||||
rt_err_t ret = -RT_ERROR;
|
if (ret)
|
||||||
|
|
||||||
write32(pdat->virt + EMMC_BLKSIZECNT, dlen);
|
|
||||||
|
|
||||||
if(dat->flag & DATA_DIR_READ)
|
|
||||||
{
|
{
|
||||||
write32(pdat->virt + EMMC_STATUS, SR_READ_TRANSFER);
|
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);
|
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);
|
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);
|
ret = raspi_transfer_command(pdat, cmd);
|
||||||
if (ret < 0) return ret;
|
if (ret) return ret;
|
||||||
write32(pdat->virt + EMMC_STATUS, SR_WRITE_TRANSFER);
|
mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz );
|
||||||
ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
|
ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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)
|
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_t *sdhci = (struct sdhci_t *)host->private_data;
|
||||||
struct sdhci_cmd_t cmd;
|
struct sdhci_cmd_t cmd;
|
||||||
struct sdhci_cmd_t stop;
|
struct sdhci_cmd_t stop;
|
||||||
struct sdhci_data_t dat;
|
struct sdhci_data_t dat;
|
||||||
|
|
||||||
rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
|
rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
|
||||||
rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
|
rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
|
||||||
rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
|
rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
|
||||||
|
|
||||||
cmd.cmdidx = req->cmd->cmd_code;
|
cmd.cmdidx = req->cmd->cmd_code;
|
||||||
EMMCCommand* cmdtab = &sdCommandTable[cmd.cmdidx];
|
|
||||||
cmd.cmdarg = req->cmd->arg;
|
cmd.cmdarg = req->cmd->arg;
|
||||||
cmd.resptype = cmdtab->resp;
|
cmd.resptype =resp_type(req->cmd);
|
||||||
|
if (req->data)
|
||||||
if(req->data)
|
|
||||||
{
|
{
|
||||||
dat.buf = (rt_uint8_t *)req->data->buf;
|
dat.buf = (rt_uint8_t *)req->data->buf;
|
||||||
dat.flag = req->data->flags;
|
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)
|
if (req->stop)
|
||||||
{
|
{
|
||||||
stop.cmdidx = req->stop->cmd_code;
|
stop.cmdidx = req->stop->cmd_code;
|
||||||
cmdtab = &sdCommandTable[cmd.cmdidx];
|
|
||||||
stop.cmdarg = req->stop->arg;
|
stop.cmdarg = req->stop->arg;
|
||||||
cmd.resptype = cmdtab->resp;
|
cmd.resptype =resp_type(req->stop);
|
||||||
|
|
||||||
req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
|
req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
mmcsd_req_complete(host);
|
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)
|
rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
|
||||||
{
|
{
|
||||||
return 0;
|
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;
|
rt_uint32_t temp = 0;
|
||||||
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_CONTROL0));
|
if (width == MMCSD_BUS_WIDTH_4)
|
||||||
temp |= C0_HCTL_HS_EN;
|
{
|
||||||
temp |= C0_HCTL_DWITDH; // always use 4 data lines:
|
temp = read32((pdat->virt + EMMC_CONTROL0));
|
||||||
write32((pdat->virt + EMMC_CONTROL0), temp);
|
temp |= C0_HCTL_HS_EN;
|
||||||
|
temp |= C0_HCTL_DWITDH; // always use 4 data lines:
|
||||||
|
write32((pdat->virt + EMMC_CONTROL0), temp);
|
||||||
|
}
|
||||||
return RT_EOK;
|
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 divisor;
|
||||||
rt_uint32_t closest = 41666666 / freq;
|
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
|
else
|
||||||
divisor = (1 << shiftcount);
|
divisor = (1 << shiftcount);
|
||||||
|
|
||||||
if (divisor <= 2) {
|
if (divisor <= 2)
|
||||||
|
{
|
||||||
divisor = 2;
|
divisor = 2;
|
||||||
shiftcount = 0;
|
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 temp = 0;
|
||||||
rt_uint32_t sdHostVer = 0;
|
rt_uint32_t sdHostVer = 0;
|
||||||
int count = 100000;
|
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 ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
|
||||||
while((temp & (SR_CMD_INHIBIT | SR_DAT_INHIBIT))&&(--count))
|
DELAY_MICROS(1);
|
||||||
bcm283x_clo_delayMicros(1);
|
if (count <= 0)
|
||||||
|
|
||||||
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;
|
return RT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch clock off.
|
// Switch clock off.
|
||||||
temp = read32((pdat->virt + EMMC_CONTROL1));
|
temp = read32((pdat->virt + EMMC_CONTROL1));
|
||||||
temp |= ~C1_CLK_EN;
|
temp &= ~C1_CLK_EN;
|
||||||
write32((pdat->virt + EMMC_CONTROL1),temp);
|
write32((pdat->virt + EMMC_CONTROL1),temp);
|
||||||
|
DELAY_MICROS(10);
|
||||||
bcm283x_clo_delayMicros(10);
|
|
||||||
|
|
||||||
// Request the new clock setting and enable the clock
|
// Request the new clock setting and enable the clock
|
||||||
temp = read32(pdat->virt + EMMC_SLOTISR_VER);
|
temp = read32(pdat->virt + EMMC_SLOTISR_VER);
|
||||||
sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
|
sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
|
||||||
|
|
||||||
int cdiv = sdhci_getdivider(sdHostVer, clock);
|
int cdiv = sdhci_getdivider(sdHostVer, clock);
|
||||||
temp = read32((pdat->virt + EMMC_CONTROL1));
|
temp = read32((pdat->virt + EMMC_CONTROL1));
|
||||||
temp = (temp & 0xffff003f) | cdiv;
|
temp = (temp & 0xffff003f) | cdiv;
|
||||||
write32((pdat->virt + EMMC_CONTROL1),temp);
|
write32((pdat->virt + EMMC_CONTROL1),temp);
|
||||||
bcm283x_clo_delayMicros(10);
|
DELAY_MICROS(10);
|
||||||
|
|
||||||
// Enable the clock.
|
// Enable the clock.
|
||||||
temp = read32(pdat->virt + EMMC_CONTROL1);
|
temp = read32(pdat->virt + EMMC_CONTROL1);
|
||||||
temp |= C1_CLK_EN;
|
temp |= C1_CLK_EN;
|
||||||
write32((pdat->virt + EMMC_CONTROL1),temp);
|
write32((pdat->virt + EMMC_CONTROL1),temp);
|
||||||
bcm283x_clo_delayMicros(10);
|
DELAY_MICROS(10);
|
||||||
|
|
||||||
// Wait for clock to be stable.
|
// Wait for clock to be stable.
|
||||||
count = 10000;
|
count = 10000;
|
||||||
temp = read32(pdat->virt + EMMC_CONTROL1);
|
while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--)
|
||||||
while( !(temp & C1_CLK_STABLE) && count-- )
|
DELAY_MICROS(10);
|
||||||
bcm283x_clo_delayMicros(10);
|
if (count <= 0)
|
||||||
|
|
||||||
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;
|
return RT_ERROR;
|
||||||
}
|
}
|
||||||
|
mmcsd_dbg("set stable clock %d.\n", clock);
|
||||||
return RT_EOK;
|
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 =
|
static const struct rt_mmcsd_host_ops ops =
|
||||||
{
|
{
|
||||||
mmc_request_send,
|
mmc_request_send,
|
||||||
|
@ -444,27 +459,67 @@ static const struct rt_mmcsd_host_ops ops =
|
||||||
|
|
||||||
static void sdmmc_gpio_init()
|
static void sdmmc_gpio_init()
|
||||||
{
|
{
|
||||||
int pin;
|
// int pin;
|
||||||
|
// bcm283x_gpio_fsel(47,BCM283X_GPIO_FSEL_INPT);
|
||||||
for (pin = BCM_GPIO_PIN_48; pin <= BCM_GPIO_PIN_53; pin++)
|
// bcm283x_gpio_set_pud(47, BCM283X_GPIO_PUD_UP);
|
||||||
{
|
// bcm283x_peri_set_bits(BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN1, 1<<15, 1<<15);
|
||||||
bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
|
// for (pin = 53; pin >= 48; pin--)
|
||||||
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3);
|
// {
|
||||||
}
|
// bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3);
|
||||||
bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
|
// bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
|
||||||
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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)
|
int raspi_sdmmc_init(void)
|
||||||
{
|
{
|
||||||
rt_uint32_t virt;
|
rt_uint32_t virt;
|
||||||
rt_uint32_t id;
|
|
||||||
struct rt_mmcsd_host * host = RT_NULL;
|
struct rt_mmcsd_host * host = RT_NULL;
|
||||||
struct sdhci_pdata_t * pdat = RT_NULL;
|
struct sdhci_pdata_t * pdat = RT_NULL;
|
||||||
struct sdhci_t * sdhci = RT_NULL;
|
struct sdhci_t * sdhci = RT_NULL;
|
||||||
|
|
||||||
rt_kprintf("raspi_sdmmc_init start\n");
|
|
||||||
|
|
||||||
#ifdef BSP_USING_SDIO0
|
#ifdef BSP_USING_SDIO0
|
||||||
host = mmcsd_alloc_host();
|
host = mmcsd_alloc_host();
|
||||||
if (!host)
|
if (!host)
|
||||||
|
@ -481,21 +536,19 @@ int raspi_sdmmc_init(void)
|
||||||
}
|
}
|
||||||
rt_memset(sdhci, 0, sizeof(struct sdhci_t));
|
rt_memset(sdhci, 0, sizeof(struct sdhci_t));
|
||||||
|
|
||||||
rt_kprintf(">> sdmmc_gpio_init\n");
|
|
||||||
sdmmc_gpio_init();
|
sdmmc_gpio_init();
|
||||||
rt_kprintf("<< sdmmc_gpio_init\n");
|
|
||||||
|
|
||||||
virt = MMC0_BASE_ADDR;
|
virt = MMC0_BASE_ADDR;
|
||||||
|
|
||||||
pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
|
pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
|
||||||
RT_ASSERT(pdat != RT_NULL);
|
RT_ASSERT(pdat != RT_NULL);
|
||||||
|
|
||||||
pdat->virt = (rt_uint32_t)virt;
|
pdat->virt = (rt_uint32_t)virt;
|
||||||
|
reset_emmc(pdat);
|
||||||
|
|
||||||
sdhci->name = "sd0";
|
sdhci->name = "sd0";
|
||||||
sdhci->voltages = VDD_33_34;
|
sdhci->voltages = VDD_33_34;
|
||||||
sdhci->width = MMCSD_BUSWIDTH_4;
|
sdhci->width = MMCSD_BUSWIDTH_4;
|
||||||
sdhci->clock = 26 * 1000 * 1000;
|
sdhci->clock = 200 * 1000 * 1000;
|
||||||
sdhci->removeable = RT_TRUE;
|
sdhci->removeable = RT_TRUE;
|
||||||
|
|
||||||
sdhci->detect = sdhci_detect;
|
sdhci->detect = sdhci_detect;
|
||||||
|
@ -503,7 +556,6 @@ int raspi_sdmmc_init(void)
|
||||||
sdhci->setclock = sdhci_setclock;
|
sdhci->setclock = sdhci_setclock;
|
||||||
sdhci->transfer = sdhci_transfer;
|
sdhci->transfer = sdhci_transfer;
|
||||||
sdhci->priv = pdat;
|
sdhci->priv = pdat;
|
||||||
//write32(pdat->virt + PL180_POWER, 0xbf);
|
|
||||||
|
|
||||||
host->ops = &ops;
|
host->ops = &ops;
|
||||||
host->freq_min = 400000;
|
host->freq_min = 400000;
|
||||||
|
@ -517,16 +569,20 @@ int raspi_sdmmc_init(void)
|
||||||
|
|
||||||
host->private_data = sdhci;
|
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);
|
mmcsd_change(host);
|
||||||
|
#endif
|
||||||
return RT_EOK;
|
return RT_EOK;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if(host) rt_free(host);
|
if (host) rt_free(host);
|
||||||
if(sdhci) rt_free(sdhci);
|
if (sdhci) rt_free(sdhci);
|
||||||
|
|
||||||
return -RT_EIO;
|
return -RT_EIO;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
INIT_APP_EXPORT(raspi_sdmmc_init);
|
|
||||||
#endif
|
INIT_DEVICE_EXPORT(raspi_sdmmc_init);
|
||||||
|
|
|
@ -13,50 +13,12 @@
|
||||||
#define __DRV_SDIO_H__
|
#define __DRV_SDIO_H__
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
#include <rtdevice.h>
|
||||||
|
#include <drivers/mmcsd_core.h>
|
||||||
|
|
||||||
#define MMC0_BASE_ADDR 0x20300000
|
#include "board.h"
|
||||||
|
|
||||||
struct raspi_mmc
|
#define MMC0_BASE_ADDR 0x3F300000
|
||||||
{
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
#define BIT(x) (1<<(x))
|
|
||||||
|
|
||||||
/* Struct for Intrrrupt Information */
|
/* Struct for Intrrrupt Information */
|
||||||
#define SDXC_CmdDone BIT(0)
|
#define SDXC_CmdDone BIT(0)
|
||||||
|
@ -78,25 +40,6 @@ typedef struct raspi_mmc *raspi_mmc_t;
|
||||||
#define SDXC_DENDErr BIT(22)
|
#define SDXC_DENDErr BIT(22)
|
||||||
#define SDXC_ACMDErr BIT(24)
|
#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_BLKCNT_EN BIT(1)
|
||||||
#define SDXC_AUTO_CMD12_EN BIT(2)
|
#define SDXC_AUTO_CMD12_EN BIT(2)
|
||||||
#define SDXC_AUTO_CMD23_EN BIT(3)
|
#define SDXC_AUTO_CMD23_EN BIT(3)
|
||||||
|
@ -112,82 +55,20 @@ REG[31] : Load cmd
|
||||||
#define SDXC_CMD_RESUME BIT(23)
|
#define SDXC_CMD_RESUME BIT(23)
|
||||||
#define SDXC_CMD_ABORT BIT(23)|BIT(22)
|
#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_CMD_INHIBIT BIT(0)
|
||||||
#define SDXC_DAT_INHIBIT BIT(1)
|
#define SDXC_DAT_INHIBIT BIT(1)
|
||||||
#define SDXC_DAT_ACTIVE BIT(2)
|
#define SDXC_DAT_ACTIVE BIT(2)
|
||||||
#define SDXC_WRITE_TRANSFER BIT(8)
|
#define SDXC_WRITE_TRANSFER BIT(8)
|
||||||
#define SDXC_READ_TRANSFER BIT(9)
|
#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
|
struct sdhci_cmd_t
|
||||||
{
|
{
|
||||||
rt_uint32_t cmdidx;
|
rt_uint32_t cmdidx;
|
||||||
rt_uint32_t cmdarg;
|
rt_uint32_t cmdarg;
|
||||||
//const char* name;
|
|
||||||
// rt_uint32_t code;
|
|
||||||
rt_uint32_t resptype;
|
rt_uint32_t resptype;
|
||||||
// rt_uint8_t rca;
|
rt_uint32_t datarw;
|
||||||
// rt_uint32_t delay;
|
#define DATA_READ 1
|
||||||
|
#define DATA_WRITE 2
|
||||||
rt_uint32_t response[4];
|
rt_uint32_t response[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -240,17 +121,6 @@ struct sdhci_pdata_t
|
||||||
#define TM_BLKCNT_EN 0x00000002
|
#define TM_BLKCNT_EN 0x00000002
|
||||||
#define TM_MULTI_DATA (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
|
#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_NO 1
|
||||||
#define RCA_YES 2
|
#define RCA_YES 2
|
||||||
|
|
||||||
|
@ -341,5 +211,43 @@ struct sdhci_pdata_t
|
||||||
#define SR_DAT_INHIBIT 0x00000002
|
#define SR_DAT_INHIBIT 0x00000002
|
||||||
#define SR_CMD_INHIBIT 0x00000001
|
#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
|
#endif
|
||||||
|
|
|
@ -67,4 +67,10 @@ enum rpi_pin_name
|
||||||
RPI_GPIO_PIN_NUM,
|
RPI_GPIO_PIN_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define DELAY_MICROS(micros) \
|
||||||
|
do{ \
|
||||||
|
rt_uint32_t compare = STIMER_CLO + micros * 25; \
|
||||||
|
while (STIMER_CLO < compare); \
|
||||||
|
} while (0) \
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio
|
if [ ! -f "sd.bin" ]; then
|
||||||
|
dd if=/dev/zero of=sd.bin bs=1024 count=65536
|
||||||
|
fi
|
||||||
|
qemu-system-aarch64 -M raspi3 -kernel kernel8.img -serial null -serial stdio -sd sd.bin -nographic -monitor pty
|
|
@ -43,7 +43,7 @@
|
||||||
#define RT_USING_DEVICE
|
#define RT_USING_DEVICE
|
||||||
#define RT_USING_DEVICE_OPS
|
#define RT_USING_DEVICE_OPS
|
||||||
#define RT_USING_CONSOLE
|
#define RT_USING_CONSOLE
|
||||||
#define RT_CONSOLEBUF_SIZE 128
|
#define RT_CONSOLEBUF_SIZE 512
|
||||||
#define RT_CONSOLE_DEVICE_NAME "uart1"
|
#define RT_CONSOLE_DEVICE_NAME "uart1"
|
||||||
#define RT_VER_NUM 0x40003
|
#define RT_VER_NUM 0x40003
|
||||||
#define ARCH_CPU_64BIT
|
#define ARCH_CPU_64BIT
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
#define RT_USING_COMPONENTS_INIT
|
#define RT_USING_COMPONENTS_INIT
|
||||||
#define RT_USING_USER_MAIN
|
#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
|
#define RT_MAIN_THREAD_PRIORITY 10
|
||||||
|
|
||||||
/* C++ features */
|
/* C++ features */
|
||||||
|
@ -81,6 +81,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 */
|
||||||
|
@ -90,6 +102,13 @@
|
||||||
#define RT_USING_SERIAL
|
#define RT_USING_SERIAL
|
||||||
#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 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 */
|
/* Using USB */
|
||||||
|
|
||||||
|
@ -174,6 +193,8 @@
|
||||||
#define RT_USING_UART1
|
#define RT_USING_UART1
|
||||||
#define BSP_USING_PIN
|
#define BSP_USING_PIN
|
||||||
#define BSP_USING_CORETIMER
|
#define BSP_USING_CORETIMER
|
||||||
|
#define BSP_USING_SDIO
|
||||||
|
#define BSP_USING_SDIO0
|
||||||
|
|
||||||
/* Board Peripheral Drivers */
|
/* Board Peripheral Drivers */
|
||||||
|
|
||||||
|
|
|
@ -610,7 +610,7 @@ RTM_EXPORT(mmcsd_wait_cd_changed);
|
||||||
|
|
||||||
void mmcsd_change(struct rt_mmcsd_host *host)
|
void mmcsd_change(struct rt_mmcsd_host *host)
|
||||||
{
|
{
|
||||||
rt_mb_send(&mmcsd_detect_mb, (rt_uint32_t)host);
|
rt_mb_send(&mmcsd_detect_mb, (rt_ubase_t)host);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mmcsd_detect(void *param)
|
void mmcsd_detect(void *param)
|
||||||
|
@ -649,7 +649,7 @@ void mmcsd_detect(void *param)
|
||||||
if (init_sd(host, ocr))
|
if (init_sd(host, ocr))
|
||||||
mmcsd_power_off(host);
|
mmcsd_power_off(host);
|
||||||
mmcsd_host_unlock(host);
|
mmcsd_host_unlock(host);
|
||||||
rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
|
rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,7 +662,7 @@ void mmcsd_detect(void *param)
|
||||||
if (init_mmc(host, ocr))
|
if (init_mmc(host, ocr))
|
||||||
mmcsd_power_off(host);
|
mmcsd_power_off(host);
|
||||||
mmcsd_host_unlock(host);
|
mmcsd_host_unlock(host);
|
||||||
rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
|
rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mmcsd_host_unlock(host);
|
mmcsd_host_unlock(host);
|
||||||
|
@ -683,7 +683,7 @@ void mmcsd_detect(void *param)
|
||||||
host->card = RT_NULL;
|
host->card = RT_NULL;
|
||||||
}
|
}
|
||||||
mmcsd_host_unlock(host);
|
mmcsd_host_unlock(host);
|
||||||
rt_mb_send(&mmcsd_hotpluge_mb, (rt_uint32_t)host);
|
rt_mb_send(&mmcsd_hotpluge_mb, (rt_ubase_t)host);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue