?? sdmmcloader.c
字號:
/****************************************Copyright (c)**************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: SDMMCLoader.c
** Last modified Date: 2006-10-09
** Last Version: V1.0
** Description: Windows CE S3C2410 SD/MMC卡插入/撥出驅動
** 插入時, 加載SD/MMC卡驅動, 撥出時, 卸載 SD/MMC 卡驅動
**------------------------------------------------------------------------------------------------------
** Created By: MingYuan Zheng 鄭明遠
** Created date: 2006-10-09
** Version: V1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#include <windows.h>
#include <types.h>
#include <excpt.h>
#include <tchar.h>
#include <cardserv.h>
#include <cardapi.h>
#include <tuple.h>
#include <devload.h>
#include <diskio.h>
#include <nkintr.h>
#include <windev.h>
#include <Pkfuncs.h>
#include <s3c2410x.h>
// 全局變量
HANDLE hSDEvent;
void InitializeHardware(void);
HANDLE gSDMMCDetectThread; /* 檢測線程句柄 */
HANDLE gSDMMCIntrEvent; /* 中斷事件 */
HANDLE hDevice = NULL;
static BOOL SDMMC_DETECT = 0; /* 卡原來是否已經插入,*/
UINT32 g_CardInsertIrq = IRQ_EINT18; /* 使用EINT18作為卡插入與否檢測線 */
UINT32 g_CardInsertSysIntr = SYSINTR_UNDEFINED;
static volatile S3C2410X_IOPORT_REG * v_pIOPregs;
/*******************************************************************************************
函數名稱: SDMMCLoader_InitializeAddresses
描 述: 獲取 GPIO 寄存器的虛擬空間
輸入參數: 無
輸出參數: 無
返 回: 驅動程序引用事例句柄
*******************************************************************************************/
static BOOL SDMMCLoader_InitializeAddresses(VOID)
{
BOOL RetValue = TRUE;
RETAILMSG(1, (TEXT("::: SDMMCLoader Initialize address..set..\r\n")));
/* IO Register Allocation */
v_pIOPregs = (volatile S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
ERRORMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
ERRORMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
RETAILMSG (1, (TEXT("::: PBT_InitializeAddresses - Fail!!\r\n") ));
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
}
else
RETAILMSG (1, (TEXT("::: SDMMCLoader_InitializeAddresses - Success\r\n") ));
return(RetValue);
}
/*******************************************************************************************
函數名稱: InitializeHardware
描 述: 初始化硬件: 設置 GP10 為 EINT18, 并且中斷為雙邊沿觸發
輸入參數: 無
輸出參數: 無
返 回: 無
*******************************************************************************************/
void InitializeHardware(void)
{
v_pIOPregs->GPGCON &= ~(0x03 << 20);
v_pIOPregs->GPGCON |= (0x02 << 20); /* GPG10 is Interrupt Pin (EINT18) */
v_pIOPregs->GPGUP &= ~(1<<10); /* enable pull up */
v_pIOPregs->EXTINT2 &= ~(0x7 << 8); /* Configure EINT18 as Falling Edge Mode */
v_pIOPregs->EXTINT2 |= (0x6 << 8);
}
/*******************************************************************************************
函數名稱: SDMMCDetectThread
描 述: 卡是否插入檢測線程
輸入參數: LPVOID pArgument: 線程輸入參數
輸出參數: 無
返 回: 1: 沒有特別含義
*******************************************************************************************/
WCHAR *szRegKey_SDMMC = L"Drivers\\SDCARD\\ClientDrivers\\Class\\SDMemory_Class";
static DWORD WINAPI SDMMCDetectThread(LPVOID pArgument)
{
RETAILMSG(1, (TEXT("Entering SDMMCDetectThread done.\r\n")));
Sleep (1000); // Same as CF driver, wait for 1 sencond to avoid data abort.
while(1)
{
Sleep(20);
if (((v_pIOPregs->GPGDAT & (0x01 << 10)) != 0) && (SDMMC_DETECT == 1))
{
RETAILMSG(1, (TEXT("INFO: SD/MMC Card is removed.\r\n")));
SDMMC_DETECT = 0;
InterruptDone(g_CardInsertSysIntr); /* 中斷結束 */
}
if ((SDMMC_DETECT == 0) && ((v_pIOPregs->GPGDAT & (0x01 << 10)) == 0))
{
RETAILMSG(1, (TEXT("INFO: SD/MMC Card is detected.\r\n")));
SDMMC_DETECT = 1;
hDevice = ActivateDeviceEx(szRegKey_SDMMC, NULL, 0, NULL); /* 加載SD/MMC卡驅動 */
InterruptDone(g_CardInsertSysIntr);
}
else
{
InterruptDone(g_CardInsertSysIntr);
}
WaitForSingleObject(hSDEvent, INFINITE); /* 等待卡的下一次插入/撥出事件 */
}
return 1;
}
/*******************************************************************************************
函數名稱: DllEntry
描 述: 驅動程序動態庫入口
輸入參數:
輸出參數:
返 回:
*******************************************************************************************/
BOOL WINAPI DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("SDMMCLoader: DLL_PROCESS_ATTACH\r\n")));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("SDMMCLoader: DLL_PROCESS_DETACH\r\n")));
break;
}
return (TRUE);
}
/*******************************************************************************************
函數名稱: IIC_Init
描 述: 驅動程序初始化函數
輸入參數: DWORD dwContext: 設備管理器傳遞給本驅動的參數, 通常為流接口驅動在注冊表內的位置
輸出參數: 無
返 回: 驅動程序句柄
*******************************************************************************************/
DWORD SML_Init(DWORD dwContext)
{
// 申請硬件寄存器虛擬空間
SDMMCLoader_InitializeAddresses();
// 初始化硬件
InitializeHardware();
// 創建卡插入事件
hSDEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if(!hSDEvent)
{
RETAILMSG( 1, (TEXT("SML_Init: CreateEvent hSDEvent failed, error = %x\r\n"), GetLastError()));
return FALSE;
}
// 向 OAL 層申請硬件中斷對應的邏輯中斷
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &g_CardInsertIrq, sizeof(UINT32), &g_CardInsertSysIntr, sizeof(UINT32), NULL))
{
RETAILMSG(1, (TEXT("ERROR: SDMMCLoader: Failed to request sysintr value for SDMMC Card Detect interrupt.\r\n")));
return(0);
}
RETAILMSG(1,(TEXT("INFO: SDMMCLoader: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_CardInsertIrq, g_CardInsertSysIntr));
// 綁定卡插入邏輯中斷到對應的事件
InterruptDone(g_CardInsertSysIntr);
InterruptDisable(g_CardInsertSysIntr);
if (!(InterruptInitialize(g_CardInsertSysIntr, hSDEvent, 0, 0)))
{
RETAILMSG(1, (TEXT("ERROR: SDMMCLoader: Interrupt initialize failed.\r\n")));
return FALSE;
}
// 創建卡插入檢測線程
gSDMMCDetectThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SDMMCDetectThread, NULL, 0, NULL);
if (gSDMMCDetectThread == NULL )
{
RETAILMSG(1, (TEXT("Fatal Error! Failed to create MMC card detect thread.\r\n")));
return (FALSE);
}
RETAILMSG(1, (TEXT(":::SML_Init Sucessfully.\r\n")));
return TRUE;
}
/*******************************************************************************************
函數名稱: SML_Open
描 述: 打開驅動程序
輸入參數: DWORD dwData : 設備驅動程序句柄
DWORD dwAccess : 訪問請求代碼,是讀和寫的組合
DWORD dwShareMode: 共享模式
輸出參數:
返 回: 驅動程序引用事例句柄
*******************************************************************************************/
DWORD SML_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
return 1;
}
/*******************************************************************************************
函數名稱: SML_Close
描 述: 驅動程序關閉函數
輸入參數: DWORD Handle:驅動程序句柄
輸出參數: 無
返 回: FALSE: 失敗 TRUE: 成功
*******************************************************************************************/
BOOL SML_Close(DWORD Handle)
{
return (TRUE);
}
/*******************************************************************************************
函數名稱: SML_Read
描 述:
輸入參數: DWORD Handle : 驅動程序引用事例句柄
LPVOID pBuffer : 接收緩沖區
DWORD dwNumBytes: 要讀的字節數
輸出參數: 無
返 回: 實際讀到字節數
*******************************************************************************************/
DWORD SML_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
return (0);
}
/*******************************************************************************************
函數名稱: SML_Write
描 述:
輸入參數:
輸出參數:
返 回: 成功發送的字節數
*******************************************************************************************/
DWORD SML_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
return (0);
}
/*******************************************************************************************
函數名稱: SML_Seek
描 述: 對設備的數據指針進行操作,本驅動不支持該函數
輸入參數:
輸出參數:
返 回:
*******************************************************************************************/
DWORD SML_Seek(DWORD Handle, long lDistance, DWORD dwMoveMethod)
{
return (DWORD)-1;
}
/*******************************************************************************************
函數名稱: SML_PowerUp
描 述: 電源下電驅動處理函數
輸入參數:
輸出參數:
返 回: 無
*******************************************************************************************/
VOID SML_PowerUp(VOID)
{
return;
}
/*******************************************************************************************
函數名稱: SML_PowerDown
描 述: 電源下電驅動處理函數
輸入參數:
輸出參數:
返 回: 無
*******************************************************************************************/
BOOL SML_PowerDown(VOID)
{
RETAILMSG (1, (TEXT("SMLoader Power down end...\r\n")));
return (TRUE);
}
/*******************************************************************************************
函數名稱: SML_Deinit
描 述: 驅動程序卸載函數
輸入參數: DWORD dwContext: 驅動程序句柄
輸出參數: 無
返 回: FALSE: 失敗 TRUE: 成功
*******************************************************************************************/
BOOL SML_Deinit(DWORD dwData)
{
return (TRUE);
}
/*******************************************************************************************
函數名稱: SML_IOControl
描 述: 驅動程序 I/O 請求
輸入參數:
輸出參數:
返 回: TRUE: 成功 FALSE: 失敗
*******************************************************************************************/
BOOL
SML_IOControl(
DWORD Handle,
DWORD dwIoControlCode,
PBYTE pInBuf,
DWORD nInBufSize,
PBYTE pOutBuf,
DWORD nOutBufSize,
PDWORD pBytesReturned
)
{
return (FALSE);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -