1、PIO_OUTPUT_ENABLE和PIO_OUTPUT_DISABLE是控制输出和输入的;PIO_INT_ENABLE和PIO_INT_DISABLE是控制中断的触发类型。其中输入的状态在超级终端上可以打印出来。
2、对于 GPIO 的中断控制,如果有两个驱动控制,可能会发生冲突,从而导致失败。
1.1 oal 中断配置
在WINCE600\PLATFORM\NANO\SRC\INC\oemintr.h 中
#defineIRQ_CHARGEDONE (IRQ_TD1120 - 1)//61
#defineSYSINTR_CHARGEDONE (SYSINTR_TD1120 - 1)//66
在WINCE600\PLATFORM\NANO\SRC\OAL\OALLIB\intr.c
BOOLBSPIntrInit() 中,系统中断ID 与中断服务ID:
OALIntrStaticTranslate(SYSINTR_CHARGEDONE,IRQ_CHARGEDONE);
UINT32BSPIntrEnableIrq(UINT32 irq) 中,增加case:
caseIRQ_CHARGEDONE:
if(!OALGpioIntrIsRegisterd(GPIO_NUM(GPIO_GROUTP_CHARGEDONE_INT, GPIO_INDEX_CHARGEDONE_INT)))
{
RETAILMSG(1,(TEXT("^^==========61=========^^^^IRQ_JACK enable 2\r\n")));
OALGpioRegisterIntr(GPIO_NUM(GPIO_GROUTP_CHARGEDONE_INT,GPIO_INDEX_CHARGEDONE_INT),
GPIO_INTTYPE_FALLING_EDGE,SYSINTR_CHARGEDONE, IRQ_CHARGEDONE);
GPIO_PAD_EN_SET(GPIO_GROUTP_CHARGEDONE_INT,1 << GPIO_INDEX_CHARGEDONE_INT);
PIO_OUTPUT_DISABLE(GPIO,GPIO_GROUTP_CHARGEDONE_INT, GPIO_INDEX_CHARGEDONE_INT);
//PIO_SET_PULL(GPIO,GPIO_GROUTP_CMMB_INT, GPIO_INDEX_CMMB_INT);
PIO_INT_ENABLE(GPIO,GPIO_GROUTP_CHARGEDONE_INT, GPIO_INDEX_CHARGEDONE_INT);
}
break;
其中定义中断的IO 口:(GPIO0_0 作中断)
#defineGPIO_GROUTP_CHARGEDONE_INT GPIO_GROUP(0)
#defineGPIO_INDEX_CHARGEDONE_INT GPIO_INDEX(0)
以上程序首先判断GPIO0_0 是否注册了,如果没有,进行注册:OALGpioRegisterIntr 把IO 口与系统中断关联,
还要考虑中断类型如下:
typedefenum
{
GPIO_INTTYPE_HIGH_LEVEL,
GPIO_INTTYPE_LOW_LEVEL,
GPIO_INTTYPE_RAISING_EDGE,
GPIO_INTTYPE_FALLING_EDGE,
GPIO_INTTYPE_HI_LO_LEVEL,
GPIO_INTTYPE_RISE_FALL_EDGE
}GPIO_INTTYPE;
其具体意义参考:SiRFatlasIV Developer Manual 的GPIO 部分GPIO Control Register Definition
此时GPIO0_0 注册成下降沿触发的中断类型。
UINT32BSPIntrDisableIrq(UINT32 irq) 中,增加case :
caseIRQ_CHARGEDONE:
PIO_INT_DISABLE(GPIO,GPIO_GROUTP_CHARGEDONE_INT,
GPIO_INDEX_CHARGEDONE_INT);
break;
UINT32BSPIntrDoneIrq(UINT32 irq) 中,增加case :
caseIRQ_CHARGEDONE:
PIO_INT_ENABLE(GPIO,GPIO_GROUTP_CHARGEDONE_INT, GPIO_INDEX_CHARGEDONE_INT);
break;
1.2 中断服务程序
添加驱动(比如:Key.c 中),在Key.c 中声明全局变量:
HANDLEm_hChargeDone = NULL;
驱动加载函数KEY_Init 中:
m_hChargeDone= CreateEvent(NULL, FALSE, FALSE, NULL);
if (!m_hChargeDone)
{
RETAILMSG(1,(TEXT("\r\nCreateEvent ERROR!!--\r\n")));
return FALSE;
}
else RETAILMSG(1,(TEXT("\r\nCreateEvent OK!!--\r\n")));
//以下:初始化中断:系统中断ID:SYSINTR_CHARGEDONE 与事件关联,此时会调用OAL 中UINT32
BSPIntrEnableIrq(UINT32irq) ,进行中断的注册
bSuccess= InterruptInitialize(SYSINTR_CHARGEDONE, m_hChargeDone, NULL, 0);
————由于存在 SYSINTR_CHARGEDONE,因此需要添加头文件oemintr.h,还要在 GPIO 的Source 文件中添加该头文件路径(需要编译该头文件)。
//以下创造中断服务线程,再此线程中等待事件m_hChargeDone 信号触发(即中断触发)
m_hChargeDoneThread = CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)CheckChargeDoneThread,
NULL,
0,
NULL);
if (!m_hChargeDoneThread)
{
return FALSE;
}
中断服务线程如下:
voidCheckChargeDoneThread()
{
while(TRUE)
{
InterruptDone(SYSINTR_CHARGEDONE);
WaitForSingleObject(m_hChargeDone,INFINITE);//等待中断事件发生,即向下执行
RETAILMSG(1,(TEXT("CheckChargeDoneThread: WaitForSingleObject -m_hChargeDone!\r\n")));
}
}
BOOL GIO_Deinit(DWORD dwData)
{
RETAILMSG(1, (TEXT("KEY_Deinit++\r\n")));
if (m_hChargeDone)
CloseHandle(m_hChargeDone);
// if (m_hJackCheck)
// CloseHandle(m_hJackCheck);
RETAILMSG(1, (TEXT("KEY_Deinit--\r\n")));
return (TRUE);
}
Intr.c(wince600\platform\common\src\soc\atlasiv_sirf_v1\at8x0a\src\oal\oallib\intr):BOOLOALIntrInit()中:
if(g_oalSysInfo.warmrstInfo.bEnabled)
{
dwIrq= IRQ_WARMRESET;
g_oalSysInfo.warmrstInfo.dwSysIntr= SYSINTR_NOP;//无dwSysIntr
if(g_oalSysInfo.warmrstInfo.bEdge)
{
dwExtIntType= g_oalSysInfo.warmrstInfo.bFalling ?
GPIO_INTTYPE_FALLING_EDGE: GPIO_INTTYPE_RAISING_EDGE;
}
else
{
dwExtIntType= g_oalSysInfo.warmrstInfo.bFalling ?
GPIO_INTTYPE_LOW_LEVEL: GPIO_INTTYPE_HIGH_LEVEL;
}
if(!OALGpioRegisterIntr(g_oalSysInfo.warmrstInfo.dwRestBtnGpio, dwExtIntType,
g_oalSysInfo.warmrstInfo.dwSysIntr,IRQ_WARMRESET))
{
g_oalSysInfo.warmrstInfo.bEnabled= FALSE;
RETAILMSG(1,(TEXT("OALIntrInit: OALGpioRegisterIntr warmreset intr fail!\r\n")));
}
}
if(g_oalSysInfo.pwrbtnInfo.bEnabled)
{
dwIrq= IRQ_POWER;
g_oalSysInfo.pwrbtnInfo.dwSysIntr= OALIntrRequestSysIntr(1, &dwIrq, OAL_INTR_TRANSLATE);
if(g_oalSysInfo.pwrbtnInfo.dwSysIntr == SYSINTR_UNDEFINED)
g_oalSysInfo.pwrbtnInfo.bEnabled= FALSE;
else
{
if(g_oalSysInfo.pwrbtnInfo.bEdge)
{
dwExtIntType= g_oalSysInfo.pwrbtnInfo.bFalling ?
GPIO_INTTYPE_FALLING_EDGE: GPIO_INTTYPE_RAISING_EDGE;
}
else
{
dwExtIntType= g_oalSysInfo.pwrbtnInfo.bFalling ?
GPIO_INTTYPE_LOW_LEVEL: GPIO_INTTYPE_HIGH_LEVEL;
}
if(!OALGpioRegisterIntr(g_oalSysInfo.pwrbtnInfo.dwPwrBtnGpio, dwExtIntType,
g_oalSysInfo.pwrbtnInfo.dwSysIntr,IRQ_POWER))
g_oalSysInfo.pwrbtnInfo.bEnabled= FALSE;
}
}