📄 msdc.c
字号:
{
msdc_input.type = DMA_HWRX;
if(count <= MSDC_READ_THD_POLL)
//if(0)
{
msdc_input.callback = NULL;
is_poll = KAL_TRUE;
}
else
{
msdc_input.callback = MSDC_DMA_Callback;
is_poll = KAL_FALSE;
}
}
if(kal_query_systemInit() == KAL_TRUE)
{
msdc_input.callback = NULL;
is_poll = KAL_TRUE;
}
if(adrs%4 == 0)
{
is_aligned = KAL_TRUE;
total_count = count;
}
else
{
is_aligned = KAL_FALSE;
total_count = count<<2;
}
gMSDC_Handle.total_count = total_count;
gMSDC_Handle.is_poll = is_poll;
gMSDC_Handle.is_aligned = is_aligned;
{
if(is_aligned)
{
#if defined(USE_DMA_BURST)
MSDC_SET_FIFO(4);
#else
msdc_menu.TMOD.burst_mode = KAL_FALSE;
#endif
msdc_input.count = (total_count > 65024)?(65024):(total_count);
msdc_input.size = DMA_LONG;
DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_FALSE);
msdc_menu.addr += msdc_input.count*4;
}
else
{
#if defined(USE_DMA_BURST)
MSDC_SET_FIFO(1);
#else
msdc_menu.TMOD.burst_mode = KAL_TRUE;
#endif
msdc_input.count = (total_count > 65024)?(65024):(total_count);
msdc_input.size = DMA_BYTE;
DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_TRUE);
msdc_menu.addr += msdc_input.count;
}
}
}
kal_uint32 MSDC_DMATransferFinal(void)
{
kal_uint32 total_count = gMSDC_Handle.total_count, t1;
kal_bool is_poll = gMSDC_Handle.is_poll;
kal_bool is_aligned = gMSDC_Handle.is_aligned;
t1 = drv_get_current_time();
if(gMSDC_Handle.timeout_period > MSDC_TIMEOUT_PERIOD_DAT)
gMSDC_Handle.timeout_period = MSDC_TIMEOUT_PERIOD_DAT;
MSDC_START_TIMER(gMSDC_Handle.timeout_period);
if(is_poll)
{
while(IS_MSDC_DMA_RUN && MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
{
if(drv_get_duration_ms(t1) > MSDC_TIMEOUT_PERIOD_DAT*11)
gMSDC_Handle.is_timeout = KAL_TRUE;
}
}
else
{
kal_uint32 flags;
kal_retrieve_eg_events(MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);
}
MSDC_STOP_TIMER();
total_count -= msdc_input.count;
if(total_count == 0)
return MSDC_NOERROR;
while(1)
{
if(is_aligned)
{
#if defined(USE_DMA_BURST)
MSDC_SET_FIFO(4);
#else
msdc_menu.TMOD.burst_mode = KAL_FALSE;
#endif
msdc_input.count = (total_count > 65024)?(65024):(total_count);
msdc_input.size = DMA_LONG;
DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_FALSE);
msdc_menu.addr += msdc_input.count*4;
gMSDC_Handle.timeout_period = 1 + (msdc_input.count>>7);
}
else
{
#if defined(USE_DMA_BURST)
MSDC_SET_FIFO(1);
#else
msdc_menu.TMOD.burst_mode = KAL_TRUE;
#endif
msdc_input.count = (total_count > 65024)?(65024):(total_count);
msdc_input.size = DMA_BYTE;
DMA_Config_B2W(msdc_dmaport,&msdc_input,KAL_TRUE,KAL_TRUE);
msdc_menu.addr += msdc_input.count;
gMSDC_Handle.timeout_period = 1 + (msdc_input.count>>9);
}
// wait until running bit clr
if(msdc_input.type == DMA_HWTX)
gMSDC_Handle.timeout_period <<= 2 ;
if(gMSDC_Handle.mMSDC_type == MMC_CARD)
gMSDC_Handle.timeout_period <<= 1;
t1 = drv_get_current_time();
MSDC_START_TIMER(gMSDC_Handle.timeout_period);
if(is_poll)
{
while(IS_MSDC_DMA_RUN && MSDC_Check_Card_Present() && !gMSDC_Handle.is_timeout)
{
if(drv_get_duration_ms(t1) > gMSDC_Handle.timeout_period*11)
gMSDC_Handle.is_timeout = KAL_TRUE;
}
}
else
{
kal_uint32 flags;
kal_retrieve_eg_events(MSDC_Events,(EVENT_DMAIRQ),KAL_OR_CONSUME,&flags,KAL_SUSPEND);
}
MSDC_STOP_TIMER();
if(IS_MSDC_DMA_RUN && gMSDC_Handle.is_timeout)
return MSDC_GPT_TIMEOUT_ERR;
total_count -= msdc_input.count;
if(total_count == 0)
break;
}
return MSDC_NOERROR;
}
#endif // DMA
#ifdef MSDC_INT
#ifdef USE_INT26_CARD_DETECTION
void MSDC_CardDetect_LISR(void)
{
IRQMask(IRQ_MSDC_CD_CODE);
gMSDC_Handle.mIsChanged = KAL_TRUE;
drv_active_hisr(DRV_MSDC_HISR_ID);
}
#endif //USE_INT26_CARD_DETECTION
/*************************************************************************
* FUNCTION
* MSDC_INT_Init
*
* DESCRIPTION
* Initialize MSDC's interrupt
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_INT_Init(void)
{
MSDC_Events = kal_create_event_group("MSDC Events");
DRV_Register_HISR(DRV_MSDC_HISR_ID, MSDC_HISR_Entry);
IRQ_Register_LISR(IRQ_MSDC_CODE, MSDC_LISR,"MSDC ISR");
IRQSensitivity(IRQ_MSDC_CODE,LEVEL_SENSITIVE);
IRQUnmask(IRQ_MSDC_CODE);
// enable MSDC interrupt
MSDC_CLR_INT();
#if !defined(MSDC_USE_INT)
MSDC_DISABLE_INT();// (active)turn off other interrupt event except pin interrupt
#else
MSDC_ENABLE_INT();// (deactive)
#endif
#ifdef USE_INT26_CARD_DETECTION
// for card detection
IRQ_Register_LISR(IRQ_MSDC_CD_CODE, MSDC_CardDetect_LISR,"MSDC CD ISR");
IRQSensitivity(IRQ_MSDC_CD_CODE,EDGE_SENSITIVE);
IRQUnmask(IRQ_MSDC_CD_CODE);
#if !defined(MSDC_USE_INT)
IRQMask(IRQ_MSDC_CODE);
#endif
#endif //USE_INT26_CARD_DETECTION
}
void MSDC_LISR(void)
{
IRQMask(IRQ_MSDC_CODE);
drv_active_hisr(DRV_MSDC_HISR_ID);
}
/*************************************************************************
* FUNCTION
* MSDC_HISR_Entry
*
* DESCRIPTION
* Set corresponding enevt and wake up waiting task.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_HISR_Entry(void)
{
register kal_uint16 msdc_int = 0;
#if defined(__MSDC_MS__)||defined(__MSDC_MSPRO__)
kal_uint16 msc_sta;
#if defined (USE_INT26_CARD_DETECTION)
if(gMSDC_Handle.mIsChanged == KAL_TRUE)
{
static kal_bool pre_IsPresent = KAL_TRUE; // it works only at first time
if(pre_IsPresent)
pre_IsPresent = gMSDC_Handle.mIsPresent;
#if defined(MSDC_USE_INT)
kal_set_eg_events(MSDC_Events,
(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
KAL_OR);
#endif
TurnOnMSDC();
if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_FALSE;
else
gMSDC_Handle.mIsPresent = KAL_TRUE;
}
else
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_TRUE;
else
gMSDC_Handle.mIsPresent = KAL_FALSE;
}
// use INT26 as the card detection, if the card is present during power on, then the
// card detection interrup of INT26 will always generated. This interrupt should be ignored.
if(pre_IsPresent && gMSDC_Handle.mIsPresent && gMSDC_Handle.mIsInitialized )
{
pre_IsPresent = KAL_FALSE;
gMSDC_Handle.mIsInitialized = KAL_TRUE;
IRQUnmask(IRQ_MSDC_CD_CODE);
return;
}
else
gMSDC_Handle.mIsInitialized = KAL_FALSE;
if(gMSDC_Handle.mIsPresent == KAL_FALSE)
{
MSDC_CLR_FIFO();
MSDC_CLR_INT();
MSDC_CLR_INT();
//TurnOffMSDC();
DMA_Stop(msdc_dmaport);
}
#if !defined(FMT_NOT_PRESENT)
MSDC_SendCardInd(MOD_FMT);
#endif
IRQUnmask(IRQ_MSDC_CD_CODE);
return;
}
#endif //USE_INT26_CARD_DETECTION
TurnOnMSDC();
msc_sta = *(volatile kal_uint16*)MSC_STA;
if(msc_sta & MSC_STA_SIF)
kal_set_eg_events(MSDC_Events,EVENT_MSIFIRQ,KAL_OR);
else
kal_set_eg_events(MSDC_Events,EVENT_MSRDYIRQ,KAL_OR);
msdc_int = *(volatile kal_uint16*)MSDC_INTR;
#if !defined(USE_INT26_CARD_DETECTION)
if(msdc_int & MSDC_INT_PINIRQ)
{
gMSDC_Handle.mIsInitialized = KAL_FALSE;
gMSDC_Handle.mIsChanged = KAL_TRUE;
kal_set_eg_events(MSDC_Events,
(EVENT_MSIFIRQ|EVENT_DMAIRQ|EVENT_MSRDYIRQ),
KAL_OR);
if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_FALSE;
else
gMSDC_Handle.mIsPresent = KAL_TRUE;
}
else
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_TRUE;
else
gMSDC_Handle.mIsPresent = KAL_FALSE;
}
if(gMSDC_Handle.mIsPresent == KAL_FALSE)
{
MSDC_CLR_FIFO();
MSDC_CLR_INT();
MSDC_CLR_INT();
//TurnOffMSDC();
DMA_Stop(msdc_dmaport);
} //dbg_print("MSDC_HISR present %d \r\n",gMSDC_Handle.mIsPresent);
#if !defined(FMT_NOT_PRESENT)
MSDC_SendCardInd(MOD_FMT);
#endif
//MSDC_PDNControl(KAL_TRUE);
}
#endif //USE_INT26_CARD_DETECTION
#else // sd/mmc
#if defined (USE_INT26_CARD_DETECTION)
if(gMSDC_Handle.mIsChanged == KAL_TRUE)
{
static kal_bool pre_IsPresent = KAL_TRUE; // it works only at first time
if(pre_IsPresent)
pre_IsPresent = gMSDC_Handle.mIsPresent;
#if defined(MSDC_USE_INT)
kal_set_eg_events(MSDC_Events,
(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
KAL_OR);
#endif
TurnOnMSDC();
if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_FALSE;
else
gMSDC_Handle.mIsPresent = KAL_TRUE;
}
else
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_TRUE;
else
gMSDC_Handle.mIsPresent = KAL_FALSE;
}
// use INT26 as the card detection, if the card is present during power on, then the
// card detection interrup of INT26 will always generated. This interrupt should be ignored.
if(pre_IsPresent && gMSDC_Handle.mIsPresent && gMSDC_Handle.mIsInitialized )
{
pre_IsPresent = KAL_FALSE;
gMSDC_Handle.mIsInitialized = KAL_TRUE;
IRQUnmask(IRQ_MSDC_CD_CODE);
return;
}
else
gMSDC_Handle.mIsInitialized = KAL_FALSE;
if(gMSDC_Handle.mIsPresent == KAL_FALSE)
{
MSDC_CLR_FIFO();
MSDC_CLR_INT();
MSDC_CLR_INT();
//TurnOffMSDC();
DMA_Stop(msdc_dmaport);
}
#if !defined(FMT_NOT_PRESENT)
MSDC_SendCardInd(MOD_FMT);
#endif
IRQUnmask(IRQ_MSDC_CD_CODE);
return;
}
#endif //USE_INT26_CARD_DETECTION
TurnOnMSDC();
msdc_int = *(volatile kal_uint16*)MSDC_INTR;
#if defined(MSDC_USE_INT)
if(msdc_int & MSDC_INT_SDCMDIRQ)
{
kal_set_eg_events(MSDC_Events,EVENT_SDCMDIRQ,KAL_OR);
}
if(msdc_int & MSDC_INT_SDDATIRQ)
{
kal_set_eg_events(MSDC_Events,EVENT_SDDATIRQ,KAL_OR);
}
if(msdc_int & MSDC_INT_SDMCIRQ)
{
kal_set_eg_events(MSDC_Events,EVENT_SDMCIRQ,KAL_OR);
}
if(msdc_int & MSDC_INT_SDR1BIRQ)
{
kal_set_eg_events(MSDC_Events,EVENT_SDR1BIRQ,KAL_OR);
}
#endif // MSDC_USE_INT
#if defined(__MSDC_SD_MMC__)&&defined(__MSDC_SD_SDIO__)
/*SDIO*/
if(msdc_int & MSDC_INT_SDIOIRQ)
{
SDIO_HISR_Entry();
}
#endif
#if !defined(USE_INT26_CARD_DETECTION)
if(msdc_int & MSDC_INT_PINIRQ)
{
gMSDC_Handle.mIsInitialized = KAL_FALSE;
gMSDC_Handle.mIsChanged = KAL_TRUE;
#if defined(MSDC_USE_INT)
kal_set_eg_events(MSDC_Events,
(EVENT_SDCMDIRQ|EVENT_SDDATIRQ|EVENT_SDMCIRQ|EVENT_SDR1BIRQ|EVENT_DMAIRQ),
KAL_OR);
#endif
if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0)
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_FALSE;
else
gMSDC_Handle.mIsPresent = KAL_TRUE;
}
else
{
if(gMSDC_Handle.ins_level == MSDC_IOCTRL_PULL_UP)
gMSDC_Handle.mIsPresent = KAL_TRUE;
else
gMSDC_Handle.mIsPresent = KAL_FALSE;
}
if(gMSDC_Handle.mIsPresent == KAL_FALSE)
{
MSDC_CLR_FIFO();
MSDC_CLR_INT();
MSDC_CLR_INT();
//TurnOffMSDC();
DMA_Stop(msdc_dmaport);
}
#if !defined(FMT_NOT_PRESENT)
MSDC_SendCardInd(MOD_FMT);
#endif
// Set the power down bit too fast will cause MSDC failed to detect next card plug in/out
// So, move it to GetCardStatus
//MSDC_PDNControl(KAL_TRUE);
}
#endif // USE_INT26_CARD_DETECTION
#endif // MSDC_MS
IRQUnmask(IRQ_MSDC_CODE);
}
/*************************************************************************
* FUNCTION
* MSDC_DMA_Callback
*
* DESCRIPTION
* Call back while DMA has done the data transfer.
*
* PARAMETERS
*
* RETURNS
*
* GLOBALS AFFECTED
*
*
*************************************************************************/
void MSDC_DMA_Callback(void)
{
kal_set_eg_events(MSDC_Events,EVENT_DMAIRQ,KAL_OR);
}
#endif //end of MSDC_INT
#endif // end of (defined(__MSDC_MS__) || defined(__MSDC_SD_MMC__))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -