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

📄 xsac97ctrl.c

📁 优龙YLP270开发板 光盘自带的BIOS和实验例程源码 强烈推荐
💻 C
📖 第 1 页 / 共 5 页
字号:
*                   when a specified AC'97 interrupt type occurs.  Also
*                   register a pointer that will be passed to that handler.
*
*                   Critical section is performed under interrupt protection.
*
* INPUT PARAMETERS:
*  XsAc97CtrlIdT          interruptTypeId   - int type to register handler for
*  XsAc97CtrlHandlerFnPT  clientHandlerFnP  - Handler to be called for int.
*  void *                 paramP      - Pointer to be passed to reg. handler
*
* RETURNS:
*       Success: 0 (ERR_NONE)
*       Failure: ERR_T_ILLPARAM    - Interrupt type ID out of range
*                ERR_T_NOT_AVAIL   - Interrupt type ID unsupported
*                ERR_T_REG_HANDLER - pin already has a registered handler
*
* GLOBAL EFFECTS:
*       - Required for XsAc97CtrlEnableIntType().
*       - Records last detected failure condition
*
* ASSUMPTIONS:
*
* CALLS:
*
* CALLED BY:
*
* Notes:
*   - Does not enable the interrupt: use XsAc97CtrlEnableIntType() afterwards.
*
* PROTOTYPE:        UINT32 XsAc97CtrlRegisterHandler (XsAc97CtrlIdT,
*                                                     XsAc97CtrlHandlerFnPT,
*                                                     void *)
*
*******************************************************************************
*/

ErrorT XsAc97CtrlRegisterHandler ( XsAc97CtrlIntIdT      interruptTypeId,
                                   XsAc97CtrlHandlerFnPT clientHandlerFnP,
                                   void *                paramP)
{
    ErrorT retVal;
    UINT32 irqIntState;
    XsAc97CtrlStatusEntryT*  currIntTypeCfgP;

    retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);

    irqIntState = XsIcDisableInterruptsIrq();       // Begin atomic zone.

    if (!retVal)
    {   // Interrupt type ID is safe.  Check other conditions.

        // Map interrupt type ID onto retVal IDs and get pointer into table.
        currIntTypeCfgP = XsAc97CtrlStatusTable +
            XsAc97CtrlIntToStatusTransTbl[interruptTypeId];

        if (currIntTypeCfgP->registeredHandlerFnP)
        {
            retVal = ERR_T_REG_HANDLER;     // Can't overwrite existing hndlr
        }
    }

    if (retVal)
    {
        LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
            ERR_S_XSAC97CTRL_REG_HANDLER, retVal, 0, 0, 0)
    }
    else // No problems, register the handler.
    {
        currIntTypeCfgP->registeredHandlerFnP = clientHandlerFnP;
        currIntTypeCfgP->registeredParamP     = paramP;
    }

    XsIcRestoreInterruptsIrq (irqIntState);         // End atomic zone.

    return (retVal);

} // XsAc97CtrlRegisterHandler ()


/*
*******************************************************************************
*
* FUNCTION:         XsAc97CtrlUnRegisterHandler
*
* DESCRIPTION:      Disable any interrupt of the specified AC '97 Controller
*                   interrupt type and unregister any registered handler for it.
*                   The only error is out-of-range interrupt type ID;
*
* INPUT PARAMETERS: XsAc97CtrlIdT interruptTypeId - AC'97 interrupt type
*                                                   to unregister handler for
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   Failure: ERR_T_ILLPARAM  - Interrupt type ID out of range
*                            ERR_T_NOT_AVAIL - Interrupt type ID unsupported
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:      None
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE:        UINT32 XsAc97CtrlUnRegisterHandler (XsAc97CtrlIdT);
*
*******************************************************************************
*/

ErrorT XsAc97CtrlUnRegisterHandler (XsAc97CtrlIntIdT interruptTypeId)
{
    ErrorT retVal ;
    UINT32 irqIntState ;
    XsAc97CtrlStatusEntryT*  currIntTypeCfgP ;

    irqIntState = XsIcDisableInterruptsIrq();   // Begin atomic zone.

    // Also checks interruptTypeId
    retVal = XsAc97CtrlDisableIntType (interruptTypeId);

    if (retVal)
    {
        LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
            ERR_S_XSAC97CTRL_UNR_HANDLER, retVal, 0, 0, 0)
    }
    else    // Interrupt disabled for interrupt type.  Unregister.
    {

        // Map interrupt type ID onto retVal IDs and get pointer into table.
        currIntTypeCfgP = XsAc97CtrlStatusTable +
            XsAc97CtrlIntToStatusTransTbl[interruptTypeId];

        currIntTypeCfgP->registeredHandlerFnP = NULL;
        currIntTypeCfgP->registeredParamP     = NULL;
    }

    XsIcRestoreInterruptsIrq (irqIntState);     // End atomic zone.

    return(retVal);

} // XsAc97CtrlUnRegisterHandler ()


/*
*******************************************************************************
*
* FUNCTION:         XsAc97CtrlEnableIntType
*
* DESCRIPTION:      Enable interrupts for the specified AC '97 Controller
*                   interrupt type.  An interrupt handling subroutine must
*                   already be registered.  Performed under interrupt protection.
*                   Clears any existing interrupt triggering indication on
*                   specified interrupt type before enabling.
*
*                   Gracefully does nothing if already enabled.
*
* INPUT PARAMETERS: XsAc97CtrlIntIdT interruptTypeId - ID for AC '97 interrupt
*                                                      type to enable
*
* RETURNS:
*       Success: 0 (ERR_NONE)
*       Failure: ERR_T_ILLPARAM    - Interrupt type ID out of range
*                ERR_T_NOT_AVAIL   - Interrupt type ID unsupported
*                ERR_T_NO_HANDLER  - interrupt type lacks a registered handler
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:
*
* CALLS:            XsAc97CtrlCheckStatus
*                   XsAc97CtrlRangeCheckIntTypeId
*
* CALLED BY:
*
* PROTOTYPE:        UINT32 XsAc97CtrlEnableIntType (XsAc97CtrlIdT);
*
*******************************************************************************
*/

ErrorT XsAc97CtrlEnableIntType (XsAc97CtrlIntIdT interruptTypeId)
{
    ErrorT retVal ;
    UINT32 irqIntState ;

    XsAc97CtrlStatusEntryT*  currIntTypeCfgP;

    // Look for out of range IDs and non-supported IDs
    retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);

    if (!retVal)
    {   // Valid ID, type is supported.

        // Map interrupt type ID onto retVal IDs and get pointer into table.
        currIntTypeCfgP = XsAc97CtrlStatusTable +
            XsAc97CtrlIntToStatusTransTbl[interruptTypeId];

        // Only enable interrupts that have registered handlers.
        if (NULL == currIntTypeCfgP->registeredHandlerFnP)
        {
            retVal = ERR_T_NO_HANDLER;
        }
    } // Finished if !retVal: all error states checked.

    if (retVal)
    {
        LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
            ERR_S_XSAC97CTRL_ENAB_INT, retVal, 0, 0, 0)
    }
    // Act only if currently disabled.
    else if (FALSE == currIntTypeCfgP->intIsEnabled)
    {
        irqIntState = XsIcDisableInterruptsIrq();   // Begin atomic zone.

        // Clear old indications that might trigger spurious interrupt.
        // - Use side effect of status check subroutine.
        (void) XsAc97CtrlGetStatus (
            XsAc97CtrlIntToStatusTransTbl[interruptTypeId]);

        // Enable int type: All AC '97 Controller interrupt type enables
        //  are active high and controlled by a single bit.
        *currIntTypeCfgP->enableRegisterP |=
            (1u << currIntTypeCfgP->enableBitShift);

            currIntTypeCfgP->intIsEnabled = TRUE;       // Record new state

        XsIcRestoreInterruptsIrq (irqIntState);     // End atomic zone.

    } // Done else (retVal): range checked and supported, and if (not enabled).


    return(retVal);

} // XsAc97CtrlEnableIntType ()


/*
*******************************************************************************
*
* FUNCTION:         XsAc97CtrlDisableIntType
*
* DESCRIPTION:      Disable, if currently enabled, interrupts for the specified
*                   AC '97 Controller interrupt type.  Performed under
*                   interrupt protection.
*
*                   No-ops gracefully if not enabled.
*
* INPUT PARAMETERS: XsAc97CtrlIntIdT interruptTypeId - ID for AC '97 interrupt
*                                                       type to disable
*
* RETURNS:          Success: 0 (ERR_NONE)
*                   Failure: ERR_T_ILLPARAM  - Interrupt type ID out of range
*                            ERR_T_NOT_AVAIL - Interrupt type ID unsupported
*
* GLOBAL EFFECTS:   None
*
* ASSUMPTIONS:
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE:        UINT32 XsAc97CtrlDisableIntType (XsAc97CtrlIntIdT);
*
*******************************************************************************
*/

ErrorT XsAc97CtrlDisableIntType (XsAc97CtrlIntIdT interruptTypeId)
{
    ErrorT retVal ;
    UINT32 irqIntState;
    XsAc97CtrlStatusEntryT*  currIntTypeCfgP;

    retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);

    if (retVal)
    {
        LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
            ERR_S_XSAC97CTRL_DISAB_INT, retVal, 0, 0, 0)
    }
    else
    {
        // Map interrupt type ID onto retVal IDs and get pointer into table.
        currIntTypeCfgP = XsAc97CtrlStatusTable +
            XsAc97CtrlIntToStatusTransTbl[interruptTypeId];

        irqIntState = XsIcDisableInterruptsIrq();   // Begin atomic zone.

        if (TRUE == currIntTypeCfgP->intIsEnabled)
        {
            // All AC '97 Controller interrupt type enables are active high
            //  and controlled by a single bit.

            *currIntTypeCfgP->enableRegisterP &=
                ~(1u << currIntTypeCfgP->enableBitShift);

                currIntTypeCfgP->intIsEnabled = FALSE;  // Record new state

        } // Was enabled, so disabled it.

        XsIcRestoreInterruptsIrq (irqIntState);     // End atomic zone.

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

    return(retVal);

} // XsAc97CtrlDisablePinInt ()


/*
*******************************************************************************
*
* FUNCTION:         XsAc97CtrlGetStatus
*
* DESCRIPTION:      Reports the value of the specified status indicator, as
*                   obtained from the ACUNIT's GSR register.  Clears the
*                   status indicator, if possible, after reading it.
*
*                   Should not be used for status types that are currently in
*                   use as interrupt triggers.
*
* INPUT PARAMETERS: XsAc97CtrlStatusIdT statusId: ID of status indicator to get
*
* RETURNS:    Status indicator masked and normalized to bit 0.
*             Invalid ID: 0 (There is no direct reporting of invalid ID error).
*
* GLOBAL EFFECTS:   1) Because the status indicator is cleared, it will not be
*                       available to trigger an interrupt.
*                   2) If the specified status ID is invalid, an error is
*                       logged in the error log and the context structure.
*
* ASSUMPTIONS:      We don't have to double-check the hardware by making sure
*                   that a clearable status actually cleared.
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE:        UINT32 XsAc97CtrlGetStatus (XsAc97CtrlStatusIdT);
*
*******************************************************************************
*/

ErrorT XsAc97CtrlGetStatus (XsAc97CtrlStatusIdT statusId)
{
    UINT32                  statusIndication = 0;  // Assume bad ID
    UINT32                  rangeCheckResult;
    XsAc97CtrlStatusEntryT* statusTableEntryP;

⌨️ 快捷键说明

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