[N9H30] Fix SDH dual ports.
This commit is contained in:
parent
84e5ec69a2
commit
978ea520d9
|
@ -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 */
|
||||
|
|
|
@ -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,21 +788,24 @@ 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)
|
||||
{
|
||||
|
@ -770,6 +818,26 @@ void SDH_Open(SDH_T *sdh, SDH_INFO_T *pSD, uint32_t u32CardDetSrc)
|
|||
{
|
||||
}
|
||||
|
||||
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,12 +868,9 @@ 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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue