|
@@ -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)
|