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

📄 xsgpio.c

📁 ylpxa270 GPRS 通信代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_SSP2_EXTCLK, XS_GPIO_ALT_FUNC_GPIO);
	        (void) XsGpioSetDirection (XS_GPIO_ID_SSP2_EXTCLK, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_X);
			break;
		case SSP3:
            break;
	}
}    


void XsGpioEnableFlashWrite()
{
#if 0	//hzh
    // GPIO 12 - Processor card flash memory write protect
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_FLASH_nWP, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetDirection (XS_GPIO_ID_FLASH_nWP, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_1);

    // GPIO 22 - Processor card flash memory program enable
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_FLASH_VPEN, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetDirection (XS_GPIO_ID_FLASH_VPEN, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_1);
#endif
}    

void XsGpioDisableFlashWrite()
{
#if 0	//hzh
    // GPIO 12 - Processor card flash memory write protect
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_FLASH_nWP, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetDirection (XS_GPIO_ID_FLASH_nWP, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_0);

    // GPIO 22 - Processor card flash memory program enable
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_FLASH_VPEN, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetDirection (XS_GPIO_ID_FLASH_VPEN, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_X);
#endif
}    

/*
*******************************************************************************
    General GPIO utility function prototypes
*******************************************************************************
*/

// The following two functions are used for navigating in XsGpioRegsT

/*
*******************************************************************************
*
* FUNCTION:         XsGpioRegsCalcLocIndices
*
* DESCRIPTION:      Given a GPIO pin ID, calculate the two values that are
*                   needed for locating the right bit in the right register.
*                   Valid for all GPIO registers in the XsGpioRegsT structure
*                   that use only one bit per pin (that is, all but the GAFRs).
*
* INPUT PARAMETERS:
*       XsGpioIdT   pinID       - GPIO pin to get index values for
*       INT *       pinIndexP   - Address of variable in which to place the 
*                                   index into the named register array
*       INT *       bitShiftP   - Address of variable in which to place the
*                                   relative bit position, within the target
*                                   register, that corresponds to the specified
*                                   pin.
*
* RETURNS:          None
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None.  Note, does not range-check pin ID.
*
* CALLS:            
*
* CALLED BY:        
*
* PROTOTYPE:        void XsGpioRegsCalcLocIndices (XsGpioIdT, INT *, INT *);
*
*******************************************************************************
*/
void XsGpioRegsCalcLocIndices (XsGpioIdT pinId, PINT pinIndexP, PINT bitShiftP)
{
    // Assume range already validated by calling function

    *pinIndexP = (INT) pinId / XS_GPIO_PINS_PER_REG;
    *bitShiftP = (INT) pinId & XS_GPIO_PIN_POS_IN_REG_MSK;

} // End XsGpioRegsCalcLocIndices ()    


/*
*******************************************************************************
*
* FUNCTION:         XsGpioRegsCalcLocIndices
*
* DESCRIPTION:      Given a GPIO pin ID, calculate the two values that are
*                   needed for locating the right bit in the right register.
*                   Valid only for the GAFR registers in the XsGpioRegsT 
*                   structure.  
*
* INPUT PARAMETERS:
*       XsGpioIdT   pinID       - GPIO pin to get index values for
*       INT *       pinIndexP   - Address of variable in which to place the 
*                                   index into the GAFRs register array
*       INT *       bitShiftP   - Address of variable in which to place the
*                                   relative bit position, within the target
*                                   register, that corresponds to the base
*                                   for the specified pin.
*
* RETURNS:          None
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None.  Note, does not range-check pin ID.
*
* CALLS:            
*
* CALLED BY:        
*
* PROTOTYPE:       void XsGpioRegsCalcLocIndicesGafr (XsGpioIdT, INT *, INT *);
*
*******************************************************************************
*/
void XsGpioRegsCalcLocIndicesGafr (XsGpioIdT pinId, 
                                   PINT      pinIndexP, 
                                   PINT      bitShiftP)
{
    // Assume range already validated by calling function
    INT tmp;

    *pinIndexP = (INT) pinId / XS_GPIO_PINS_PER_REG_GAFR;

    tmp        = (INT) pinId & XS_GPIO_PIN_POS_IN_REG_MSK_GAFR;
    *bitShiftP = tmp * XS_GPIO_BITS_PER_PIN_GAFR;
    
} // End XsGpioRegsCalcLocIndicesGafr ()    


/*
*******************************************************************************
*
* FUNCTION:         XsGpioRangeCheckPinId
*
* DESCRIPTION:      Report whether the GPIO pin ID is valid for this processor.
*
* INPUT PARAMETERS: XsGpioIdT   pinID  - GPIO pin index to range-check
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   Failure: ERR_T_ILLPARAM - Pin ID out of range
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None
*
* CALLS:            
*
* CALLED BY:        
*
* PROTOTYPE:        UINT32 XsGpioRangeCheckPinId (XsGpioIdT);
*
*******************************************************************************
*/
UINT32 XsGpioRangeCheckPinId (XsGpioIdT pinId)
{
    UINT32 status = ERR_NONE;
    if ((pinId < XS_GPIO_ID_00)|| (pinId > XS_GPIO_ID_MAX))
    {
        status = ERR_T_ILLPARAM;
    }
    return(status);

} // End XsGpioRangeCheckPinId ()


/*
*******************************************************************************
    Private functions for main processor on-board GPIO driver
*******************************************************************************
*/

/*
*******************************************************************************
*
* FUNCTION:         XsGpioInterruptHandler
*
* DESCRIPTION:      Clear each active main processor GPIO interrupt reason and
*                   dispatch any corresponding registered interrupt handling
*                   subroutines.  Special handling for some pins, to act as
*                   if there is a "level," as opposed to edge-triggered, 
*                   interrupt activation.  In that case, the event is cleared
*                   only if the input is at the non-triggering level after
*                   the client handler has run.
*
* INPUT PARAMETERS: None
*
* RETURNS:          None
*
* GLOBAL EFFECTS:   Two error conditions are detected.  In either case,
*                   the error is logged [and DM_ErrorFatal() is invoked??].
*                       ERR_T_NO_HANDLER: No handler registered for 
*                           an activated GPIO interrupt.  This is a GPIO module
*                           internal error.
*                       ERR_T_NO_INT_REASON: No bit was set in any of the GEDRs
*                           so this GPIO interrupt should not have happened.
*
* ASSUMPTIONS:      DM "owns" the GPIO interrupts: if a debug monitor uses
*                   any GPIO pins, they will not be used to generate interrupts
*
* CALLS:            
*
* CALLED BY:        
*
* NOTES:            Clearing the interrupt on the pin is done by the main GPIO 
*                   handler before calling the registered handler.  This avoids
*                   race conditions.
*
*                   When the registered handler is invoked, it is given the pin 
*                   level (0 or 1) as its second parameter.
*
* PROTOTYPE:        void XsGpioInterruptHandler (void *);
*
*******************************************************************************
*/
void XsGpioInterruptHandler (void *xsGpioContextP)
{
    UINT32  status      = ERR_T_NO_INT_REASON ; // Must prove success
    INT     erroredPinID = 0;                   // What pin had the problem
    UINT32  tempGEDR;
    UINT32  tempGPLR;
    UINT32  tempGPLRsimLvl;

    XsGpioUsageEntryT* currPinCfgP;

    UINT32  pinReport;              // Passing pin level to client handler
    UINT32  pinMSK;                 // For isolating target pin within reg.
    INT     regIndex;               // For GPIO register addressing.
    INT     bitOffset;              // For GPIO register addressing.
    INT     currPin;                // Limits actions to defined reg. bits

//  Read all three GEDRs (edge detect registers), completely processing one 
//      at a time.
//
//  If any event (= an activated GPIO interrupt) is reported in GEDR, then:
//      - Make a copy of this corresponding register:
//         - GPLR[n]  pin-level
//
//  For each active bit in the GEDR[n] (GEDR[n][b]),
//      1. Clear the event by writing a 1 back to that bit in the GEDR.
//          (Delayed, optional processing for simulated level interrupts
//      2. If there is a corresponding registered handler, invoke it with
//          its registered parameter and the current pin level.
//      2a. If this is a simulated level interrupt (because we only have edge-
//          triggered interrupts in the GPIO), clear only if signal is at
//          inactive level
//      3. If there is no corresponding registered interrupt, log an error
//      

    for (regIndex=0; 
         (regIndex< XS_GPIO_REGS_PER_FUNC) 
                && (ERR_T_NO_HANDLER != status) ; 
         regIndex++ )
    {
        tempGEDR = XsGpioRegsP->GEDRs[regIndex];
        if (tempGEDR)
        {
            status = ERR_NONE;      //There was a reason for the GPIO interrupt
            
            // Record state before interrupt processing
            tempGPLR = XsGpioRegsP->GPLRs[regIndex];

            // Process entire register's worth of pins
            // But don't go beyond the last GPIO.
            for (bitOffset = 0,          // Need three initialized values
                        pinMSK = 1u, 
                        currPin = regIndex * XS_GPIO_PINS_PER_REG;
                 // Either reason will stop the processing:    
                 (bitOffset < XS_GPIO_PINS_PER_REG)        // entire register
                        && (currPin < XS_GPIO_PIN_COUNT);  // all GPIOs checked
                 bitOffset++ )
            {
                if (tempGEDR & pinMSK)  
                {   // We have a winner!
                    currPinCfgP = &XsGpioCurrentUsageTable[currPin];

                    // If not a simulated level interrupt, clear now to avoid
                    //  missing new events.
                    if (!currPinCfgP->simulatedLevelInt)
                    {
                        XsGpioRegsP->GEDRs[regIndex] = pinMSK; // Clear int.
                    }

                    // Create pin level report for registered handler
                    pinReport = (tempGPLR & pinMSK) >> bitOffset;
                
                    if (currPinCfgP->registeredHandlerFnP)
                    {   // Have handler, call it.

                        // Invoke registered handler with registered
                        //   param plus pin level report
                        (*currPinCfgP->registeredHandlerFnP)(
                                             currPinCfgP->registeredParamP,
                                             pinReport);

                        // If this is a simulated level interrupt, make sure 
                        //  that the level has gone inactive before clearing.
                        if (currPinCfgP->simulatedLevelInt)
                        {
                            // Get level post-processing.
                            tempGPLRsimLvl = XsGpioRegsP->GPLRs[regIndex]
                                             & pinMSK;

                            // Is this the inactive level for pin?
                            // Note: Doesn't make sense for edge trigger on
                            //       transition to both levels, so don't 
                            //       check for that.
                            if (  (tempGPLRsimLvl && (XS_GPIO_INT_FALLING_EDGE
                                           == currPinCfgP->triggerCondition))
                                ||(!tempGPLRsimLvl && (XS_GPIO_INT_RISING_EDGE
                                           ==  currPinCfgP->triggerCondition)))
                            {
                                XsGpioRegsP->GEDRs[regIndex] = pinMSK;
                            }
                        } // if simulated level interrupt

                    } // if (there is a registered handler)
                    else
                    {
                        // Oops.
                        status = ERR_T_NO_HANDLER;  
                        XsGpioRegsP->GEDRs[regIndex] = pinMSK;
                        erroredPinID = currPin;
                        XsGpioDisablePinInt (erroredPinID); //Patch the problem
                    }
                 
                } // if (tempGEDR & pinMSK)

                pinMSK <<= 1;
                currPin++;

            } // for (processing an entire GEDR's worth of pins)
        }  // if tempGEDR: had an interrupt reported in this GEDR
    } // for (regindex=0; regindex< XS_GPIO_REGS_PER_FUNC; regindex++ )

    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                  ERR_S_XSGPIO_INT_HANDLER, status, erroredPinID, 0, 0)
#if 0
// Note: fatal isn't friendly.  Probably never do this.
        // Good-bye.  Both known errors are fatal.
//        DM_ErrorFatal (status, (UINT32) XsGpioInterruptHandler); 
#endif

    } // status non-zero (error exists)
   
} // End XsGpioInterruptHandler ()


⌨️ 快捷键说明

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