WinCE下的GPIO中断的处理

在我所负责的音频驱动部分代码中,采用了PXA270的GPIO34来检测Headphone的插入与拔出.原驱动部分有个BUG,即当耳机插入以后,耳机和喇叭同时在响,很明显没有对耳机插入事件做出响应.所以我开始采用了检测GPIO信号拉高或者拉低和检测耳机的插入事件,但是这样做有个问题,就是会有延时,插入耳机以后,会有一两秒的时候喇叭才会变关掉.为了改变这种办法,经过咨询,决定采用中断的办法来做这件事情,可以保证没有这样的检测延时.

    在音频驱动(WM9705)的Hwctxt.cpp的initcodec函数中加入如下代码:

  if (m_pGPIORegs == NULL)
    {
        PHYSICAL_ADDRESS ioPhysicalBase = {BULVERDE_BASE_REG_PA_GPIO,0};
        m_pGPIORegs = (PBULVERDE_GPIO_REG)MmMapIoSpace(ioPhysicalBase, sizeof(BULVERDE_GPIO_REG),FALSE);
       
     }
     
     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);

    //create the headphone Event
     gHeadPhoneIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    //Interrupt initialize and connect SYSINTR with EVENT.    

     if (!(InterruptInitialize(SYSINTR_HEADPHONE_DETECT, gHeadPhoneIntrEvent, NULL, 0))) {
     WAV_DBGMSG(TEXT("[Audio]Intialize the interrupt gHeadphoneIntrEvent error/r/n"));
              
    }
       

//Create the Interrupt thread 
    gHeadPhoneIntrThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)HeadPhoneIntrThread,this, 0, NULL);
    if (!gHeadPhoneIntrThread)
  {
   WAV_DBGMSG(TEXT("Create the Detect thread failure--/r/n"));
  }

其中SYSINTR_HEADPHONE_DETECT定义在Bsp_cfg.h中,具体定义如下:

#define SYSINTR_HEADPHONE_DETECT (SYSINTR_FIRMWARE+19) //chose a unused intr

具体的中断处理函数如下:

int WINAPI HeadPhoneIntrThread(void)
{
    
    while(1)
    {            
        WaitForSingleObject(gHeadPhoneIntrEvent,INFINITE);

 
     //if GPIO34 is high,means headphone is inserted 
     if (m_pGPIORegs->GPLR1 & XLLP_BIT_2)
     {
         
         HeadPhone_Detect=1; 
         //WAV_DBGMSG(TEXT("[Audio]in HeadphoneIntrThread Headphone in--/r/n"));
         WMAudioMuteSignal( DeviceToRW, WM_AUDIO_HEADPHONE, FALSE );//open headphone output
         WMAudioMuteSignal( DeviceToRW, WM_AUDIO_LINEOUT, TRUE );//mute the lineout output
     }
     else
     {
        
         HeadPhone_Detect=0;  
         //WAV_DBGMSG(TEXT("[Audio]in HeadphoneIntrThread Headphone out--/r/n"));
         WMAudioMuteSignal( DeviceToRW, WM_AUDIO_HEADPHONE,TRUE );
         WMAudioMuteSignal( DeviceToRW, WM_AUDIO_LINEOUT, FALSE );
            
     } 
     
      InterruptDone(SYSINTR_HEADPHONE_DETECT);
    }
}

但是SYSINTR_HEADPHONE_DETECT是如何和真正的中断联系起来的呢,具体的操作在intr.c里面.这个文件位于/project/platform/mainstoneii/src/kernel/oal.

OALIntrStaticTranslate(SYSINTR_HEADPHONE_DETECT, IRQ_HEADPHONE_DETECT);
这句将SYSINTR_HEADPHOONE_DETECT和真正的中断号联系起来.而IRQ_HEADPHONE_DETECT的定义也在这儿:#define IRQ_HEADPHONE_DETECT          (IRQ_BULVERDE_MAX + 15) 

注意,这里的IRQ_HEADPHONE_DETECT与#define IRQ_GPIO0_PCMCIA_S1_CSC       (IRQ_BULVERDE_MAX + 15) 是一样的,因为PCMCIA在系统里面没有用,所以采用这个中断来给我们的HEADPHONE使用.所以别忘了把下面这句注释掉,否则你的系统会不知道这个中断给谁用了.

//OALIntrStaticTranslate(SYSINTR_PCCARD_CSC_S1, IRQ_GPIO0_PCMCIA_S1_CSC);

然后在BSPIntrEnableIrq函数中加入对headphone IRQ的处理:

 if (irq == IRQ_HEADPHONE_DETECT)
    {
    // WAV_DBGMSG(TEXT("[Audio]Setting GPIO for Headphone in BSPIntrEnableIrq/r/n")); 

     g_pGPIORegs->GAFR1_L &= ~XLLP_GPIO_AF_BIT_FFRXD_MASK;   //GPIO34 as GPIO
     g_pGPIORegs->GPDR1 &= ~XLLP_BIT_2;                      //GPIO34 as HPS Input

//set the falling edge and rising edg to work
       g_pGPIORegs->GFER1 |=XLLP_BIT_2;
     g_pGPIORegs->GRER1 |=XLLP_BIT_2;
    }

同样的在BSPIntrDisableIrq函数中也要加入处理headphone IRQ的代码:

 else if (irq == IRQ_HEADPHONE_DETECT)
    {

//clear the falling edge and rising to start the interrupt
     g_pGPIORegs->GFER1 &=~XLLP_BIT_2;
     g_pGPIORegs->GRER1 &=~XLLP_BIT_2;
    }

在BSPIntrActiveIrq函数中,可以知道这个函数的用途是:This function is called from interrupt handler to give BSP chance to  translate IRQ in case of secondary interrupt controller.可以看到实际处理我们HEADPHONE IRQ的函数是GPIOXX2InterruptHandler().在这个函数中处理Headphone IRQ的代码为:

else if (g_pGPIORegs->GEDR1 & XLLP_BIT_2) 
     {//set the GPIO Edge Status Register
        g_pGPIORegs->GEDR1 |= XLLP_BIT_2;  
       //return IRQ to enbale the EVENT
        return IRQ_HEADPHONE_DETECT;
     }

此处返回中断号可以触发EVENT.这样的话在中断处理函数中 WaitForSingleObject(gHeadPhoneIntrEvent,INFINITE);就可以知道中断发生了,否则的话它会等在这儿.

这样在WINCE下的GPIO中断处理到检测就完成了.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值