123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971 |
- //*****************************************************************************
- //
- // peci.c - Driver for the Platform Environment Control Interface (PECI)
- // module.
- //
- // Copyright (c) 2010-2011 Texas Instruments Incorporated. All rights reserved.
- // Software License Agreement
- //
- // Texas Instruments (TI) is supplying this software for use solely and
- // exclusively on TI's microcontroller products. The software is owned by
- // TI and/or its suppliers, and is protected under applicable copyright
- // laws. You may not combine this software with "viral" open-source
- // software in order to form a larger program.
- //
- // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
- // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
- // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
- // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
- // DAMAGES, FOR ANY REASON WHATSOEVER.
- //
- // This is part of revision 8264 of the Stellaris Peripheral Driver Library.
- //
- //*****************************************************************************
- //*****************************************************************************
- //
- //! \addtogroup peci_api
- //! @{
- //
- //*****************************************************************************
- #include "inc/hw_ints.h"
- #include "inc/hw_memmap.h"
- #include "inc/hw_peci.h"
- #include "inc/hw_sysctl.h"
- #include "inc/hw_types.h"
- #include "driverlib/debug.h"
- #include "driverlib/interrupt.h"
- #include "driverlib/peci.h"
- //*****************************************************************************
- //
- // The following defines provide characteristics of the PECI module that are
- // important to the driver but which can not be gleaned from the register
- // definitions.
- //
- //*****************************************************************************
- #define PECI_MAX_BAUD 2000000 // Maximum baud rate
- #define PECI_MIN_BAUD 2000 // Minimum baud rate
- #define PECI_MIN_RATIO 8 // Minimum baud rate divider
- #define PECI_MAX_RATIO 65535 // Maximum baud rate divider
- #define PECI_POLL_PRESCALE 4096 // Polling timer prescaler
- #define PECI_MIN_POLL 2 // Minimum polling interval (ms)
- #define PECI_MAX_POLL 1000 // Maximum polling interval (ms)
- //*****************************************************************************
- //
- //! \internal
- //! Checks a PECI domain.
- //!
- //! \param ulDomain is the PECI domain identifier.
- //!
- //! This function determines if a domain identifier is valid.
- //!
- //! \return Returns \b true if the domain identifier is valid and \b false
- //! otherwise.
- //
- //*****************************************************************************
- #ifdef DEBUG
- static tBoolean
- PECIDomainValid(unsigned long ulDomain)
- {
- return((ulDomain == PECI_DOMAIN_M0D0) ||
- (ulDomain == PECI_DOMAIN_M0D1) ||
- (ulDomain == PECI_DOMAIN_M1D0) ||
- (ulDomain == PECI_DOMAIN_M1D1));
- }
- #endif
- //*****************************************************************************
- //
- //! Sets the configuration of the PECI module.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulPECIClk is the rate of the clock supplied to the PECI module.
- //! \param ulBaud is the bit rate that should be used for the PECI transfers.
- //! \param ulPoll is the polling rate, in ms, that should be used for the
- //! time between PECI polls.
- //! \param ulOffset is the offset to be applied to all temperature values to
- //! convert from relative to absolute.
- //! \param ulRetry is the number of retry attempts for a PECI transaction.
- //!
- //! This function initializes operation of the PECI block. It programs the bit
- //! rate, polling rate and retry counts for PECI transactions. It also
- //! programs the offset value to be used to translate relative temperature
- //! values from PECI transactions to absolute values. At the end of this
- //! function, no host/domain combinations are enabled. Each desired
- //! host/domain combination can be configured/enabled with a call to
- //! PECIDomainEnable().
- //!
- //! The peripheral clock is the same as the processor clock. This value is
- //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is
- //! constant and known (to save the code/execution overhead of a call to
- //! SysCtlClockGet()).
- //!
- //! The \e ulBaud parameter defines the bit rate for the PECI transactions.
- //! This value is used to calculate a divisor value based on the specified
- //! \e ulPECIClk. If the exact baud rate cannot be achieved (due to rounding),
- //! the baud rate is programmed to the nearest value that is less than the
- //! specified value.
- //!
- //! The \e ulPoll parameter defines the polling rate, in milliseconds, used
- //! for PECI transactions. For generation of the polling rate, the \e
- //! ulPECIClk is pre-divided by \b 4096. A value of 0 disables the polling
- //! feature. If the exact polling rate cannot be achieved (due to rounding),
- //! the polling rate is programmed to the nearest value that is greater than
- //! the specified value.
- //!
- //! The \e ulRetry parameter defines the number of PECI transactions that are
- //! attempted before indicating an error condition.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIConfigSet(unsigned long ulBase, unsigned long ulPECIClk,
- unsigned long ulBaud, unsigned long ulPoll,
- unsigned long ulOffset, unsigned long ulRetry)
- {
- unsigned long ulTemp, ulDiv;
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(ulPECIClk != 0);
- ASSERT((ulBaud != 0) && (ulBaud <= PECI_MAX_BAUD) &&
- (ulBaud >= PECI_MIN_BAUD) &&
- ((ulBaud * 4 * PECI_MIN_RATIO) < ulPECIClk));
- ASSERT((ulPoll == 0) ||
- ((ulPoll >= PECI_MIN_POLL) && (ulPoll <= PECI_MAX_POLL)));
- //
- // Generate value for the PECI Control Register.
- //
- ulTemp = ((ulOffset << PECI_CTL_OFFSET_S) & PECI_CTL_OFFSET_M);
- ulTemp |= ((ulRetry << PECI_CTL_CRETRY_S) & PECI_CTL_CRETRY_M);
- HWREG(ulBase + PECI_O_CTL) = ulTemp;
- //
- // Compute the divisor for the PECI baud rate clock.
- // Round up, to ensure programmed baud rate is <= specified rate.
- // Ensure that proper ratio is maintained for clock:baud.
- //
- ulDiv = (ulPECIClk + (4 * ulBaud) - 1) / (4 * ulBaud);
- ulDiv = (ulDiv < PECI_MIN_RATIO) ? PECI_MIN_RATIO : ulDiv;
- ulDiv = (ulDiv > PECI_MAX_RATIO) ? PECI_MAX_RATIO : ulDiv;
- ulTemp = ((ulDiv << PECI_DIV_BAUD_S) & PECI_DIV_BAUD_M);
- //
- // Compute the divisor for the PECI polling rate.
- // Round up, to ensure programmed polling rate is >= specified rate.
- //
- ulDiv = ((ulPoll == 0) ? 0 : ((((ulPECIClk * ulPoll) / 1000) +
- (PECI_POLL_PRESCALE - 1)) /
- PECI_POLL_PRESCALE));
- ulTemp |= ((ulDiv << PECI_DIV_POLL_S) & PECI_DIV_POLL_M);;
- HWREG(ulBase + PECI_O_DIV) = ulTemp;
- }
- //*****************************************************************************
- //
- //! Gets the current configuration of the PECI module.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulPECIClk is the rate of the clock supplied to the PECI module.
- //! \param pulBaud is a pointer to storage for the bit rate.
- //! \param pulPoll is a pointer to storage for the polling rate.
- //! \param pulOffset is a pointer to stoarage for the offset.
- //! \param pulRetry is a pointer to storage for the retry count.
- //!
- //! The baud rate and poll rate for the PECI module are determined, given an
- //! explicitly provided peripheral clock. The returned rates are the actual
- //! rates being used; they may not be the same as the requested rates, due to
- //! rounding in the calculations.
- //!
- //! The peripheral clock is the same as the processor clock. This value is
- //! returned by SysCtlClockGet(), or it can be explicitly hard coded if it is
- //! constant and known (to save the code/execution overhead of a call to
- //! SysCtlClockGet()).
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIConfigGet(unsigned long ulBase, unsigned long ulPECIClk,
- unsigned long *pulBaud, unsigned long *pulPoll,
- unsigned long *pulOffset, unsigned long *pulRetry)
- {
- unsigned long ulTemp;
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(ulPECIClk != 0);
- ASSERT(*pulBaud != 0);
- ASSERT(*pulPoll != 0);
- ASSERT(*pulOffset != 0);
- ASSERT(*pulRetry != 0);
- //
- // Retrieve the Offset and Retry values
- //
- ulTemp = HWREG(ulBase + PECI_O_CTL);
- *pulOffset = ((ulTemp & PECI_CTL_OFFSET_M) >> PECI_CTL_OFFSET_S);
- *pulRetry = ((ulTemp & PECI_CTL_CRETRY_M) >> PECI_CTL_CRETRY_S);
- //
- // Calculate the baud rate.
- //
- ulTemp = HWREG(ulBase + PECI_O_DIV);
- *pulBaud = ulPECIClk / ((ulTemp & PECI_DIV_BAUD_M) >> PECI_DIV_BAUD_S);
- //
- // Compute the divisor for the PECI polling rate.
- // Round up, to ensure programmed polling rate is >= specified rate.
- //
- *pulPoll = ((((ulTemp & PECI_DIV_POLL_M) >> PECI_DIV_POLL_S) * 1000) /
- (ulPECIClk / PECI_POLL_PRESCALE));
- }
- //*****************************************************************************
- //
- //! Enables bypassing of negotiation errors.
- //!
- //! \param ulBase is the base address of the PECI module.
- //!
- //! This function enables bypassing of negotiation errors that might occur
- //! during a PECI transaction. When enabled, negotiation errors are ignored.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIBypassEnable(unsigned long ulBase)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Enable bypass.
- //
- HWREG(ulBase + PECI_O_CTL) |= PECI_CTL_BYERR;
- }
- //*****************************************************************************
- //
- //! Disables bypassing of negotiation errors.
- //!
- //! \param ulBase is the base address of the PECI module.
- //!
- //! This function disables bypassing of negotiation errors that might occur
- //! during a PECI transaction. When disabled, negotiation errors are reported
- //! and the remainder of the transaction is aborted.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIBypassDisable(unsigned long ulBase)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Disable bypass.
- //
- HWREG(ulBase + PECI_O_CTL) &= ~PECI_CTL_BYERR;
- }
- //*****************************************************************************
- //
- //! Sets the configuration of the specified PECI domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be configured.
- //! \param ulHigh is the high temperature threshold value.
- //! \param ulLow is the low temperature threshold value.
- //!
- //! This function configures the specified PECI domain for temperature
- //! monitoring operations. The values for \e ulHigh and \e ulLow can be
- //! specified as values relative to the maximum temperature allowed, or they
- //! can be specified as absolute temperatures if an offset was programmed
- //! in the PECIConfigSet() function.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainConfigSet(unsigned long ulBase, unsigned long ulDomain,
- unsigned long ulHigh, unsigned long ulLow)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- ASSERT(ulHigh <= 0xFFFF);
- ASSERT(ulLow <= 0xFFFF);
- ASSERT(ulHigh > ulLow);
- //
- // Set the HTHRESH and LTHRESH fields in the domain control/status
- // register.
- //
- HWREG(ulBase + PECI_O_M0D0C + (ulDomain * 4)) =
- (((ulHigh << PECI_M0D0C_HITHR_S) & PECI_M0D0C_HITHR_M) |
- ((ulLow << PECI_M0D0C_LOTHR_S) & PECI_M0D0C_LOTHR_M));
- }
- //*****************************************************************************
- //
- //! Gets the configuration of the specified PECI domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be configured.
- //! \param pulHigh is a pointer to storage for the high threshold.
- //! \param pulLow is a pointer to storage for the low threshold.
- //!
- //! This function configures the specified PECI domain for temperature
- //! monitoring operations. The values for \e ulHigh and \e ulLow can be
- //! specified as values relative to the maximum temperature allowed, or they
- //! can be specified as absolute temperatures if an offset was programmed
- //! in the PECIConfigSet() function.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainConfigGet(unsigned long ulBase, unsigned long ulDomain,
- unsigned long *pulHigh, unsigned long *pulLow)
- {
- unsigned long ulTemp;
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- ASSERT(pulHigh != 0);
- ASSERT(pulLow != 0);
- //
- // Get the HTHRESH and LTHRESH fields in the domain control/status
- // register.
- //
- ulTemp = HWREG(ulBase + PECI_O_M0D0C + (ulDomain * 4));
- *pulHigh = ((ulTemp && PECI_M0D0C_HITHR_M) >> PECI_M0D0C_HITHR_S);
- *pulLow = ((ulTemp && PECI_M0D0C_LOTHR_M) >> PECI_M0D0C_LOTHR_S);
- }
- //*****************************************************************************
- //
- //! Enables a domain within the PECI module.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be enabled.
- //!
- //! This function enables the specified PECI domain for temperature monitoring
- //! operations.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainEnable(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Enable the specified domain.
- //
- HWREG(ulBase + PECI_O_CTL) |= (1 << ulDomain);
- }
- //*****************************************************************************
- //
- //! Disables a domain within the PECI module.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be disabled.
- //!
- //! This function disables the specified PECI domain.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainDisable(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Disable the specified domain.
- //
- HWREG(ulBase + PECI_O_CTL) &= ~(1 << ulDomain);
- }
- //*****************************************************************************
- //
- //! Reads the current temperature value for the specified domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be disabled.
- //!
- //! This function returns the most recently read temperature value from the
- //! specified domain.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- unsigned long
- PECIDomainValueGet(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Return the most recently polled temperature value
- //
- return(((HWREG(ulBase + PECI_O_M0D0 + (ulDomain * 4)) &
- PECI_M0D0_VALUE_M)));
- }
- //*****************************************************************************
- //
- //! Reads the maximum/error value for the specified domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be disabled.
- //!
- //! This function returns the maximum temperature value for the specified
- //! domain.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- unsigned long
- PECIDomainMaxReadGet(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Return the most recently polled temperature value
- //
- return(((HWREG(ulBase + PECI_O_M0D0 + (ulDomain * 4)) &
- PECI_M0D0_MAXREAD_M) >> PECI_M0D0_MAXREAD_S));
- }
- //*****************************************************************************
- //
- //! Clears the current temperature value for the specified domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be disabled.
- //!
- //! This function clears the current and maximum values for the specified
- //! domain.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainValueClear(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Clear the temperature value.
- //
- HWREG(ulBase + PECI_O_M0D0 + (ulDomain * 4) ) &= ~PECI_M0D0_VALUE_M;
- }
- //*****************************************************************************
- //
- //! Clears the maximum/error value for the specified domain.
- //!
- //! \param ulBase is the base address of the PECI module.
- //! \param ulDomain is the PECI domain that should be disabled.
- //!
- //! This function clears the current and maximum values for the specified
- //! domain.
- //!
- //! The \e ulDomain parameter can be one of the following values:
- //! \b PECI_DOMAIN_M0D0, \b PECI_DOMAIN_M0D1, \b PECI_DOMAIN_M1D0, or
- //! \b PECI_DOMAIN_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIDomainMaxReadClear(unsigned long ulBase, unsigned long ulDomain)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(PECIDomainValid(ulDomain));
- //
- // Clear the maximum/error value.
- //
- HWREG(ulBase + PECI_O_M0D0 + (ulDomain * 4) ) &= ~PECI_M0D0_MAXREAD_M;
- }
- //*****************************************************************************
- //
- //! Registers an interrupt handler for the PECI module.
- //!
- //! \param ulBase specifies the PECI module base address.
- //! \param pfnHandler is a pointer to the function to be called when the
- //! PECI interrupt occurs.
- //!
- //! This function registers the handler to be called when an PECI interrupt
- //! occurs. This function enables the global interrupt in the interrupt
- //! controller; specific PECI interrupts must be enabled via PECIIntEnable().
- //! If necessary, it is the interrupt handler's responsibility to clear the
- //! interrupt source via PECIIntClear().
- //!
- //! \sa IntRegister() for important information about registering interrupt
- //! handlers.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIIntRegister(unsigned long ulBase, void (*pfnHandler)(void))
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- ASSERT(pfnHandler != 0);
- //
- // Register the interrupt handler.
- //
- IntRegister(INT_PECI0, pfnHandler);
- //
- // Enable the PECI interrupt.
- //
- IntEnable(INT_PECI0);
- }
- //*****************************************************************************
- //
- //! Unregisters an interrupt handler for the PECI module.
- //!
- //! \param ulBase specifies the PECI module base address.
- //!
- //! This function unregisters the handler to be called when a PECI interrupt
- //! occurs. This function also masks off the interrupt in the interrupt
- //! controller so that the interrupt handler no longer is called.
- //!
- //! \sa IntRegister() for important information about registering interrupt
- //! handlers.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIIntUnregister(unsigned long ulBase)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Disable the PECI interrupt.
- //
- IntDisable(INT_PECI0);
- //
- // Unregister the interrupt handler.
- //
- IntUnregister(INT_PECI0);
- }
- //*****************************************************************************
- //
- //! Enables individual PECI interrupt sources.
- //!
- //! \param ulBase specifies the PECI module base address.
- //! \param ulIntFlags is a bit mask of the interrupt sources to be enabled.
- //! \param ulIntMode is the mode for the PECI domain interrupts.
- //!
- //! This function enables the indicated PECI interrupt sources. Only the
- //! sources that are enabled can be reflected to the processor interrupt;
- //! disabled sources have no effect on the processor.
- //!
- //! The \e ulIntFlags parameter can be any of the following values:
- //! \b PECI_READ, \b PECI_ERR, \b PECI_AC, \b PECI_M0D0, \b PECI_M0D1,
- //! \b PECI_M1D0, or \b PECI_M1D1.
- //!
- //! The \e ulIntMode parameter is used to configure the interrupt mode for
- //! the corresponding \b PECI_DOMAIN_MnDm field, and can be any of the
- //! following values: \b PECI_M0D0_MODE1, \b PECI_M0D0_MODE2,
- //! \b PECI_M0D0_MODE3, \b PECI_M0D1_MODE1, \b PECI_M0D1_MODE2,
- //! \b PECI_M0D1_MODE3. \b PECI_M1D0_MODE1, \b PECI_M1D0_MODE2,
- //! \b PECI_M1D0_MODE3, \b PECI_M1D1_MODE1, \b PECI_M1D1_MODE2, or
- //! \b PECI_M1D1_MODE3.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIIntEnable(unsigned long ulBase, unsigned long ulIntFlags,
- unsigned long ulIntMode)
- {
- unsigned long ulTemp;
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Get the current mask value.
- //
- ulTemp = HWREG(ulBase + PECI_O_IM);
- //
- // Clear the bit/bit-fields that are configured, based on the value
- // in the flags parameter.
- //
- ulTemp &= ~ulIntFlags;
- //
- // Set/Enable the bit/bit-fields based on the value in the flags and mode
- // parameter. The flags parameter alters the bits in the lower half
- // of the mask, while the mode alters the bit fields in the upper
- // half of the mask.
- //
- ulTemp |= (0x0000FFFF & ulIntFlags);
- ulTemp |= (0xFFFF0000 & ulIntMode);
- HWREG(ulBase + PECI_O_IM) = ulTemp;
- }
- //*****************************************************************************
- //
- //! Disables individual PECI interrupt sources.
- //!
- //! \param ulBase specifies the PECI module base address.
- //! \param ulIntFlags is a bit mask of the interrupt sources to be disabled.
- //!
- //! This function disables the indicated PECI interrupt sources. Only the
- //! sources that are enabled can be reflected to the processor interrupt;
- //! disabled sources have no effect on the processor.
- //!
- //! The \e ulIntFlags parameter can be any of the following values:
- //! \b PECI_READ, \b PECI_ERR, \b PECI_AC, \b PECI_M0D0, \b PECI_M0D1,
- //! \b PECI_M1D0, or \b PECI_M1D1.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIIntDisable(unsigned long ulBase, unsigned long ulIntFlags)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Disable the specified interrupts.
- //
- HWREG(ulBase + PECI_O_IM) &= ~ulIntFlags;
- }
- //*****************************************************************************
- //
- //! Gets the current interrupt status.
- //!
- //! \param ulBase specifies the PECI module base address.
- //! \param bMasked is \b false if the raw interrupt status is required or
- //! \b true if the masked interrupt status is required.
- //!
- //! This function returns the interrupt status for the PECI module. Either the
- //! raw interrupt status or the status of interrupts that are allowed to
- //! reflect to the processor can be returned.
- //!
- //! The interpretation of the PECI_DOMAIN_MnDm fields vary based on the mode
- //! value programed using the PECIIntEnable() function for the field. Each
- //! field may take on one of the following values:
- //! \b PECI_MnDm_MODE1_HIGH, \b PECI_MnDm_MODE2_MID, \b PECI_MnDm_MODE2_HIGH,
- //! \b PECI_MnDm_MODE3_LOW, \b PECI_MnDm_MODE3_MID, or \b PECI_MnDm_MODE3_HIGH.
- //!
- //! \return The current interrupt status, enumerated as a bit field of
- //! \b PECI_READ, \b PECI_ERR, \b PECI_AC, \b PECI_M0D0, \b PECI_M0D1,
- //! \b PECI_M1D0, or \b PECI_M1D1.
- //
- //*****************************************************************************
- unsigned long
- PECIIntStatus(unsigned long ulBase, tBoolean bMasked)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Return either the interrupt status or the raw interrupt status as
- // requested.
- //
- if(bMasked)
- {
- return(HWREG(ulBase + PECI_O_MIS));
- }
- else
- {
- return(HWREG(ulBase + PECI_O_RIS));
- }
- }
- //*****************************************************************************
- //
- //! Clears PECI interrupt sources.
- //!
- //! \param ulBase specifies the PECI module base address.
- //! \param ulIntFlags is a bit mask of the interrupt sources to be cleared.
- //!
- //! This function clears the specified PECI interrupt sources so that they no
- //! longer assert. This function must be called in the interrupt handler to
- //! keep the interrupts from being recognized again immediately upon exit.
- //! The \e ulIntFlags parameter can consist of any combination of the
- //! \b PECI_READ, \b PECI_ERR, \b PECI_AC, \b PECI_M0D0, \b PECI_M0D1,
- //! \b PECI_M1D0, or \b PECI_M1D1 values.
- //!
- //! \note Because there is a write buffer in the Cortex-M processor, it may
- //! take several clock cycles before the interrupt source is actually cleared.
- //! Therefore, it is recommended that the interrupt source be cleared early in
- //! the interrupt handler (as opposed to the very last action) to avoid
- //! returning from the interrupt handler before the interrupt source is
- //! actually cleared. Failure to do so may result in the interrupt handler
- //! being immediately reentered (because the interrupt controller still sees
- //! the interrupt source asserted).
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIIntClear(unsigned long ulBase, unsigned long ulIntFlags)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Clear the requested interrupt sources.
- //
- HWREG(ulBase + PECI_O_IC) = ulIntFlags;
- }
- //*****************************************************************************
- //
- //! Sends a PECI Advanced Command.
- //!
- //! \param ulBase specifies the PECI module base address.
- //!
- //! This function sends a PECI Advanced Command. If the interface is not IDLE,
- //! it waits for the interface to become IDLE then sends the command. The
- //! function parameters are used to populate the message control fields before
- //! activating the command.
- //!
- //! \return None.
- //
- //*****************************************************************************
- void
- PECIAdvCmdSend(unsigned long ulBase, unsigned char ucCmd,
- unsigned char ucHidRe, unsigned char ucDomain,
- unsigned char ucProcAdd, unsigned long ulArg,
- unsigned char ucSize, unsigned long ulData0,
- unsigned long ulData1)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Wait for the interface to be idle.
- //
- while(HWREG(ulBase + PECI_O_ACCODE) == 0xFFFFFFFF)
- {
- }
- //
- // Fill in the registers for the advanced command.
- //
- HWREG(ulBase + PECI_O_ACARG) = ulArg;
- HWREG(ulBase + PECI_O_ACRDWR0) = ulData0;
- HWREG(ulBase + PECI_O_ACRDWR1) = ulData1;
- HWREG(ulBase + PECI_O_ACADDR) = (ucHidRe << 24) |
- (ucSize << 16) |
- (ucDomain << 8) |
- (ucProcAdd << 0);
- //
- // Now, issue the command.
- //
- HWREG(ulBase + PECI_O_ACCMD) = ucCmd;
- }
- //*****************************************************************************
- //
- //! Sends a PECI Advanced Command (non blocking).
- //!
- //! \param ulBase specifies the PECI module base address.
- //!
- //! This function sends a PECI Advanced Command. If the interface is not IDLE,
- //! it returns immediately. Otherwise, it sends the the command. The function
- //! paramters are used to populate the message control fields before activating
- //! the command.
- //!
- //! \return None.
- //
- //*****************************************************************************
- unsigned long
- PECIAdvCmdSendNonBlocking(unsigned long ulBase, unsigned char ucCmd,
- unsigned char ucHidRe, unsigned char ucDomain,
- unsigned char ucProcAdd, unsigned long ulArg,
- unsigned char ucSize, unsigned long ulData0,
- unsigned long ulData1)
- {
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // Check for the interface to be idle.
- // If not, return immediately.
- //
- if(HWREG(ulBase + PECI_O_ACCODE) == 0xFFFFFFFF)
- {
- return(0);
- }
- //
- // Send the command.
- //
- PECIAdvCmdSend(ulBase, ucCmd, ucHidRe, ucDomain, ucProcAdd, ulArg,
- ucSize, ulData0, ulData1);
- //
- // Return, indicating that the command has been issued.
- //
- return(1);
- }
- //*****************************************************************************
- //
- //! Obtains status of previous PECI Advanced Command.
- //!
- //! \param ulBase specifies the PECI module base address.
- //!
- //! This function gets the status of a previously issued PECI Advanced Command.
- //! If the command has completed, and the data pointers are non-zero, the data
- //! registers are read and saved.
- //!
- //! \return -1 if command has not yet been completed, otherwise, the return
- //! code associated with the Advanced Command.
- //
- //*****************************************************************************
- unsigned long
- PECIAdvCmdStatusGet(unsigned long ulBase, unsigned long *pulData0,
- unsigned long *pulData1)
- {
- unsigned long ulCode;
- //
- // Check the arguments.
- //
- ASSERT(ulBase == PECI0_BASE);
- //
- // If the command has completed, optionally read and save the data
- // registers.
- //
- ulCode = HWREG(ulBase + PECI_O_ACCODE);
- if(ulCode != 0xFFFFFFFF)
- {
- if(pulData0 != (void *)0)
- {
- *pulData0 = HWREG(ulBase + PECI_O_ACRDWR0);
- }
- if(pulData1 != (void *)0)
- {
- *pulData1 = HWREG(ulBase + PECI_O_ACRDWR1);
- }
- }
- //
- // Return the command code from the most recently completed command.
- //
- return(ulCode);
- }
- //*****************************************************************************
- //
- // Close the Doxygen group.
- //! @}
- //
- //*****************************************************************************
|