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

📄 xsgpio.c

📁 ylpxa270 GPRS 通信代码
💻 C
📖 第 1 页 / 共 4 页
字号:
*                   interrupt for pin.  No-ops unless pin mode is GPIO
*                   and direction is input.  Leaves the record of desired
*                   trigger type for subsequent use of XsGpioEnablePinInt().
*
* INPUT PARAMETERS: XsGpioIdT pinID - GPIO pin to deactivate interrupt for
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   Failure: ERR_T_ILLPARAM    - out of range parameter
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      
*
* CALLS:            
*
* CALLED BY:        
*
* PROTOTYPE:        UINT32 XsGpioDisablePinInt (XsGpioIdT);
*
*******************************************************************************
*/

UINT32 XsGpioDisablePinInt (XsGpioIdT pinID)
// Does not change the edge type that triggers the interrupt
// Only error is for bad pinID.  If not GPIO input,
//  quietly does nothing.

{

    UINT32 status     = ERR_NONE;  // Assume success
    UINT32 previousIntState;
    INT    regIndex;              // For GPIO register addressing.
    INT    bitOffset;             // For GPIO register addressing.

    XsGpioUsageEntryT *currPinCfgP;


    status = XsGpioRangeCheckPinId (pinID);
    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                  ERR_S_XSGPIO_DI_PIN_INT, status, 0, 0, 0)
    }
    else
    {
        currPinCfgP = XsGpioCurrentUsageTable + pinID;

        if (   (XS_GPIO_ALT_FUNC_GPIO == currPinCfgP->fnCategory)
            && (XS_GPIO_DIR_IN        == currPinCfgP->direction ))
        {

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

            // Perform the register accesses under interrupt protection
            previousIntState = IRQ_DisableInterrupts(CPSR_I_Bit|CPSR_F_Bit);

            // Clear out the current setting for the target pin in both
            //  edge detect selection registers.
            // Then the clear current edge detect status because we
            //  don't want an interrupt on this pin now.

            XsGpioRegsP->GRERs[regIndex] 
                                    &= ~(XS_GPIO_INT_EDGE_MSK << bitOffset);
            XsGpioRegsP->GFERs[regIndex] 
                                    &= ~(XS_GPIO_INT_EDGE_MSK << bitOffset);

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

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

            IRQ_EnableInterrupts (previousIntState);

        } // GPIO function and input direction: perform the operation

    } // Finished else (status): parameter range checked

    return(status);

} // End XsGpioDisablePinInt ()   


/*
*******************************************************************************
    XsGpioSetSimulatedLevelInt
*******************************************************************************
*/

void XsGpioSetSimulatedLevelInt (XsGpioIdT pinID, BOOL simulatedLevelInt)
    // Don't use bad params, but don't report param errors.  Other calls to the
    // driver in this vicinity will catch them.
{
    UINT32 status;
    status = XsGpioRangeCheckPinId (pinID);
    if (!status)
    {
        XsGpioCurrentUsageTable[pinID].simulatedLevelInt = simulatedLevelInt;
    }
    
} // XsGpioSetSimulatedLevelInt ()

/*
*******************************************************************************
    Non-standard, test-oriented API of main processor on-board 
        GPIO driver.  Lower level access provided.
*******************************************************************************
*/
//=============================== LATER ================================

UINT32 XsGpioSetAlternateFunction ( XsGpioIdT pinID,
                                    XsGpioAltFuncCodeT alternateFunction)
//    (This is a register-oriented primitive and does not trigger
//      a general initialization of all pins needed to support
//      the alternate function selected for this pin)
//      It may be necessary to set the direction and the level (for outputs)

// If an interrupt handler is registered, the new function must be GPIO.
{
    UINT32               status;
    INT                  regIndex;       // For GPIO register addressing.
    INT                  bitOffset;      // For GPIO register addressing.
    UINT32               tempGAFR;
    INT                  previousIntState;
    XsGpioUsageEntryT   *currPinCfgP;

    status = XsGpioRangeCheckPinId (pinID);

    if (!status)
    {
        currPinCfgP = &XsGpioCurrentUsageTable[pinID];

        if (XS_GPIO_UNAVAILABLE == currPinCfgP->fnCategory)
        {
            status = ERR_T_NOT_AVAIL;
        }
        else
        {   // Non-reserved pin.  Continue checking
                // Absence of change is OK; otherwise,
                // Start function must be GPIO
            if (  ( alternateFunction     != currPinCfgP->fnCategory)
                &&( XS_GPIO_ALT_FUNC_GPIO != currPinCfgP->fnCategory)
                && (XS_GPIO_ALT_FUNC_GPIO != alternateFunction))
            {
                status = ERR_T_WRONG_STATE;
            }
        }
    }

    if (!status)
    {
        // No SW problems, do the job

        // Set up addressing for GAFR access (alternate function regs)
        XsGpioRegsCalcLocIndicesGafr ( pinID, &regIndex, &bitOffset );

        
        previousIntState = IRQ_DisableInterrupts(CPSR_I_Bit|CPSR_F_Bit);

        // Get current alternate function register setting, clearing
        //  out the target pin's control bits.
        tempGAFR = XsGpioRegsP->GAFRs[regIndex] 
                            & ~(XS_GPIO_GAFR_PIN_MSK << bitOffset);

        // Set target bits, leave others untouched.
        tempGAFR |= alternateFunction << bitOffset;
        XsGpioRegsP->GAFRs[regIndex] = tempGAFR;  // Write to HW

        // Record the change 
        currPinCfgP->fnCategory = alternateFunction;

        IRQ_EnableInterrupts (previousIntState);
    } // if (!status)   No SW problems, do the job

    return(status);

} // XsGpioSetAlternateFunction () 


//=============================== ================================

UINT32 XsGpioGetLevel (XsGpioIdT pinID, XsGpioPinLevelT *level)

{
    UINT32  status;
    INT     regIndex;       // For GPIO register addressing.
    INT     bitOffset;      // For GPIO register addressing.
    UINT32  tempGPLR;

    status = XsGpioRangeCheckPinId (pinID);
    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                              ERR_S_XSGPIO_GET_LEVEL, status, pinID, 0, 0)
    }
    else
    {
        XsGpioRegsCalcLocIndices ( pinID, &regIndex, &bitOffset );

        // Get current value of pin set
        tempGPLR = XsGpioRegsP->GPLRs[regIndex];
        // Isolate target pin level and normalize to LSB
        *level = (tempGPLR >> bitOffset) & 1;
    }

    return(status);

} // XsGpioGetLevel ()

//=============================== ================================
UINT32 XsGpioSetLevel (XsGpioIdT pinID, XsGpioPinLevelT level)
// For general purpose use, performed with interrupt protection.
{
    UINT32   status;
    INT      regIndex;       // For GPIO register addressing.
    INT      bitOffset;      // For GPIO register addressing.
    PVUINT32 targetRegP;
    INT      previousIntState;

    status = XsGpioRangeCheckPinId (pinID);

    if (!status)
    {
        if (XS_GPIO_UNAVAILABLE == 
                        XsGpioCurrentUsageTable[pinID].fnCategory)
        {
            status = ERR_T_NOT_AVAIL;
        }
    }

    if (!status)
    {
        // No SW problems, do the job
        XsGpioRegsCalcLocIndices ( pinID, &regIndex, &bitOffset );

        if (level)
        {   // For sets, use the GPIO Pin Output Set Register
            targetRegP = &XsGpioRegsP->GPSRs[regIndex];
        }
        else
        {   // For clears, use the GPIO Pin Output Clear Register
            targetRegP = &XsGpioRegsP->GPCRs[regIndex];
        }

        // Hardware access and record-keeping done under interrupt protection
        previousIntState = IRQ_DisableInterrupts (CPSR_I_Bit|CPSR_F_Bit);

        *targetRegP = 1u << bitOffset;      // Just write a "1" to target bit

        IRQ_EnableInterrupts (previousIntState); // Restore state

    } // if (!status) No SW problems, do the job
    else
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                              ERR_S_XSGPIO_SET_LEVEL, status, pinID, 0, 0)
    }

    return(status);
} // XsGpioSetLevel

//=============================== ================================
UINT32 XsGpioSetLevelIsr (XsGpioIdT pinID, XsGpioPinLevelT level)
// For speed, assumes interrupt protection.  Intended for use in ISRs.
{
    UINT32  status;
    INT     regIndex;       // For GPIO register addressing.
    INT     bitOffset;      // For GPIO register addressing.

    status = XsGpioRangeCheckPinId (pinID);
    if (status)
    {
        LOGERROR (XsGpioContext.loggedError, ERR_L_XSGPIO, 
                              ERR_S_XSGPIO_SET_LEVEL, status, pinID, 0, 0)
    }
    else
    {
        XsGpioRegsCalcLocIndices ( pinID, &regIndex, &bitOffset );

        if (level)
        {   // Write a "1" to target bit in GPIO Pin Output Set Register
            XsGpioRegsP->GPSRs[regIndex] = 1u << bitOffset;
        }
        else
        {   // Write a "1" to target bit in GPIO Pin Output Clear Register
            XsGpioRegsP->GPCRs[regIndex] = 1u << bitOffset;
        }
    }

    return(status);

} // XsGpioSetLevelIsr ()


// Set the pins needed by the STUART or ICP to that alternate function.  These functions are expected 
//  to be used to toggle them betweeen STUART and ICP, and it is assumed that they will never be used 
//  for GPIO in the systems where this function is used.  Also, the only two pins affected in this
//  are Rx and Tx data, so initial levels are not important.  The ICP and STUART devices should both 
//  be disabled (clocks off) when either of these calls are made.

// Note that the alternate function selector values are reversed for ICP and STUART between the 
//  Rx and Tx capabilities.

void XsGpioSetIcp (void)
{
    // First move target pins to GPIO function, then to target functions
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_ALT_FUNC_GPIO);
	(void) XsGpioSetDirection (XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_0);
	(void) XsGpioSetDirection (XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_1);

    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_ALT_FUNC_1);
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_ALT_FUNC_2);
}    


void XsGpioSetStuart (void)
{
    // First move target pins to GPIO function, then to target functions
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_ALT_FUNC_GPIO);
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_ALT_FUNC_GPIO);
	(void) XsGpioSetDirection (XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_0);
	(void) XsGpioSetDirection (XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_DIR_OUT, XS_GPIO_PIN_LEVEL_1);

    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_RX, XS_GPIO_ALT_FUNC_2);
    (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_ICPSTUART_TX, XS_GPIO_ALT_FUNC_1);
}    

void XsGpioSetSspExtClock (UINT device)
{
	switch (device & 0x03)
	{
		case SSP1:
            (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_SSP1_EXTCLK, XS_GPIO_ALT_FUNC_GPIO);
	        (void) XsGpioSetDirection (XS_GPIO_ID_SSP1_EXTCLK, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_0);
            (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_SSP1_EXTCLK, XS_GPIO_ALT_FUNC_1);
			break;
		case SSP2:
            (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_0);
            (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_SSP2_EXTCLK, XS_GPIO_ALT_FUNC_1);
			break;
		case SSP3:
            break;
	}
}    

void XsGpioClearSspExtClock (UINT device)
{
	switch (device & 0x03)
	{
		case SSP1:
            (void) XsGpioSetAlternateFunction ( XS_GPIO_ID_SSP1_EXTCLK, XS_GPIO_ALT_FUNC_GPIO);
	        (void) XsGpioSetDirection (XS_GPIO_ID_SSP1_EXTCLK, XS_GPIO_DIR_IN, XS_GPIO_PIN_LEVEL_X);
			break;
		case SSP2:

⌨️ 快捷键说明

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