接下来我们来看看CSDIOControllerBase的继承类CSDIOController,实现在sdiocontroller.cpp.这个类的对象在SDH_Init中通过调用CreateSDIOController来创建其对象,这个函数也在sdiocontroller.cpp中实现:
- CSDIOControllerBase* CreateSDIOController( PSDCARD_HC_CONTEXT pHCContext )
- {
- return new CSDIOController( pHCContext );
- }
CSDIOController实现了CSDIOControllerBase中定义的几个纯虚函数:
virtual BOOL InitializeHardware( BOOL bOnPowerUp = FALSE ) = 0;
virtual void DeinitializeHardware( BOOL bOnPowerDown = FALSE ) = 0;
virtual BOOL CustomSetup( LPCTSTR pszRegistryPath ) = 0;
virtual BOOL IsCardWriteProtected() = 0;
virtual BOOL IsCardPresent() = 0;
这些函数定义了与实际硬件平台相关的一些代码,当硬件发生变化时,只需要修改和硬件相关的代码就可以了.
1.CustomSetup
CustomSetup被基类的InterpretCapabilities函数调用,和InterpretCapabilities一样,CustomSetup主要工作也是从注册表中获取信息.如CardDetect,CardReadWrite的信息,比如是哪个GPIO寄存器,相应的掩码和具体的值等.这些信息被以下几个函数用到.
- BOOL CSDIOController::CustomSetup( LPCTSTR pszRegistryPath )
- {
- BOOL fRetVal = TRUE;
- CReg regDevice; // encapsulated device key
- HKEY hKeyDevice = OpenDeviceKey(pszRegistryPath);
- if ( (hKeyDevice == NULL) || !regDevice.Open(hKeyDevice, NULL) ) {
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CSDIOControllerBase::InterpretCapabilities: Failed to open device key/n")));
- fRetVal = FALSE;
- goto FUNCTION_EXIT;
- }
- // read the card detect GPIO settings
- LPCTSTR pszCardDetectGPIO = regDevice.ValueSZ( CARD_DETECT_GPIO_TEXT );
- if( pszCardDetectGPIO && pszCardDetectGPIO[0] >= TEXT('a') && pszCardDetectGPIO[0] <= TEXT('h') )
- {
- m_chCardDetectGPIO = (char)pszCardDetectGPIO[0] - ('a'-'A');
- }
- else if( pszCardDetectGPIO && pszCardDetectGPIO[0] >= TEXT('A') && pszCardDetectGPIO[0] <= TEXT('H') )
- {
- m_chCardDetectGPIO = (char)pszCardDetectGPIO[0];
- }
- else
- {
- // invalid SDIO SYSINTR value!
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO SYSINTR value!/n")));
- fRetVal = FALSE;
- goto FUNCTION_EXIT;
- }
- m_dwCardDetectMask = regDevice.ValueDW( CARD_DETECT_MASK_TEXT );
- m_dwCardDetectFlag = regDevice.ValueDW( CARD_DETECT_FLAG_TEXT );
- m_dwCardDetectControlMask = regDevice.ValueDW( CARD_DETECT_CONTROL_MASK_TEXT );
- m_dwCardDetectControlFlag = regDevice.ValueDW( CARD_DETECT_CONTROL_FLAG_TEXT );
- m_dwCardDetectPullupMask = regDevice.ValueDW( CARD_DETECT_PULLUP_MASK_TEXT );
- m_dwCardDetectPullupFlag = regDevice.ValueDW( CARD_DETECT_PULLUP_FLAG_TEXT );
- // read the card read/write GPIO settings
- LPCTSTR pszCardReadWriteGPIO = regDevice.ValueSZ( CARD_READWRITE_GPIO_TEXT );
- if( pszCardReadWriteGPIO && pszCardReadWriteGPIO[0] >= TEXT('a') && pszCardReadWriteGPIO[0] <= TEXT('h') )
- {
- m_chCardReadWriteGPIO = (char)pszCardReadWriteGPIO[0] - ('a'-'A');
- }
- else if( pszCardReadWriteGPIO || pszCardReadWriteGPIO[0] >= TEXT('A') && pszCardReadWriteGPIO[0] <= TEXT('H') )
- {
- m_chCardReadWriteGPIO = (char)pszCardReadWriteGPIO[0];
- }
- else
- {
- // invalid SDIO SYSINTR value!
- DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("invalid SDIO SYSINTR value!/n")));
- if (hKeyDevice) RegCloseKey(hKeyDevice);
- fRetVal = FALSE;
- goto FUNCTION_EXIT;
- }
- m_dwCardReadWriteMask = regDevice.ValueDW( CARD_READWRITE_MASK_TEXT );
- m_dwCardReadWriteFlag = regDevice.ValueDW( CARD_READWRITE_FLAG_TEXT );
- m_dwCardReadWriteControlMask = regDevice.ValueDW( CARD_READWRITE_CONTROL_MASK_TEXT );
- m_dwCardReadWriteControlFlag = regDevice.ValueDW( CARD_READWRITE_CONTROL_FLAG_TEXT );
- m_dwCardReadWritePullupMask = regDevice.ValueDW( CARD_READWRITE_PULLUP_MASK_TEXT );
- m_dwCardReadWritePullupFlag = regDevice.ValueDW( CARD_READWRITE_PULLUP_FLAG_TEXT );
- FUNCTION_EXIT:
- if (hKeyDevice) RegCloseKey(hKeyDevice);
- return fRetVal;
- }
2.InitializeHardware
InitializeHardware被基类的Initialize函数调用.
根据具体的GPIO(读写检测m_chCardReadWriteGPIO,这里是GPH8,插入检测m_chCardDetectGPIO,这里是GPG10)来对相应的GPIO寄存器进行初始化(如GPACON或者GPBCON等).根据以下变量的值来进行设置,这些变量从注册表中获得(CustomSetup函数中进行).m_dwCardReadWriteControlMask,m_dwCardReadWriteControlFlag,m_dwCardDetectControlMask,m_dwCardDetectControlFlag
- BOOL CSDIOController::InitializeHardware( BOOL bOnPowerUp )
- {
- // Configure GPIO pin to detect WRITE-PROTECT status
- RETAILMSG(1, (TEXT("++CSDIOController::InitializeHardware for GEC2410 SDHC/r/n")));
- switch( m_chCardReadWriteGPIO )
- {
- case 'A':
- vm_pIOPreg->GPACON = ( vm_pIOPreg->GPACON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- break;
- case 'B':
- vm_pIOPreg->GPBCON = ( vm_pIOPreg->GPBCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPBUP = ( vm_pIOPreg->GPBUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'C':
- vm_pIOPreg->GPCCON = ( vm_pIOPreg->GPCCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPCUP = ( vm_pIOPreg->GPCUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'D':
- vm_pIOPreg->GPDCON = ( vm_pIOPreg->GPDCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPDUP = ( vm_pIOPreg->GPDUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'E':
- vm_pIOPreg->GPECON = ( vm_pIOPreg->GPECON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPEUP = ( vm_pIOPreg->GPEUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'F':
- vm_pIOPreg->GPFCON = ( vm_pIOPreg->GPFCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPFUP = ( vm_pIOPreg->GPFUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'G':
- vm_pIOPreg->GPGCON = ( vm_pIOPreg->GPGCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPGUP = ( vm_pIOPreg->GPGUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- case 'H':
- vm_pIOPreg->GPHCON = ( vm_pIOPreg->GPHCON & m_dwCardReadWriteControlMask ) | m_dwCardReadWriteControlFlag;
- vm_pIOPreg->GPHUP = ( vm_pIOPreg->GPHUP & m_dwCardReadWritePullupMask ) | m_dwCardReadWritePullupFlag;
- break;
- default:
- ASSERT(0); // invalid GPIO! We should never get here!
- return FALSE;
- }
- // Configure GPIO pin to detect CARD PRESENT status
- switch( m_chCardDetectGPIO )
- {
- case 'A':
- vm_pIOPreg->GPACON = ( vm_pIOPreg->GPACON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- break;
- case 'B':
- vm_pIOPreg->GPBCON = ( vm_pIOPreg->GPBCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPBUP = ( vm_pIOPreg->GPBUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'C':
- vm_pIOPreg->GPCCON = ( vm_pIOPreg->GPCCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPCUP = ( vm_pIOPreg->GPCUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'D':
- vm_pIOPreg->GPDCON = ( vm_pIOPreg->GPDCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPDUP = ( vm_pIOPreg->GPDUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'E':
- vm_pIOPreg->GPECON = ( vm_pIOPreg->GPECON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPEUP = ( vm_pIOPreg->GPEUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'F':
- vm_pIOPreg->GPFCON = ( vm_pIOPreg->GPFCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPFUP = ( vm_pIOPreg->GPFUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'G':
- vm_pIOPreg->GPGCON = ( vm_pIOPreg->GPGCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPGUP = ( vm_pIOPreg->GPGUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- case 'H':
- vm_pIOPreg->GPHCON = ( vm_pIOPreg->GPHCON & m_dwCardDetectControlMask ) | m_dwCardDetectControlFlag;
- vm_pIOPreg->GPHUP = ( vm_pIOPreg->GPHUP & m_dwCardDetectPullupMask ) | m_dwCardDetectPullupFlag;
- break;
- default:
- ASSERT(0); // invalid GPIO! We should never get here!
- return FALSE;
- }
- return TRUE;
- }
3.DeinitializeHardware
未做任何工作
4.IsCardWriteProtected
在SlotOptionHandler中被调用,给PSD_CARD_INTERFACE结构的WriteProtected成员赋值,判断SD卡是否写保护,通过判断对应的GPHDAT寄存器m_dwCardReadWriteMask位(GPH8)与m_dwCardReadWriteFlag进行比较判断.
- BOOL CSDIOController::IsCardWriteProtected()
- {
- switch( m_chCardReadWriteGPIO )
- {
- case 'A':
- return ( ( vm_pIOPreg->GPADAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'B':
- return ( ( vm_pIOPreg->GPBDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'C':
- return ( ( vm_pIOPreg->GPCDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'D':
- return ( ( vm_pIOPreg->GPDDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'E':
- return ( ( vm_pIOPreg->GPEDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'F':
- return ( ( vm_pIOPreg->GPFDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'G':
- return ( ( vm_pIOPreg->GPGDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- case 'H':
- return ( ( vm_pIOPreg->GPHDAT & m_dwCardReadWriteMask ) == m_dwCardReadWriteFlag ) ? TRUE : FALSE;
- default:
- ASSERT(0); // invalid GPIO! We should never get here
- return TRUE;
- }
- }
5.IsCardPresent
判断SD卡是否存在,这个函数被基类的很多函数调用,如TransferIstThread等,很多操作都要先判断SD卡是否存在,然后在进行下面的操作.
通过判断GPG10状态来获得.
- BOOL CSDIOController::IsCardPresent()
- {
- switch( m_chCardDetectGPIO )
- {
- case 'A':
- return ( ( vm_pIOPreg->GPADAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'B':
- return ( ( vm_pIOPreg->GPBDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'C':
- return ( ( vm_pIOPreg->GPCDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'D':
- return ( ( vm_pIOPreg->GPDDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'E':
- return ( ( vm_pIOPreg->GPEDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'F':
- return ( ( vm_pIOPreg->GPFDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'G':
- return ( ( vm_pIOPreg->GPGDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- case 'H':
- return ( ( vm_pIOPreg->GPHDAT & m_dwCardDetectMask ) == m_dwCardDetectFlag ) ? TRUE : FALSE;
- default:
- ASSERT(0); // invalid GPIO! We should never get here
- }
- return (vm_pIOPreg->GPGDAT & (1<<10)) ? FALSE : TRUE;
- }
另外附上注册表sdhc_sc2410.reg的内容:
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/SDHC_SMDK2410]
"Order"=dword:21
"Dll"="sdhc_smdk2410.dll"
"Prefix"="SDH"
"DMAChannel"=dword:0 ; DMA channel to use. Set to 0xffffffff to disable DMA
"DMAIrq"=dword:11
"DMA_IST_Priority"=dword:96
"SDIOIrq"=dword:15
"SDIO_IST_Priority"=dword:97
"PollingTimeout"=dword:100 ; 100 ms
"CardDetect_Thread_Priority"=dword:98
"CardDetectGPIO"="G" ; card detect on GPG10
"CardDetectMask"=dword:400
"CardDetectFlag"=dword:0
"CardDetectControlMask"=dword:fffcffff
"CardDetectControlFlag"=dword:0
"CardDetectPullupMask"=dword:ffffffef
"CardDetectPullupFlag"=dword:10
"CardReadWriteGPIO"="H" ; card R/W on GPH8
"CardReadWriteMask"=dword:100
"CardReadWriteFlag"=dword:100
"CardReadWriteControlMask"=dword:ffcfffff
"CardReadWriteControlFlag"=dword:0
"CardReadWritePullupMask"=dword:ffffffbf
"CardReadWritePullupFlag"=dword:40
"HandleBusyFinishOnCommand38"=dword:1
"DmaTransferTimeoutFactor"=dword:8
"DmaTransferTimeoutConstant"=dword:3000