📄 xsgpio.c
字号:
(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 + -