[N9H30] Support P0 and P1 ports of SDH.

This commit is contained in:
Wayne Lin 2021-06-21 22:04:34 +08:00
parent db3dec0ef3
commit 84e5ec69a2
6 changed files with 187 additions and 52 deletions

View File

@ -741,6 +741,7 @@ uint32_t SDH_Probe(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num);
uint32_t SDH_Read(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
uint32_t SDH_Write(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32StartSec, uint32_t u32SecCount);
void SDH_CardSelect(SDH_T *sdh, uint32_t u32CardSrc);
uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num);
void SDH_Open_Disk(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc);
void SDH_Close_Disk(SDH_T *sdh, SDH_INFO_T *pSD);

View File

@ -249,16 +249,18 @@ void SDH_Set_clock(SDH_T *sdh, uint32_t sd_clock_khz)
else
reg = REG_CLK_DIVCTL9;
if(sd_clock_khz<=2000)
if (sd_clock_khz <= 2000)
{
SDH_ReferenceClock=12000;
SDH_ReferenceClock = 12000;
outpw(reg, (inpw(reg) & ~0x18) | (0x0 << 3)); // SD clock from XIN [4:3]
}else{
}
else
{
SDH_ReferenceClock = 300000;
outpw(reg, (inpw(reg) & ~0x18) | (0x3 << 3)); // SD clock from UPLL [4:3]
}
div=(SDH_ReferenceClock/sd_clock_khz)-1;
if(div>=SDH_CLK_DIV0_MAX) div=0xff;
div = (SDH_ReferenceClock / sd_clock_khz) - 1;
if (div >= SDH_CLK_DIV0_MAX) div = 0xff;
outpw(reg, (inpw(reg) & ~0xff00) | ((div) << 8)); // SD clock divided by CLKDIV3[SD_N] [15:8]
}
@ -269,7 +271,7 @@ uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
uint32_t u32INTSTS_CDSTS_Msk;
uint32_t u32CTL_CLKKEEP_Msk;
if ( card_num == SD_PORT1 )
if (card_num == SD_PORT1)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS1_Msk;
@ -279,9 +281,9 @@ uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS_Msk;
u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP_Msk;
u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP_Msk;
}
if ((sdh->INTEN & u32INTEN_CDSRC_Msk) == u32INTEN_CDSRC_Msk) /* Card detect pin from GPIO */
{
if ((sdh->INTSTS & u32INTSTS_CDSTS_Msk) == u32INTSTS_CDSTS_Msk) /* Card remove */
@ -318,6 +320,19 @@ uint32_t SDH_CardDetection(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
return val;
}
void SDH_CardSelect(SDH_T *sdh, uint32_t u32CardSrc)
{
if (u32CardSrc & SD_PORT0)
{
sdh->CTL &= ~SDH_CTL_SDPORT_Msk;
}
else if (u32CardSrc & SD_PORT1)
{
sdh->CTL &= ~SDH_CTL_SDPORT_Msk;
sdh->CTL |= (1 << SDH_CTL_SDPORT_Pos);
}
}
uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
{
uint32_t volatile i, status;
@ -725,17 +740,17 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
{
volatile int i;
uint32_t u32INTEN_CDSRC_Msk=0;
uint32_t u32INTSTS_CDIF_Msk=0;
uint32_t u32INTEN_CDIEN_Msk=0;
uint32_t u32INTEN_CDSRC_Msk = 0;
uint32_t u32INTSTS_CDIF_Msk = 0;
uint32_t u32INTEN_CDIEN_Msk = 0;
if ( u32CardDetSrc & SD_PORT0 )
if (u32CardDetSrc & SD_PORT0)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
u32INTSTS_CDIF_Msk = SDH_INTSTS_CDIF_Msk;
u32INTEN_CDIEN_Msk = SDH_INTEN_CDIEN_Msk;
}
else if ( u32CardDetSrc & SD_PORT1 )
else if (u32CardDetSrc & SD_PORT1)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
u32INTSTS_CDIF_Msk = SDH_INTSTS_CDIF1_Msk;
@ -774,11 +789,11 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
if ((u32CardDetSrc & CardDetect_From_DAT3) == CardDetect_From_DAT3)
{
sdh->INTEN &= ~u32INTEN_CDSRC_Msk;
sdh->INTEN &= ~u32INTEN_CDSRC_Msk;
}
else
{
sdh->INTEN |= u32INTEN_CDSRC_Msk;
sdh->INTEN |= u32INTEN_CDSRC_Msk;
}
for (i = 0; i < 0x100; i++);
@ -816,13 +831,13 @@ uint32_t SDH_Probe(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
sdh->CTL |= 0x01ul << SDH_CTL_BLKCNT_Pos; /* set BLKCNT = 1 */
sdh->CTL &= ~SDH_CTL_DBW_Msk; /* SD 1-bit data bus */
if ( sdh != SDH0 ) //EMMC
{
if (sdh != SDH0) //EMMC
{
if (!(SDH_CardDetection(sdh, pSD, card_num)))
{
return SDH_NO_SD_CARD;
}
}
}
if ((val = SDH_Init(sdh, pSD)) != 0ul)
{
@ -830,7 +845,7 @@ uint32_t SDH_Probe(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t card_num)
}
/* divider */
if ( pSD->CardType == SDH_TYPE_MMC )
if (pSD->CardType == SDH_TYPE_MMC)
{
SDH_Set_clock(sdh, MMC_FREQ);
}

View File

@ -279,19 +279,11 @@ config SOC_SERIES_N9H30
config BSP_USING_EMMC
bool "Enable FMI_EMMC"
choice
prompt "Select SDH Port number"
config BSP_USING_SDH0
bool "Enable SDH_PORT0"
config BSP_USING_SDH_NONE
bool "Disable SDH Function"
config BSP_USING_SDH0
bool "Enable SDH_PORT0"
config BSP_USING_SDH1
bool "Enable SDH_PORT1"
endchoice
config BSP_USING_SDH1
bool "Enable SDH_PORT1"
config NU_SDH_HOTPLUG
bool "Using HOTPLUG"

View File

@ -60,6 +60,10 @@
#define NU_SDH_MOUNTPOINT_SDH1 NU_SDH_MOUNTPOINT_ROOT"/sd1"
#endif
#if defined(BSP_USING_SDH0) && defined(BSP_USING_SDH1)
#define NU_SDH_SHARED 1
#endif
enum
{
SDH_START = -1,
@ -82,7 +86,7 @@ enum
#endif
#if defined(NU_SDH_HOTPLUG)
typedef enum
typedef enum
{
NU_SDH_CARD_DETECTED_EMMC = (1 << 0),
NU_SDH_CARD_DETECTED_SD0 = (1 << 1),
@ -140,7 +144,21 @@ static int rt_hw_sdh_init(void);
/* Private variables ------------------------------------------------------------*/
static SDH_INFO_T EMMC, SD0, SD1;
#if defined(BSP_USING_EMMC)
static SDH_INFO_T EMMC;
#endif
#if defined(BSP_USING_SDH0)
static SDH_INFO_T SD0;
#endif
#if defined(BSP_USING_SDH1)
static SDH_INFO_T SD1;
#endif
#if defined(NU_SDH_SHARED)
static struct rt_mutex g_shared_lock;
#endif
static struct nu_sdh nu_sdh_arr [] =
{
@ -182,11 +200,17 @@ static struct nu_sdh nu_sdh_arr [] =
#if defined(NU_SDH_HOTPLUG)
.mounted_point = NU_SDH_MOUNTPOINT_SDH1,
#endif
.irqn = IRQ_SDH,
.base = SDH1,
.card_num = SD_PORT1,
#if defined(NU_SDH_SHARED)
.irqn = (IRQn_Type)0,
.rstidx = SYS_IPRST_NA,
.clkidx = SYS_IPCLK_NA,
#else
.irqn = IRQ_SDH,
.rstidx = SDIORST,
.clkidx = SDHCKEN,
#endif
.info = &SD1,
.card_detected_event = NU_SDH_CARD_DETECTED_SD1,
},
@ -219,17 +243,17 @@ static void SDH_IRQHandler(int vector, void *param)
if (isr & SDH_INTSTS_CDIF_Msk) // card number=0 detect
{
#if defined(NU_SDH_HOTPLUG)
rt_event_send(&sdh_event, sdh->card_detected_event);
#endif
#if defined(NU_SDH_HOTPLUG)
rt_event_send(&sdh_event, sdh->card_detected_event);
#endif
/* Clear CDIF interrupt flag */
SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_CDIF_Msk);
}
}
else if (isr & SDH_INTSTS_CDIF1_Msk) // card number=1 detect
{
#if defined(NU_SDH_HOTPLUG)
rt_event_send(&sdh_event, sdh->card_detected_event);
#endif
#if defined(NU_SDH_HOTPLUG)
rt_event_send(&sdh_event, sdh->card_detected_event);
#endif
/* Clear CDIF1 interrupt flag */
SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_CDIF1_Msk);
@ -277,10 +301,36 @@ static rt_err_t nu_sdh_init(rt_device_t dev)
static rt_err_t nu_sdh_open(rt_device_t dev, rt_uint16_t oflag)
{
nu_sdh_t sdh = (nu_sdh_t)dev;
rt_err_t result;
RT_ASSERT(dev != RT_NULL);
return (SDH_Probe(sdh->base, sdh->info, sdh->card_num) == 0) ? RT_EOK : -(RT_ERROR);
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
SDH_CardSelect(sdh->base, sdh->card_num);
#endif
if (SDH_Probe(sdh->base, sdh->info, sdh->card_num) == 0)
{
result = RT_EOK;
}
else
{
result = -RT_ERROR;
}
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
rt_mutex_release(&g_shared_lock);
}
#endif
return result;
}
static rt_err_t nu_sdh_close(rt_device_t dev)
@ -297,6 +347,15 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
SDH_CardSelect(sdh->base, sdh->card_num);
#endif
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
@ -346,6 +405,13 @@ exit_nu_sdh_read:
result = rt_sem_release(&sdh->lock);
RT_ASSERT(result == RT_EOK);
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
rt_mutex_release(&g_shared_lock);
}
#endif
if (ret == Successful)
return blk_nb;
@ -363,6 +429,15 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
RT_ASSERT(dev != RT_NULL);
RT_ASSERT(buffer != RT_NULL);
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
SDH_CardSelect(sdh->base, sdh->card_num);
#endif
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
@ -414,6 +489,13 @@ exit_nu_sdh_write:
result = rt_sem_release(&sdh->lock);
RT_ASSERT(result == RT_EOK);
#if defined(NU_SDH_SHARED)
if (sdh->base == SDH1)
{
rt_mutex_release(&g_shared_lock);
}
#endif
if (ret == Successful) return blk_nb;
rt_kprintf("write failed: %d, buffer 0x%08x\n", ret, buffer);
@ -454,6 +536,11 @@ static int rt_hw_sdh_init(void)
ret = rt_event_init(&sdh_event, "sdh_event", RT_IPC_FLAG_FIFO);
RT_ASSERT(ret == RT_EOK);
#if defined(NU_SDH_SHARED)
ret = rt_mutex_init(&g_shared_lock, "sdh_share_lock", RT_IPC_FLAG_PRIO);
RT_ASSERT(ret == RT_EOK);
#endif
#if defined(BSP_USING_EMMC)
nu_sys_ipclk_enable(FMICKEN);
nu_sys_ipclk_enable(NANDCKEN);
@ -476,12 +563,21 @@ static int rt_hw_sdh_init(void)
ret = rt_sem_init(&nu_sdh_arr[i].lock, "sdhlock", 1, RT_IPC_FLAG_FIFO);
RT_ASSERT(ret == RT_EOK);
rt_hw_interrupt_install(nu_sdh_arr[i].irqn, SDH_IRQHandler, (void *)&nu_sdh_arr[i], nu_sdh_arr[i].name);
rt_hw_interrupt_umask(nu_sdh_arr[i].irqn);
if (nu_sdh_arr[i].irqn != 0)
{
rt_hw_interrupt_install(nu_sdh_arr[i].irqn, SDH_IRQHandler, (void *)&nu_sdh_arr[i], nu_sdh_arr[i].name);
rt_hw_interrupt_umask(nu_sdh_arr[i].irqn);
}
nu_sys_ipclk_enable(nu_sdh_arr[i].clkidx);
if (nu_sdh_arr[i].clkidx != SYS_IPCLK_NA)
{
nu_sys_ipclk_enable(nu_sdh_arr[i].clkidx);
}
nu_sys_ip_reset(nu_sdh_arr[i].rstidx);
if (nu_sdh_arr[i].rstidx != SYS_IPRST_NA)
{
nu_sys_ip_reset(nu_sdh_arr[i].rstidx);
}
nu_sdh_arr[i].pbuf = RT_NULL;
@ -610,7 +706,7 @@ exit_nu_sdh_hotplug_unmount:
static void nu_card_detector(nu_sdh_t sdh)
{
SDH_T *sdh_base = sdh->base;
uint32_t u32INTSTS_CDSTS_Msk = (sdh->card_num==SD_PORT0)?SDH_INTSTS_CDSTS_Msk:SDH_INTSTS_CDSTS1_Msk;
uint32_t u32INTSTS_CDSTS_Msk = (sdh->card_num == SD_PORT0) ? SDH_INTSTS_CDSTS_Msk : SDH_INTSTS_CDSTS1_Msk;
unsigned int volatile isr = sdh_base->INTSTS;
if (isr & u32INTSTS_CDSTS_Msk)
@ -622,12 +718,27 @@ static void nu_card_detector(nu_sdh_t sdh)
}
else
{
SDH_Open(sdh_base, sdh->info, CardDetect_From_GPIO|sdh->card_num );
#if defined(NU_SDH_SHARED)
if (sdh_base == SDH1)
{
rt_err_t result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
SDH_CardSelect(sdh_base, sdh->card_num);
#endif
SDH_Open(sdh_base, sdh->info, CardDetect_From_GPIO | sdh->card_num);
if (!SDH_Probe(sdh_base, sdh->info, sdh->card_num))
{
/* Card inserted */
nu_sdh_hotplug_mount(sdh);
}
#if defined(NU_SDH_SHARED)
if (sdh_base == SDH1)
{
rt_mutex_release(&g_shared_lock);
}
#endif
}
}
@ -638,13 +749,29 @@ static void sdh_hotplugger(void *param)
for (i = (SDH_START + 1); i < SDH_CNT; i++)
{
#if defined(NU_SDH_SHARED)
if (nu_sdh_arr[i].base == SDH1)
{
rt_err_t result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
SDH_CardSelect(nu_sdh_arr[i].base, nu_sdh_arr[i].card_num);
#endif
/* Try to detect SD card on selected port. */
SDH_Open(nu_sdh_arr[i].base, nu_sdh_arr[i].info, CardDetect_From_GPIO|nu_sdh_arr[i].card_num);
SDH_Open(nu_sdh_arr[i].base, nu_sdh_arr[i].info, CardDetect_From_GPIO | nu_sdh_arr[i].card_num);
if (!SDH_Probe(nu_sdh_arr[i].base, nu_sdh_arr[i].info, nu_sdh_arr[i].card_num) &&
nu_sdh_arr[i].info->IsCardInsert)
{
nu_sdh_hotplug_mount(&nu_sdh_arr[i]);
}
#if defined(NU_SDH_SHARED)
if (nu_sdh_arr[i].base == SDH1)
{
rt_mutex_release(&g_shared_lock);
}
#endif
}
while (1)

View File

@ -491,6 +491,7 @@ CONFIG_PKG_USING_NUEMWIN_LATEST_VERSION=y
CONFIG_PKG_NUEMWIN_VER="latest"
CONFIG_PKG_NUEMWIN_VER_NUM=0x99999
# CONFIG_PKG_USING_MP3PLAYER is not set
# CONFIG_PKG_USING_TINYJPEG is not set
#
# tools packages
@ -859,7 +860,6 @@ CONFIG_BSP_USING_I2C0=y
# CONFIG_BSP_USING_I2C1 is not set
CONFIG_BSP_USING_SDH=y
# CONFIG_BSP_USING_EMMC is not set
# CONFIG_BSP_USING_SDHN is not set
CONFIG_BSP_USING_SDH0=y
# CONFIG_BSP_USING_SDH1 is not set
CONFIG_NU_SDH_HOTPLUG=y

View File

@ -28,9 +28,9 @@ menu "Hardware Drivers Config"
default n
config BOARD_USING_STORAGE_SDCARD
bool "SDCARD supporting(over sdh1)"
bool "SDCARD supporting(over sdh_p0)"
select BSP_USING_SDH
select BSP_USING_SDH1
select BSP_USING_SDH0
default y
config BOARD_USING_STORAGE_SPIFLASH