⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xsgpio.c

📁 ylpxa270 GPRS 通信代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    else if (initialLevel & ~1u)
    {
        badParamNum = 3;
    }
    
    if (badParamNum)
    {
        status = ERR_T_ILLPARAM;
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                  ERR_S_XSGPIO_SET_DIR, status, badParamNum, 0, 0)
    }
    else    // Now move on to checking the current state, to see 
            // if it's OK to perform the requested operation.
    {
        //  Must be for GPIO mode (ERR_T_WRONG_STATE)
        // with no interrupt currently registered if new 
        // direction is output. (ERR_T_REG_HANDLER)

        currPinCfgP = XsGpioCurrentUsageTable + pinID;

        if (XS_GPIO_UNAVAILABLE == currPinCfgP->fnCategory)
        {
            status = ERR_T_NOT_AVAIL;
        }
        else if (XS_GPIO_ALT_FUNC_GPIO != currPinCfgP->fnCategory)
        {
            status = ERR_T_WRONG_STATE;
        }
        else if (currPinCfgP->registeredHandlerFnP
                 && (XS_GPIO_DIR_OUT == direction))
        {
            status = ERR_T_REG_HANDLER;
        }

        if (status)
        {            
            LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                      ERR_S_XSGPIO_SET_DIR, status, 0, 0, 0)
        }
        else  // Safe to do the job.
        {
            currPinCfgP->initialLevel     = initialLevel;
            currPinCfgP->direction        = direction;

            // Order of operations is important in HW access.  
            // level, then direction

            // Set up addressing for register operations
            XsGpioRegsCalcLocIndices ( pinID, &regIndex, &bitOffset );

            // For output lines only, set the level.
            if (XS_GPIO_DIR_OUT == currPinCfgP->direction)
            {
                // Output level registers are write-only, don't read-"OR"-write

                if (XS_GPIO_PIN_LEVEL_1 == currPinCfgP->initialLevel)
                {
                    XsGpioRegsP->GPSRs[regIndex] = 
                                        XS_GPIO_PIN_LEVEL_MSK << bitOffset;
                }
                else // must be XS_GPIO_PIN_LEVEL_0
                {
                    XsGpioRegsP->GPCRs[regIndex] = 
                                        XS_GPIO_PIN_LEVEL_MSK << bitOffset;
                }
            } // End of set level for output direction

            // Set the new direction.
            tempGPDR = XsGpioRegsP->GPDRs[regIndex] 
                       & ~(XS_GPIO_PIN_LEVEL_MSK << bitOffset);

            XsGpioRegsP->GPDRs[regIndex] = tempGPDR 
                                           | (direction << bitOffset);

        } // else - Safe to do the job
    } // else - passed parameter checks 

//	Lubbock_WriteHexLeds(status);
//	DM_WaitMs(1000);

    return(status);

} // End of XsGpioSetDirection ()


/*
*******************************************************************************
*
* FUNCTION:         XsGpioRegisterHandler
*
* DESCRIPTION:      Register an interrupt handling subroutine to be called
*                   when a specified edge transition occurs on the target GPIO
*                   input pin level.  Also register a pointer that will be
*                   passed to that handler.  
*
* INPUT PARAMETERS: 
*      XsGpioIdT              pinID      - GPIO pin to register handler for
*      XsGpioIntTriggerEdgeT  triggerType- Pin state change to trigger int:
*                                            Rising edge, falling edge, both.
*      XsGpioHandlerFnPT      handlerFnP - Handler to be called for pinID int.
*      void *                 paramP     - Pointer to be passed to reg. handler
*
* RETURNS:
*       Success: 0 (ERR_NONE)
*       Failure: ERR_T_ILLPARAM    - out of range parameter; details in err log
*                ERR_T_WRONG_STATE - pin not configured as GPIO
*                ERR_T_REG_HANDLER - pin already has a registered handler
*
* GLOBAL EFFECTS: 
*       - Required for XsGpioEnablePinInt().
*       - Records last detected failure condition
*
* ASSUMPTIONS:      
*
* CALLS:            
*
* CALLED BY:        
*
* Notes:
*   - This is the only way to specify the type of edge trigger for an interrupt
*   - Does not enable the interrupt: use XsGpioEnablePinInt() afterwards.
*
* PROTOTYPE:        UINT32 XsGpioRegisterHandler (XsGpioIdT,
*                                                 XsGpioIntTriggerEdgeT,
*                                                 XsGpioHandlerFnPT, 
*                                                 void *)
*
*******************************************************************************
*/

UINT32 XsGpioRegisterHandler  ( XsGpioIdT pinID, 
                                XsGpioIntTriggerEdgeT triggerType,
                                XsGpioHandlerFnPT handlerFnP, 
                                void *paramP)
{
    UINT32 status       = 0;    // Assume success
    INT    badParamNum  = 0;    // Which param had error.  Assume no errors.

    XsGpioUsageEntryT   *currPinCfgP;


    status = XsGpioRangeCheckPinId (pinID);

    if (status)
    {   
        badParamNum  = 1;
    }
    else
    {   // Pin ID safe, check other conditions
     
        currPinCfgP = XsGpioCurrentUsageTable + pinID;

        if (   (XS_GPIO_ALT_FUNC_GPIO != currPinCfgP->fnCategory)
            || (XS_GPIO_DIR_IN != currPinCfgP->direction))
        {
            status = ERR_T_WRONG_STATE;
        }

        if (currPinCfgP->registeredHandlerFnP)
        {
            status = ERR_T_REG_HANDLER;
        }

        if ((UINT) triggerType  > (UINT) XS_GPIO_INT_BOTH_EDGES)
        {
            status      = ERR_T_ILLPARAM;
            badParamNum = 2;
        }
    } // else: pin ID passed range check.

    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                   ERR_S_XSGPIO_REG_HANDLER, status, badParamNum, 0, 0)
    }
    else // No problems, register the handler.
    {
        currPinCfgP->registeredHandlerFnP = handlerFnP;
        currPinCfgP->triggerCondition     = triggerType;
        currPinCfgP->registeredParamP     = paramP;
    }

    return(status);

} // End XsGpioRegisterHandler ()

/*
*******************************************************************************
*
* FUNCTION:         XsGpioUnRegisterHandler
*
* DESCRIPTION:      Disable any interrupt on the target pin and unregister any
*                   registered handler on that pin.  Clears any existing edge 
*                   type specification to XS_GPIO_INT_NONE.  The only error is 
*                   out-of-range pin ID; this function no-ops quietly.
*
* INPUT PARAMETERS: XsGpioIdT pinID - GPIO pin to unregister handler for
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   Failure: ERR_T_ILLPARAM    - out of range parameter
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None
*
* CALLS:            
*
* CALLED BY:                                ]
*
* PROTOTYPE:        UINT32 XsGpioUnRegisterHandler (XsGpioIdT;
*
*******************************************************************************
*/

UINT32 XsGpioUnRegisterHandler (XsGpioIdT pinID)

{
    UINT32 status = 0 ; // Assume success
    XsGpioUsageEntryT   *currPinCfgP;

    status = XsGpioDisablePinInt (pinID);  // Also checks pinID and all states.

    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                   ERR_S_XSGPIO_UNR_HANDLER, status, 0, 0, 0)
    }
    else    // All clear and interrupt disabled for pin.  Unregister.
    {
        currPinCfgP = XsGpioCurrentUsageTable + pinID;

        currPinCfgP->registeredHandlerFnP = NULL;
        currPinCfgP->triggerCondition     = XS_GPIO_INT_NONE;
        currPinCfgP->registeredParamP     = NULL;
    }

    return(status);

} // End XsGpioUnRegisterHandler ()


/*
*******************************************************************************
*
* FUNCTION:         XsGpioEnablePinInt
*
* DESCRIPTION:      Activate the existing specified edge type for triggering an
*                   interrupt on the target pin.  An interrupt handling 
*                   subroutine must already be registered.  Performed under
*                   interrupt protection.
*
* INPUT PARAMETERS: XsGpioIdT pinID - GPIO pin to activate interrupt for
*
* RETURNS:  
*       Success: 0 (ERR_NONE)
*       Failure: ERR_T_ILLPARAM    - out of range parameter
*                ERR_T_NO_HANDLER  - pin lacks a registered handler
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      
*
* CALLS:            
*
* CALLED BY:        
*
* PROTOTYPE:        UINT32 XsGpioEnablePinInt (XsGpioIdT);
*
*******************************************************************************
*/

UINT32 XsGpioEnablePinInt (XsGpioIdT pinID)
{
    UINT32 status = 0 ;         // Assume success
    UINT32 previousIntState;
    UINT32 tempGRER;
    UINT32 tempGFER;
    INT regIndex;               // For GPIO register addressing.
    INT bitOffset;              // For GPIO register addressing.
    XsGpioUsageEntryT   *currPinCfgP;

    status = XsGpioRangeCheckPinId (pinID);
    if (!status)
    {
        currPinCfgP = XsGpioCurrentUsageTable + pinID;

        if (!currPinCfgP->registeredHandlerFnP)
        {
            status = ERR_T_NO_HANDLER;
        }

    } // Finished if !status: all error states checked.

    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                  ERR_S_XSGPIO_EN_PIN_INT, status, 0, 0, 0)
    }
    else
    {
        // Set up addressing for register operations
        XsGpioRegsCalcLocIndices ( pinID, &regIndex, &bitOffset );

        // Set the desired values in the appropriate edge detect register(s),
        // clearing out the current setting for the target pin;
        // then the clear current edge detect status for a fresh start.

        // Perform the register accesses under interrupt protection
        // to prevent spurious interrupts.

        previousIntState = IRQ_DisableInterrupts(CPSR_I_Bit|CPSR_F_Bit);

        tempGRER = XsGpioRegsP->GRERs[regIndex];
        tempGFER = XsGpioRegsP->GFERs[regIndex];

        tempGRER &= ~(XS_GPIO_INT_EDGE_MSK << bitOffset);
        tempGFER &= ~(XS_GPIO_INT_EDGE_MSK << bitOffset);

        switch (currPinCfgP->triggerCondition)
        {
            case XS_GPIO_INT_RISING_EDGE:
                tempGRER  |= (XS_GPIO_INT_EDGE_MSK << bitOffset);
                break;
            case XS_GPIO_INT_FALLING_EDGE:
                tempGFER  |= (XS_GPIO_INT_EDGE_MSK << bitOffset);
                break;
            case XS_GPIO_INT_BOTH_EDGES:
                tempGRER  |= (XS_GPIO_INT_EDGE_MSK << bitOffset);
                tempGFER  |= (XS_GPIO_INT_EDGE_MSK << bitOffset);
                break;
        } // switch triggerCondition)

        // Set the new trigger conditions
        XsGpioRegsP->GRERs[regIndex] = tempGRER;
        XsGpioRegsP->GFERs[regIndex] = tempGFER;

        // Clear outstanding calls on this pin
        XsGpioRegsP->GEDRs[regIndex]  |= (XS_GPIO_INT_EDGE_MSK << bitOffset);

        // Now record it.
        currPinCfgP->interruptEnabled = TRUE; 

        IRQ_EnableInterrupts (previousIntState);

    } // else (status): No problems, activate the settings.

    return(status);

} // End XsGpioEnablePinInt ()   


/*
*******************************************************************************
*
* FUNCTION:         XsGpioDisablePinInt
*
* DESCRIPTION:      Deactivate any existing edge type for triggering an
*                   interrupt on the target pin.  Clears any outstanding

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -