The driver layer using the GPIO interrupt function simplify the interface

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/ScilogyHunter/article/details/100375659

Interface Description

To simplify the driver layer using the GPIO Interrupt complex function I encapsulates into two interfaces, API standards are similar to the interface provided by the system, using a direct request to the interrupt mode when the GPIO function GPIO interrupts, and then run out call the corresponding release function. These two functions encapsulate the GPIO interrupt processing interface, interrupt API function and the necessary processes and exception handling. As shown in the following:

/*********************************************************************************************************
  GPIO_IRQ 对象结构体
*********************************************************************************************************/
typedef struct {
    UINT    uiGpio;                                                     /*  GPIO 编号                   */
    ULONG   ulFlags;                                                    /*  GPIO 配置参数               */

    VOID  (*pFunc)(PVOID);                                              /*  中断回调函数                */
    PVOID   pvArg;                                                      /*  回调函数参数                */
    CPCHAR  pcLabel;                                                    /*  GPIO 标签名称               */
    CPCHAR  pcIrqName;                                                  /*  GPIO 中断名称               */

    ULONG   ulVector;                                                   /*  GPIO 中断号                 */
} GPIO_IRQ;
/*********************************************************************************************************
** 函数名称: API_GpioIrqRequest
** 功能描述: 请求使用一个中断模式的 GPIO
** 输 入  : pGpioIrq      中断GPIO对象
** 输 出  : ERROR_CODE
*********************************************************************************************************/
static  INT  API_GpioIrqRequest (GPIO_IRQ  *pGpioIrq);
/*********************************************************************************************************
** 函数名称: API_GpioIrqFree
** 功能描述: 释放一个中断模式的 GPIO
** 输 入  : pGpioIrq      中断GPIO对象
** 输 出  : ERROR_CODE
*********************************************************************************************************/
static  INT  API_GpioIrqFree (GPIO_IRQ  *pGpioIrq);

Implementation code

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                SylixOS(TM)  LW : long wing
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gpioIrqLib.h
**
** 创   建   人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2017 年 12 月 13 日
**
** 描        述: GPIO 中断模式简化接口
*********************************************************************************************************/
#define __SYLIXOS_KERNEL
#include "SylixOS.h"
/*********************************************************************************************************
  GPIO_IRQ 对象结构体
*********************************************************************************************************/
typedef struct {
    UINT    uiGpio;                                                     /*  GPIO 编号                   */
    ULONG   ulFlags;                                                    /*  GPIO 配置参数               */

    VOID  (*pFunc)(PVOID);                                              /*  中断回调函数                */
    PVOID   pvArg;                                                      /*  回调函数参数                */
    CPCHAR  pcLabel;                                                    /*  GPIO 标签名称               */
    CPCHAR  pcIrqName;                                                  /*  GPIO 中断名称               */

    ULONG   ulVector;                                                   /*  GPIO 中断号                 */
} GPIO_IRQ;
/*********************************************************************************************************
** 函数名称: __gpioIsr
** 功能描述: GPIO 中断服务函数
** 输    入: pvArg      输入参数
**           ulVector   中断向量
** 输    出: 中断返回值
*********************************************************************************************************/
static irqreturn_t  __gpioIsr (PVOID pvArg, ULONG  ulVector)
{
    irqreturn_t  irqret;
    GPIO_IRQ    *pGpioIrq;

    pGpioIrq = (GPIO_IRQ   *)pvArg;
    if (pGpioIrq == NULL) {
        return  (LW_IRQ_NONE);
    }
    irqret = API_GpioSvrIrq(pGpioIrq->uiGpio);

    if (LW_IRQ_HANDLED == irqret) {
        API_GpioClearIrq(pGpioIrq->uiGpio);
        if (pGpioIrq->pFunc) {
            pGpioIrq->pFunc(pGpioIrq->pvArg);
        }
    }

    return  (irqret);
}
/*********************************************************************************************************
** 函数名称: API_GpioIrqRequest
** 功能描述: 请求使用一个中断模式的 GPIO
** 输 入  : pGpioIrq      中断GPIO对象
** 输 出  : ERROR_CODE
*********************************************************************************************************/
static  INT  API_GpioIrqRequest (GPIO_IRQ  *pGpioIrq)
{
    INT  iRet;

    if (pGpioIrq == NULL) {
        return  (PX_ERROR);
    }

    iRet = API_GpioRequestOne(pGpioIrq->uiGpio, LW_GPIOF_DIR_IN, pGpioIrq->pcLabel);
    if (iRet != ERROR_NONE) {
        return  (PX_ERROR);
    }

    pGpioIrq->ulVector = API_GpioGetIrq(pGpioIrq->uiGpio, 0, 0);
    if (pGpioIrq->ulVector < 0) {
        return  (PX_ERROR);
    }

    if (pGpioIrq->ulFlags & LW_GPIODF_TRIG_LEVEL) {
        if (pGpioIrq->ulFlags & LW_GPIODF_TRIG_FALL) {                  /*  设置为低电平触发            */
            iRet = API_GpioSetupIrq(pGpioIrq->uiGpio, 1, 0);

        } else if (pGpioIrq->ulFlags & LW_GPIODF_TRIG_RISE) {           /*  设置为高电平触发            */
            iRet = API_GpioSetupIrq(pGpioIrq->uiGpio, 1, 1);
        }
    } else {
        if ((pGpioIrq->ulFlags & LW_GPIODF_TRIG_FALL) &&
            (pGpioIrq->ulFlags & LW_GPIODF_TRIG_RISE)) {                /*  设置为双边沿触发            */
            iRet = API_GpioSetupIrq(pGpioIrq->uiGpio, 0, 2);

        } else if (pGpioIrq->ulFlags & LW_GPIODF_TRIG_FALL) {           /*  设置为下降沿触发            */
            iRet = API_GpioSetupIrq(pGpioIrq->uiGpio, 0, 0);

        } else if (pGpioIrq->ulFlags & LW_GPIODF_TRIG_RISE) {           /*  设置为上升沿触发            */
            iRet = API_GpioSetupIrq(pGpioIrq->uiGpio, 0, 1);
        }
    }
    if (iRet == LW_VECTOR_INVALID) {
        return  (PX_ERROR);
    }

    API_InterVectorConnect(pGpioIrq->ulVector,                          /*  注册中断服务函数            */
                           (PINT_SVR_ROUTINE)__gpioIsr,
                           pGpioIrq,
                           pGpioIrq->pcIrqName);
    API_InterVectorEnable(pGpioIrq->ulVector);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: API_GpioIrqFree
** 功能描述: 释放一个中断模式的 GPIO
** 输 入  : pGpioIrq      中断GPIO对象
** 输 出  : ERROR_CODE
*********************************************************************************************************/
static  INT  API_GpioIrqFree (GPIO_IRQ  *pGpioIrq)
{
    API_InterVectorDisable(pGpioIrq->ulVector);
    API_InterVectorDisconnect(pGpioIrq->ulVector,                       /*  注册中断服务函数            */
                             (PINT_SVR_ROUTINE)__gpioIsr,
                              pGpioIrq);
    API_GpioFree(pGpioIrq->uiGpio);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

Routine use

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                SylixOS(TM)  LW : long wing
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gpioDrvExample3.c
**
** 创   建   人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2017 年 12 月 13 日
**
** 描        述: gpio 在驱动中的调用例程,针对NXP i.MX-RT1050 EVK开发版。
**               因为连接板载 LED01 的引脚同时也连接了 enet 的复位脚,硬件冲突故不能使用。
**               LED02 只是一个空闲的gpio(为J22.7),需要用户连接LED或万用表来检测电平变化。
*********************************************************************************************************/
#define __SYLIXOS_KERNEL
#include "stdio.h"
#include "SylixOS.h"
#include "gpio/gpio.h"
#include "gpioIrqLib.h"
/*********************************************************************************************************
   引脚宏定义
 ********************************************************************************************************/
#define KEY08        GPIO_E_00                                          /*  GPIO5--00                   */
#define LED01        GPIO_A_09                                          /*  GPIO1--09                   */
#define LED02        GPIO_A_18                                          /*  GPIO1--18                   */
/*********************************************************************************************************
  GPIO_TEST 对象结构体
*********************************************************************************************************/
typedef struct {
    UINT                uiGpioLed;                                      /*  GPIO编号                   */
    UINT                uiIrqCount;                                     /*  中断计数值                 */
    LW_OBJECT_HANDLE    hSemBIrq;                                       /*  信号量句柄                 */
} GPIO_TEST;
/*********************************************************************************************************
** 函数名称: gpioDrvExample3CallBack
** 功能描述: GPIO 中断回调函数
** 输    入: pvArg      输入参数
** 输    出: 无
*********************************************************************************************************/
static VOID  gpioDrvExample3CallBack (PVOID pvArg)
{
    GPIO_TEST  *pGpioTest = (GPIO_TEST  *)pvArg;

    pGpioTest->uiIrqCount++;
    API_SemaphoreBPost(pGpioTest->hSemBIrq);
}
/*********************************************************************************************************
** 函数名称: gpioDrvExample3
** 功能描述: gpio 中断例程
** 输    入: NONE
** 输    出: ERROR_CODE
*********************************************************************************************************/
INT  gpioDrvExample3 (VOID)
{
    INT          iRet;
    GPIO_TEST    gpioTest;
    GPIO_IRQ     gpioIrq;

    printf("Gpio interrupt example. Waiting press the key SW8.\n");

    gpioIrq.uiGpio    = KEY08;
    gpioIrq.ulFlags   = LW_GPIODF_TRIG_FALL;
    gpioIrq.pFunc     = gpioDrvExample3CallBack;
    gpioIrq.pvArg     = (PVOID)&gpioTest;
    gpioIrq.pcLabel   = "key";
    gpioIrq.pcIrqName = "key_isr";
    iRet = API_GpioIrqRequest(&gpioIrq);
    if (iRet != ERROR_NONE) {
        return  (PX_ERROR);
    }

    gpioTest.uiGpioLed  = LED02;
    gpioTest.uiIrqCount = 0;
    gpioTest.hSemBIrq   = API_SemaphoreBCreate("gpioTest",
                                               LW_FALSE,
                                               LW_OPTION_OBJECT_LOCAL |
                                               LW_OPTION_WAIT_PRIORITY,
                                               LW_NULL);

    API_GpioRequestOne(gpioTest.uiGpioLed, LW_GPIOF_OUT_INIT_LOW, "LED");

    while (1) {
        API_SemaphoreBPend(gpioTest.hSemBIrq, LW_OPTION_WAIT_INFINITE);

        printf("The key effective, uiIrqCount = %d\n", gpioTest.uiIrqCount);
        API_GpioSetValue(gpioTest.uiGpioLed, gpioTest.uiIrqCount & 0x01);
    }

    API_GpioIrqFree(&gpioIrq);
    API_GpioFree(gpioTest.uiGpioLed);

    return  (ERROR_NONE);
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

Guess you like

Origin blog.csdn.net/ScilogyHunter/article/details/100375659