📄 sdhc_s3c2450_ch1.cpp
字号:
volatile S3C2450_CLKPWR_REG *pCLKPWR = NULL;
pCLKPWR = (volatile S3C2450_CLKPWR_REG *)VirtualAlloc(0, sizeof(S3C2450_CLKPWR_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pCLKPWR == NULL) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] Clock & Power Management Special Register is *NOT* allocated.\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)pCLKPWR, (PVOID)(S3C2450_BASE_REG_PA_CLOCK_POWER >> 8),
sizeof(S3C2450_CLKPWR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] Clock & Power Management Special Register is *NOT* mapped.\n")));
return FALSE;
}
RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the EPLL (for SDCLK) : SYSCon.\n")));
pCLKPWR->CLKSRC |= (0x0<<17); // HSMMC1 clock: 0 = EPLL, 1 = USB 48MHz
pCLKPWR->HCLKCON |= (0x1<<16); // Enable HCLK into the HSMMC1
pCLKPWR->SCLKCON |= (0x0<<13); // Disable HSMMC_EXT clock for HSMMC 0,1 (EXTCLK)
pCLKPWR->SCLKCON |= (0x1<<12); // Enable HSMMC_1 clock for (EPLL/USB48M)
VirtualFree((PVOID) pCLKPWR, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitGPIO() {
volatile S3C2450_IOPORT_REG *pIOPreg = NULL;
pIOPreg = (volatile S3C2450_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2450_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pIOPreg == NULL) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] GPIO registers is *NOT* allocated.\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)pIOPreg, (PVOID)(S3C2450_BASE_REG_PA_IOPORT >> 8),
sizeof(S3C2450_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] GPIO registers is *NOT* mapped.\n")));
return FALSE;
}
RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the GPIO.\n")));
pIOPreg->GPLCON &= ~(0xF<<16);
pIOPreg->GPLCON |= (0xA<<16); // SD1_CLK, SD0_CMD
pIOPreg->GPLUDP &= ~(0xF<<16); // pull-up/down disable
pIOPreg->GPLCON &= ~(0xFF);
pIOPreg->GPLCON |= (0xAA); // SD1_DAT[3:0]
pIOPreg->GPLUDP &= ~(0xFF); // pull-up/down disable
#ifdef _SMDK2450_CH1_EXTCD_
// 08.04.04 by KYS
// Setting for card detect pin of HSMMC ch0 on SMDK2450.
pIOPreg->GPFCON = ( pIOPreg->GPFCON & ~(0x3<<2) ) | (0x2<<2); // SD_CD1 by EINT1(GPF1)
pIOPreg->GPFUDP = ( pIOPreg->GPFUDP & ~(0x3<<2) ) | (0x0<<2); // pull-up/down disabled
pIOPreg->EXTINT0 = ( pIOPreg->EXTINT0 & ~(0xF<<4) ) | (0x6<<4); // 4b'0110 : Filter Enable, Both edge triggered
#endif
#ifdef _SMDK2450_CH1_WP_
// This code is pseudo except SMDK2450 using GPJ15 as WriteProtection!!
// so, in other case, this code need to modify.
pIOPreg->GPJCON &= ~(0x3 << 30); // nSD1_WP(input in case of SMDK2450)
pIOPreg->GPJUDP &= ~(0x3 << 30); // pull-up/down disable
#endif
VirtualFree((PVOID) pIOPreg, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitHSMMC() {
volatile S3C2450_HSMMC_REG *pHSMMC = NULL;
pHSMMC = (volatile S3C2450_HSMMC_REG *)VirtualAlloc(0, sizeof(S3C2450_HSMMC_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pHSMMC == NULL)
{
RETAILMSG(_DBG_,(TEXT("[HSMMC1] HSMMC Special Register is *NOT* allocated.\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)pHSMMC, (PVOID)(S3C2450_BASE_REG_PA_HSMMC1 >> 8),
sizeof(S3C2450_HSMMC_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] HSMMC Special Register is *NOT* mapped.\n")));
return FALSE;
}
RETAILMSG(_DBG_, (TEXT("[HSMMC1] Setting registers for the EPLL : HSMMCCon.\n")));
pHSMMC->CONTROL2 = (pHSMMC->CONTROL2 & ~(0xffffffff)) | // clear all
(0x1<<15) | // enable Feedback clock for Tx Data/Command Clock
(0x1<<14) | // enable Feedback clock for Rx Data/Command Clock
(0x3<<9) | // Debounce Filter Count 0x3=64 iSDCLK
(0x1<<8) | // SDCLK Hold Enable
(0x2<<4); // Base Clock Source = EPLL (from SYSCON block)
pHSMMC->CONTROL3 = (0<<31) | (1<<23) | (0<<15) | (1<<7); // controlling the Feedback Clock
VirtualFree((PVOID) pHSMMC, 0, MEM_RELEASE);
return TRUE;
}
BOOL CSDHController::InitCh() {
if (!InitClkPwr()) return FALSE;
if (!InitGPIO()) return FALSE;
if (!InitHSMMC()) return FALSE;
return TRUE;
}
#ifdef _SMDK2450_CH1_EXTCD_
// 08.04.04 by KYS
// New function to Card detect thread of HSMMC ch0 on SMDK2450.
DWORD CSDHController::CardDetectThread() {
BOOL bSlotStateChanged = FALSE;
DWORD dwWaitResult = WAIT_TIMEOUT;
PCSDHCSlotBase pSlotZero = GetSlot(0);
CeSetThreadPriority(GetCurrentThread(), 100);
while(1) {
// Wait for the next insertion/removal interrupt
dwWaitResult = WaitForSingleObject(m_hevCardDetectEvent, INFINITE);
Lock();
pSlotZero->HandleInterrupt(SDSLOT_INT_CARD_DETECTED);
Unlock();
InterruptDone(m_dwSDDetectSysIntr);
EnableCardDetectInterrupt();
}
return TRUE;
}
// 08.04.04 by KYS
// New function to request a SYSINTR for Card detect interrupt of HSMMC ch1 on SMDK2450.
BOOL CSDHController::InitializeHardware() {
m_dwSDDetectIrq = SD_CD1_IRQ;
// convert the SDI hardware IRQ into a logical SYSINTR value
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &m_dwSDDetectIrq, sizeof(DWORD), &m_dwSDDetectSysIntr, sizeof(DWORD), NULL)) {
// invalid SDDetect SYSINTR value!
RETAILMSG(1, (TEXT("[HSMMC1] invalid SD detect SYSINTR value!\n")));
m_dwSDDetectSysIntr = SYSINTR_UNDEFINED;
return FALSE;
}
return CSDHCBase::InitializeHardware();
}
// 08.04.04 by KYS
// New Start function for Card detect of HSMMC ch0 on SMDK2450.
SD_API_STATUS CSDHController::Start() {
SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
m_fDriverShutdown = FALSE;
// allocate the interrupt event
m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == m_hevInterrupt) {
goto EXIT;
}
// initialize the interrupt event
if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) {
goto EXIT;
}
m_fInterruptInitialized = TRUE;
// create the interrupt thread for controller interrupts
m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL);
if (NULL == m_htIST) {
goto EXIT;
}
// allocate the card detect event
m_hevCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == m_hevCardDetectEvent) {
goto EXIT;
}
// initialize the interrupt event
if (!InterruptInitialize (m_dwSDDetectSysIntr, m_hevCardDetectEvent, NULL, 0)) {
goto EXIT;
}
// create the card detect interrupt thread
m_htCardDetectThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SD_CardDetectThread, this, 0, NULL);
if (NULL == m_htCardDetectThread) {
goto EXIT;
}
for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) {
PCSDHCSlotBase pSlot = GetSlot(dwSlot);
status = pSlot->Start();
if (!SD_API_SUCCESS(status)) {
goto EXIT;
}
}
// wake up the interrupt thread to check the slot
::SetInterruptEvent(m_dwSDDetectSysIntr);
status = SD_API_STATUS_SUCCESS;
EXIT:
if (!SD_API_SUCCESS(status)) {
// Clean up
Stop();
}
return status;
}
// 08.04.04 by KYS
// New function for enabling the Card detect interrupt of HSMMC ch0 on SMDK2450.
BOOL CSDHController::EnableCardDetectInterrupt() {
volatile S3C2450_INTR_REG *pINTRreg = NULL;
pINTRreg = (volatile S3C2450_INTR_REG *)VirtualAlloc(0, sizeof(S3C2450_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
if (pINTRreg == NULL) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] INTR registers is *NOT* allocated.\n")));
return FALSE;
}
if (!VirtualCopy((PVOID)pINTRreg, (PVOID)(S3C2450_BASE_REG_PA_INTR >> 8),
sizeof(S3C2450_INTR_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(_DBG_,(TEXT("[HSMMC1] INTR registers is *NOT* mapped.\n")));
return FALSE;
}
pINTRreg->INTPND1 = ( pINTRreg->INTPND1 | (0x1<<1)); //clear EINT1 pending bit
pINTRreg->INTMSK1 = ( pINTRreg->INTMSK1 & ~(0x1<<1)); //enable EINT1
VirtualFree((PVOID)pINTRreg, 0, MEM_RELEASE);
return TRUE;
}
#endif
#endif // !(BSP_TYPE == BSP_SMDK2443)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -