diff --git a/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h b/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h index f866a43a94..6620a29142 100644 --- a/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h +++ b/bsp/nuvoton/libraries/n9h30/Driver/Include/nu_sdh.h @@ -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); diff --git a/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c b/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c index b3a8c3faf8..106b5231bc 100644 --- a/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c +++ b/bsp/nuvoton/libraries/n9h30/Driver/Source/nu_sdh.c @@ -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); } diff --git a/bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig b/bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig index 34ca780405..54ba33049a 100644 --- a/bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig +++ b/bsp/nuvoton/libraries/n9h30/rtt_port/Kconfig @@ -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" diff --git a/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c b/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c index d7547cb30d..d1700c96d3 100644 --- a/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c +++ b/bsp/nuvoton/libraries/n9h30/rtt_port/drv_sdh.c @@ -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) diff --git a/bsp/nuvoton/nk-n9h30/.config b/bsp/nuvoton/nk-n9h30/.config index 736e227459..edb84754fd 100644 --- a/bsp/nuvoton/nk-n9h30/.config +++ b/bsp/nuvoton/nk-n9h30/.config @@ -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 diff --git a/bsp/nuvoton/nk-n9h30/board/Kconfig b/bsp/nuvoton/nk-n9h30/board/Kconfig index b5aff1bc9e..c26e25fb65 100644 --- a/bsp/nuvoton/nk-n9h30/board/Kconfig +++ b/bsp/nuvoton/nk-n9h30/board/Kconfig @@ -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