/****************************************Copyright (c)**************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: gpio.c
** Last modified Date: 2006-10-09
** Last Version: V1.0
** Description: S3C2410 GPIO 驱动
**
**------------------------------------------------------------------------------------------------------
** 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 "s2440.h"
#include "gpio.h"
#define PRIVATE static
#define PUBLIC
/* GPIO 寄存器对应的虚拟地址 */
PRIVATE volatile IOPreg * v_pIOPregs;
PRIVATE g_OpenCount = 0; /* 驱动打开计数器 */
#define ADDRESS_INTERVAL_GPIO 0x04
#define GPx_GPA 0
/*******************************************************************************************
函数名称: PIO_InitializeAddresses
描 述: 取得相关寄存器的虚拟地址
输入参数: 无
输出参数: 无
返 回: > 0 分配到的虚拟地址; FALSE: 失败
*******************************************************************************************/
PRIVATE BOOL PIO_InitializeAddresses(void)
{
BOOL RetValue = TRUE;
// IO Register Allocation
//v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
v_pIOPregs = VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
if (v_pIOPregs == NULL)
{
RETAILMSG(1,(TEXT("For IOPregs : VirtualAlloc failed!\r\n")));
RetValue = FALSE;
}
else
{
if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE >> 8), sizeof(IOPreg), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
{
RETAILMSG(1,(TEXT("For IOPregs: VirtualCopy failed!\r\n")));
RetValue = FALSE;
}
}
if (!RetValue)
{
RETAILMSG (1, (TEXT("::: PIO_InitializeAddresses - Fail!!\r\n") ));
if (v_pIOPregs)
{
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
}
v_pIOPregs = NULL;
RetValue = FALSE;
return RetValue;
}
RETAILMSG (1,(TEXT("[GPIO] v_pIOPRegs is mapped to 0x%x\r\n"), v_pIOPregs));
return(RetValue);
}
/*******************************************************************************************
函数名称: PIO_Init
描 述: 驱动程序初始化函数
输入参数: DWORD dwContext: 设备管理器传递给本驱动的参数, 通常为流接口驱动在注册表内的位置
输出参数: 无
返 回: 驱动程序句柄
*******************************************************************************************/
PUBLIC DWORD PIO_Init(DWORD dwContext)
{
PIO_InitializeAddresses();
g_OpenCount = 0;
return (DWORD)1;
}
/*******************************************************************************************
函数名称: DllEntry
描 述: 驱动程序动态库入口
输入参数:
输出参数:
返 回:
*******************************************************************************************/
PUBLIC BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch ( dwReason )
{
case DLL_PROCESS_ATTACH:
RETAILMSG(1, (TEXT("PIO: DLL_PROCESS_ATTACH\r\n")));
DisableThreadLibraryCalls((HMODULE) hInstDll);
break;
case DLL_PROCESS_DETACH:
RETAILMSG(1, (TEXT("PIO: DLL_PROCESS_DETACH\r\n")));
break;
}
return (TRUE);
}
/*******************************************************************************************
函数名称: PIO_Close
描 述: 驱动程序关闭函数
输入参数: DWORD Handle:驱动程序引用事例句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL PIO_Close(DWORD Handle)
{
g_OpenCount = 0;
return TRUE;
}
/*******************************************************************************************
函数名称: PIO_Deinit
描 述: 驱动程序卸载函数
输入参数: DWORD dwContext: 驱动程序句柄
输出参数: 无
返 回: FALSE: 失败 TRUE: 成功
*******************************************************************************************/
BOOL PIO_Deinit(DWORD dwContext)
{
g_OpenCount = 0;
if (v_pIOPregs)
VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE); /* 释放申请的虚拟空间 */
return TRUE;
}
/*******************************************************************************************
函数名称: PIO_Open
描 述: 打开驱动程序
输入参数: DWORD dwData : 设备驱动程序句柄
DWORD dwAccess : 访问请求代码,是读和写的组合
DWORD dwShareMode: 共享模式
输出参数:
返 回: 驱动程序引用事例句柄
*******************************************************************************************/
DWORD PIO_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
if (g_OpenCount > 0)
return 0;
g_OpenCount++;
return g_OpenCount; /* 返回一个不为零的数 */
}
// 定义 S3C2410 GPA ~ GPH 引脚个数
// A B C D E F G H
const BYTE PinNumTbl[8] = {23, 11, 16, 16, 16, 8, 16, 11};
/*******************************************************************************************
函数名称: GPIO_SetPinOut
描 述: 设置某个引脚为输出引脚
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号, 如 GPB1, 则值为 1
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_SetPinOut(DWORD dwIoControlCode, BYTE PinNum)
{
DWORD GPx;
volatile DWORD *pRegCON; // GPxCON's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
if (PinNum >= PinNumTbl[GPx]) return FALSE;
pRegCON = (DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO;
if (GPx != GPx_GPA)
{
*pRegCON &= ~(0x03 << (PinNum * 2));
*pRegCON |= (0x01 << (PinNum * 2));
}
else
*pRegCON &= ~(0x01 << PinNum);
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_SetMultiPinOut
描 述: 设置多个引脚为输出引脚
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号掩码, 如操作 GPB1,GPB3, 则值为: (0x01 << 1) + (0x01 << 3)
输出参数:
返 回: TRUE: 操作成功 FALSE: 操作失败
*******************************************************************************************/
BOOL GPIO_SetMultiPinOut(DWORD dwIoControlCode, DWORD PinMask)
{
DWORD GPx, i;
volatile DWORD *pRegCON; // GPXCON's address
GPx = dwIoControlCode & IOCTL_GPX_MASK;
pRegCON = (DWORD *)v_pIOPregs + GPx * ADDRESS_INTERVAL_GPIO;
for (i = 0; i < PinNumTbl[GPx]; i++)
{
if (PinMask & (0x01 << i))
{
if (GPx != GPx_GPA)
{
*pRegCON &= ~(0x03 << (i * 2));
*pRegCON |= (0x01 << (i * 2));
}
else
*pRegCON &= ~(0x01 << i);
}
}
return TRUE;
}
/*******************************************************************************************
函数名称: GPIO_SetPinIn
描 述: 设置某个引脚为输入引脚
输入参数: DWORD dwIoControlCode : I/O control code, 指出操作的GPIO组, 如GPA, GPB
BYTE PinNum : 引脚编号, 如 GPB1, 则值为 1
输出参数:
返 回: TRUE: 操作成功 FALSE: �
评论0