summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h15
-rw-r--r--bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c97
-rw-r--r--bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c22
3 files changed, 106 insertions, 28 deletions
diff --git a/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h b/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h
index 6620a29142..6a7d548c17 100644
--- a/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h
+++ b/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h
@@ -376,6 +376,7 @@ typedef struct
__IO uint32_t BLEN; /*!< [0x0838] SD Block Length Register */
__IO uint32_t TOUT; /*!< [0x083c] SD Response/Data-in Time-out Register */
+ __IO uint32_t ECTL; /*!< [0x0840] SD Host Extend Control Register */
} SDH_T;
@@ -450,8 +451,8 @@ typedef struct
#define SDH_CTL_CLK8OEN_Pos (6) /*!< SDH_T::CTL: CLK8OEN Position */
#define SDH_CTL_CLK8OEN_Msk (0x1ul << SDH_CTL_CLK8OEN_Pos) /*!< SDH_T::CTL: CLK8OEN Mask */
-#define SDH_CTL_CLKKEEP_Pos (7) /*!< SDH_T::CTL: CLKKEEP Position */
-#define SDH_CTL_CLKKEEP_Msk (0x1ul << SDH_CTL_CLKKEEP_Pos) /*!< SDH_T::CTL: CLKKEEP Mask */
+#define SDH_CTL_CLKKEEP0_Pos (7) /*!< SDH_T::CTL: CLKKEEP Position */
+#define SDH_CTL_CLKKEEP0_Msk (0x1ul << SDH_CTL_CLKKEEP0_Pos) /*!< SDH_T::CTL: CLKKEEP Mask */
#define SDH_CTL_CMDCODE_Pos (8) /*!< SDH_T::CTL: CMDCODE Position */
#define SDH_CTL_CMDCODE_Msk (0x3ful << SDH_CTL_CMDCODE_Pos) /*!< SDH_T::CTL: CMDCODE Mask */
@@ -567,6 +568,12 @@ typedef struct
#define SDH_TOUT_TOUT_Pos (0) /*!< SDH_T::TOUT: TOUT Position */
#define SDH_TOUT_TOUT_Msk (0xfffffful << SDH_TOUT_TOUT_Pos) /*!< SDH_T::TOUT: TOUT Mask */
+#define SDH_ECTL_POWEROFF0_Pos (0) /*!< SDH_T::ECTL: POWEROFF0 Position */
+#define SDH_ECTL_POWEROFF0_Msk (0x1ul << SDH_ECTL_POWEROFF0_Pos) /*!< SDH_T::ECTL: POWEROFF0 Mask */
+
+#define SDH_ECTL_POWEROFF1_Pos (1) /*!< SDH_T::ECTL: POWEROFF1 Position */
+#define SDH_ECTL_POWEROFF1_Msk (0x1ul << SDH_ECTL_POWEROFF1_Pos) /*!< SDH_T::ECTL: POWEROFF1 Mask */
+
/**@}*/ /* SDH_CONST */
/**@}*/ /* end of SDH register group */
/**@}*/ /* end of REGISTER group */
@@ -740,11 +747,11 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc);
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);
+void SDH_CardSelect(SDH_T *sdh, SDH_INFO_T *pSD, 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);
+uint32_t SDH_WhichCardIsSelected(SDH_T *sdh);
/*@}*/ /* end of group N9H30_SDH_EXPORTED_FUNCTIONS */
diff --git a/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c b/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c
index 106b5231bc..aafd93a92d 100644
--- a/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c
+++ b/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c
@@ -43,6 +43,23 @@
static uint8_t _SDH1_ucSDHCBuffer[512] __attribute__((aligned(32)));
#endif
+void dump_sdh_regs(SDH_T *sdh)
+{
+ rt_kprintf("\n+++++++++++++++++++++++\n");
+ rt_kprintf(" %s\n", sdh->CTL & SDH_CTL_SDPORT_Msk ? "SD1" : "SD0");
+ rt_kprintf(" DMACTL = 0x%08x\n", sdh->DMACTL);
+ rt_kprintf(" GCTL = 0x%08x\n", sdh->GCTL);
+ rt_kprintf(" GINTEN = 0x%08x\n", sdh->GINTEN);
+ rt_kprintf(" GINTSTS = 0x%08x\n", sdh->GINTSTS);
+ rt_kprintf(" CTL = 0x%08x\n", sdh->CTL);
+ rt_kprintf(" INTEN = 0x%08x\n", sdh->INTEN);
+ rt_kprintf(" INTSTS = 0x%08x\n", sdh->INTSTS);
+ rt_kprintf(" BLEN = 0x%08x\n", sdh->BLEN);
+ rt_kprintf(" TOUT = 0x%08x\n", sdh->TOUT);
+ rt_kprintf(" ECTL = 0x%08x\n", sdh->ECTL);
+ rt_kprintf("\n+++++++++++++++++++++++\n");
+}
+
void SDH_CheckRB(SDH_T *sdh)
{
while (1)
@@ -271,18 +288,18 @@ 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_PORT0)
+ {
+ u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
+ u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS_Msk;
+ u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP0_Msk;
+ }
+ else if (card_num & SD_PORT1)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS1_Msk;
u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP1_Msk;
}
- else
- {
- u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC_Msk;
- u32INTSTS_CDSTS_Msk = SDH_INTSTS_CDSTS_Msk;
- u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP_Msk;
- }
if ((sdh->INTEN & u32INTEN_CDSRC_Msk) == u32INTEN_CDSRC_Msk) /* Card detect pin from GPIO */
{
@@ -320,7 +337,12 @@ 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)
+uint32_t SDH_WhichCardIsSelected(SDH_T *sdh)
+{
+ return (sdh->CTL & SDH_CTL_SDPORT_Msk) ? SD_PORT1 : SD_PORT0;
+}
+
+void SDH_CardSelect(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardSrc)
{
if (u32CardSrc & SD_PORT0)
{
@@ -331,6 +353,26 @@ void SDH_CardSelect(SDH_T *sdh, uint32_t u32CardSrc)
sdh->CTL &= ~SDH_CTL_SDPORT_Msk;
sdh->CTL |= (1 << SDH_CTL_SDPORT_Pos);
}
+
+ switch (pSD->CardType)
+ {
+ case SDH_TYPE_MMC:
+ sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+ SDH_Set_clock(sdh, MMC_FREQ);
+ break;
+ case SDH_TYPE_SD_LOW:
+ case SDH_TYPE_EMMC:
+ sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+ SDH_Set_clock(sdh, SD_FREQ);
+ break;
+ case SDH_TYPE_SD_HIGH:
+ sdh->CTL |= SDH_CTL_DBW_Msk; /* set bus width to 4-bit mode for SD host controller */
+ SDH_Set_clock(sdh, SDHC_FREQ);
+ break;
+ case SDH_TYPE_UNKNOWN:
+ default:
+ break;
+ }
}
uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
@@ -363,6 +405,8 @@ uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
pSD->R7Flag = 1ul;
u32CmdTimeOut = 0xFFFFFul;
+ //dump_sdh_regs(sdh);
+
i = SDH_SDCmdAndRsp(sdh, pSD, 8ul, 0x00000155ul, u32CmdTimeOut);
if (i == Successful)
{
@@ -451,6 +495,7 @@ uint32_t SDH_Init(SDH_T *sdh, SDH_INFO_T *pSD)
else
{
pSD->CardType = SDH_TYPE_UNKNOWN;
+
return SDH_INIT_ERROR;
}
}
@@ -743,33 +788,56 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
uint32_t u32INTEN_CDSRC_Msk = 0;
uint32_t u32INTSTS_CDIF_Msk = 0;
uint32_t u32INTEN_CDIEN_Msk = 0;
+ uint32_t u32CTL_CLKKEEP_Msk = 0;
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;
+ u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP0_Msk;
}
else if (u32CardDetSrc & SD_PORT1)
{
u32INTEN_CDSRC_Msk = SDH_INTEN_CDSRC1_Msk;
u32INTSTS_CDIF_Msk = SDH_INTSTS_CDIF1_Msk;
u32INTEN_CDIEN_Msk = SDH_INTEN_CDIEN1_Msk;
+ u32CTL_CLKKEEP_Msk = SDH_CTL_CLKKEEP1_Msk;
}
- // enable DMAC
+ // Enable DMAC
sdh->DMACTL = SDH_DMACTL_DMARST_Msk;
while ((sdh->DMACTL & SDH_DMACTL_DMARST_Msk) == SDH_DMACTL_DMARST_Msk)
{
}
sdh->DMACTL = SDH_DMACTL_DMAEN_Msk;
- //Reset Global
+ // Reset Global
sdh->GCTL = SDH_GCTL_GCTLRST_Msk | SDH_GCTL_SDEN_Msk;
while ((sdh->GCTL & SDH_GCTL_GCTLRST_Msk) == SDH_GCTL_GCTLRST_Msk)
{
}
+ if (sdh == SDH1)
+ {
+ /* Enable Power, 0: Enable, 1:Disable */
+ if (u32CardDetSrc & SD_PORT0)
+ {
+ sdh->ECTL &= ~SDH_ECTL_POWEROFF0_Msk;
+ }
+ else if (u32CardDetSrc & SD_PORT1)
+ {
+ sdh->ECTL &= ~SDH_ECTL_POWEROFF1_Msk;
+ }
+ /* disable SD clock output */
+ sdh->CTL &= ~(0xFF | u32CTL_CLKKEEP_Msk);
+ }
+
+ sdh->CTL |= SDH_CTL_CTLRST_Msk;
+ while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
+ {
+ }
+
memset(pSD, 0, sizeof(SDH_INFO_T));
if (sdh == SDH0)
{
@@ -800,13 +868,10 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
sdh->INTSTS = u32INTSTS_CDIF_Msk;
sdh->INTEN |= u32INTEN_CDIEN_Msk;
-
- sdh->CTL |= SDH_CTL_CTLRST_Msk;
- while ((sdh->CTL & SDH_CTL_CTLRST_Msk) == SDH_CTL_CTLRST_Msk)
- {
- }
}
+
+
/**
* @brief This function use to initial SD card.
*
@@ -889,6 +954,7 @@ uint32_t SDH_Read(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32
{
return status;
}
+
SDH_CheckRB(sdh);
sdh->BLEN = blksize - 1ul; /* the actual byte count is equal to (SDBLEN+1) */
@@ -984,6 +1050,7 @@ uint32_t SDH_Read(SDH_T *sdh, SDH_INFO_T *pSD, uint8_t *pu8BufAddr, uint32_t u32
{
return SDH_CRC7_ERROR;
}
+
SDH_CheckRB(sdh);
SDH_SDCommand(sdh, pSD, 7ul, 0ul);
diff --git a/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c b/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c
index d1700c96d3..499311c752 100644
--- a/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c
+++ b/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c
@@ -225,6 +225,11 @@ static void SDH_IRQHandler(int vector, void *param)
unsigned int volatile isr;
SDH_INFO_T *pSD = sdh->info;
+#if defined(BSP_USING_SDH1)
+ if (SDH_WhichCardIsSelected(sdh_base) == SD_PORT1)
+ pSD = &SD1;
+#endif
+
// FMI data abort interrupt
if (sdh_base->GINTSTS & SDH_GINTSTS_DTAIF_Msk)
{
@@ -252,9 +257,8 @@ static void SDH_IRQHandler(int vector, void *param)
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);
+ rt_event_send(&sdh_event, NU_SDH_CARD_DETECTED_SD1);
#endif
-
/* Clear CDIF1 interrupt flag */
SDH_CLR_INT_FLAG(sdh_base, SDH_INTSTS_CDIF1_Msk);
}
@@ -301,7 +305,7 @@ 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_err_t result = RT_EOK;
RT_ASSERT(dev != RT_NULL);
@@ -311,7 +315,7 @@ static rt_err_t nu_sdh_open(rt_device_t dev, rt_uint16_t oflag)
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
- SDH_CardSelect(sdh->base, sdh->card_num);
+ SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
#endif
if (SDH_Probe(sdh->base, sdh->info, sdh->card_num) == 0)
@@ -353,7 +357,7 @@ static rt_size_t nu_sdh_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_siz
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
- SDH_CardSelect(sdh->base, sdh->card_num);
+ SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
#endif
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
@@ -435,7 +439,7 @@ static rt_size_t nu_sdh_write(rt_device_t dev, rt_off_t pos, const void *buffer,
result = rt_mutex_take(&g_shared_lock, RT_WAITING_FOREVER);
RT_ASSERT(result == RT_EOK);
}
- SDH_CardSelect(sdh->base, sdh->card_num);
+ SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
#endif
result = rt_sem_take(&sdh->lock, RT_WAITING_FOREVER);
@@ -724,7 +728,7 @@ static void nu_card_detector(nu_sdh_t sdh)
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);
+ SDH_CardSelect(sdh->base, sdh->info, sdh->card_num);
#endif
SDH_Open(sdh_base, sdh->info, CardDetect_From_GPIO | sdh->card_num);
@@ -755,7 +759,7 @@ static void sdh_hotplugger(void *param)
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);
+ SDH_CardSelect(nu_sdh_arr[i].base, nu_sdh_arr[i].info, nu_sdh_arr[i].card_num);
#endif
/* Try to detect SD card on selected port. */
@@ -781,7 +785,7 @@ static void sdh_hotplugger(void *param)
RT_WAITING_FOREVER, &e) == RT_EOK)
{
/* Debounce */
- rt_thread_mdelay(200);
+ rt_thread_mdelay(500);
switch (e)
{
#if defined(BSP_USING_EMMC)