标准wince5.0 BSP之SD卡驱动分析
本来打算把SD卡驱动移植到俺的4.2BSP下的,但是发现太难了,还不如直接把以前的BSP丢弃。从长远着想,还是丢弃比较好,为了将来的KITL,必须丢弃那个古董4.2BSP。这次先不告诉我的计划先,自己做出来再告诉他们了。
还是老方法,首先看SD卡的注册表。
; @CESYSGEN IF CE_MODULES_SDBUS
IF BSP_SDHC_SC2440
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/SDHC_SMDK2440]
"Order"=dword:21
"Dll"="sdhc_sc2440.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 GPG8从电路图看这是EINT16,放心里面一定要注册表读取过程的。
"CardDetectMask"=dword:100 这个是什么?有什么用?
"CardDetectFlag"=dword:0 设置以何种方式检测SD插拔
"CardDetectControlMask"=dword:fffcffff
"CardDetectControlFlag"=dword:0
"CardDetectPullupMask"=dword:fffffeff
"CardDetectPullupFlag"=dword:100
"CardReadWriteGPIO"="H" ; card R/W on GPH8--我猜测以下部分没用到,因为俺们的SD卡根本没有写保护的
"CardReadWriteMask"=dword:100
"CardReadWriteFlag"=dword:100
"CardReadWriteControlMask"=dword:fffcffff
"CardReadWriteControlFlag"=dword:0
"CardReadWritePullupMask"=dword:fffffeff
"CardReadWritePullupFlag"=dword:100
"HandleBusyFinishOnCommand38"=dword:1
"DmaTransferTimeoutFactor"=dword:8
"DmaTransferTimeoutConstant"=dword:3000
ENDIF BSP_SDHC_SC2440
; @CESYSGEN ENDIF CE_MODULES_SDBUS
我用PB的Find in file 工具查找CardDetectGPIO,就找到上面注册表的奥妙。请看下面代码
1.注册表相关部分
- #define CARD_DETECT_GPIO_TEXT TEXT("CardDetectGPIO")
- #define CARD_DETECT_MASK_TEXT TEXT("CardDetectMask")
- #define CARD_DETECT_FLAG_TEXT TEXT("CardDetectFlag")
- #define CARD_DETECT_CONTROL_MASK_TEXT TEXT("CardDetectControlMask")
- #define CARD_DETECT_CONTROL_FLAG_TEXT TEXT("CardDetectControlFlag")
- #define CARD_DETECT_PULLUP_MASK_TEXT TEXT("CardDetectPullupMask")
- #define CARD_DETECT_PULLUP_FLAG_TEXT TEXT("CardDetectPullupFlag")
- #define CARD_READWRITE_GPIO_TEXT TEXT("CardReadWriteGPIO")
- #define CARD_READWRITE_MASK_TEXT TEXT("CardReadWriteMask")
- #define CARD_READWRITE_FLAG_TEXT TEXT("CardReadWriteFlag")
- #define CARD_READWRITE_CONTROL_MASK_TEXT TEXT("CardReadWriteControlMask")
- #define CARD_READWRITE_CONTROL_FLAG_TEXT TEXT("CardReadWriteControlFlag")
- #define CARD_READWRITE_PULLUP_MASK_TEXT TEXT("CardReadWritePullupMask")
- #define CARD_READWRITE_PULLUP_FLAG_TEXT TEXT("CardReadWritePullupFlag")
上面这些东西一看便知,就不做介绍了
2.看看是怎么读取注册表的
- 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/r/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!/r/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!/r/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;
- }
以上程序写得很安全,很明了,三星,支持你!
3.再往下看——初始化硬件了
- BOOL CSDIOController::InitializeHardware( BOOL bOnPowerUp )
- {
- // Configure GPIO pin to detect WRITE-PROTECT status
- 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;
- }
看了这些代码,啥都不想说了。——三星,难怪你的用户这么多!
4.下面是检测卡擦拔以及写保户之类的东西
- 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;
- }
- }
- 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;
- }
- //----------不知道下面这个函数有什么玄机
- CSDIOControllerBase* CreateSDIOController( PSDCARD_HC_CONTEXT pHCContext )
- {
- return new CSDIOController( pHCContext );
- }
以上源码均来自/Src/Drivers/SDHC/SDHC/sdiocontroller.cpp这个文件