123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- //*****************************************************************************
- //
- // am_hal_sysctrl.c
- //! @file
- //!
- //! @brief Functions for interfacing with the M4F system control registers
- //!
- //! @addtogroup sysctrl2 System Control (SYSCTRL)
- //! @ingroup apollo2hal
- //! @{
- //
- //*****************************************************************************
- //*****************************************************************************
- //
- // Copyright (c) 2017, Ambiq Micro
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are met:
- //
- // 1. Redistributions of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // 2. Redistributions in binary form must reproduce the above copyright
- // notice, this list of conditions and the following disclaimer in the
- // documentation and/or other materials provided with the distribution.
- //
- // 3. Neither the name of the copyright holder nor the names of its
- // contributors may be used to endorse or promote products derived from this
- // software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //
- // This is part of revision 1.2.11 of the AmbiqSuite Development Package.
- //
- //*****************************************************************************
- #include <stdint.h>
- #include <stdbool.h>
- #include "am_mcu_apollo.h"
- //*****************************************************************************
- //
- // Local macro constants
- //
- //*****************************************************************************
- //
- // Define ZX workaround values.
- // These values are defined by the factory.
- //
- #define COREZXVALUE 0x07
- #define MEMZXVALUE 0x07
- //
- // Define values for g_ui32CoreBuck, which indicates which timer carries
- // the signal for the CORE Buck, and which also implies that the other timer
- // carries the signal for the MEM buck.
- //
- #define COREBUCK_TIMERA 1 // Core buck signal comes in on timer A
- #define COREBUCK_TIMERB 2 // Core buck signal comes in on timer B
- //
- // Define the bit values for static function g_buckZX_chk;
- //
- #define CHKBUCKZX_BUCKS 0x01 // The bucks are enabled
- #define CHKBUCKZX_REV 0x02 // This chip rev needs the workaround
- #define CHKBUCKZX_TIMER 0x04 // A valid timer has been allocated
- #define CHKBUCKZX_DEVEN 0x08 // Devices are powered up and enabled
- //*****************************************************************************
- //
- // Prototypes
- //
- //*****************************************************************************
- static void am_hal_sysctrl_buckA_ctimer_isr(void);
- static void am_hal_sysctrl_buckB_ctimer_isr(void);
- //*****************************************************************************
- //
- // Globals
- //
- //*****************************************************************************
- static volatile uint32_t g_ui32BuckTimer = 0;
- static volatile uint32_t g_ui32BuckInputs = 0;
- static volatile bool g_bBuckRestoreComplete = false;
- static volatile bool g_bBuckTimed = false;
- static uint32_t g_ui32SaveCoreBuckZX, g_ui32SaveMemBuckZX;
- static uint32_t g_buckZX_chk = 0;
- static volatile uint32_t g_ui32CoreBuck;
- //
- // Timer configuration for BUCK inputs.
- //
- static const am_hal_ctimer_config_t g_sBuckTimer =
- {
- // Don't link timers.
- 0,
- // Set up Timer0A.
- (AM_HAL_CTIMER_FN_ONCE |
- AM_HAL_CTIMER_INT_ENABLE |
- AM_HAL_CTIMER_BUCK),
- // Set up Timer0B.
- (AM_HAL_CTIMER_FN_ONCE |
- AM_HAL_CTIMER_INT_ENABLE |
- AM_HAL_CTIMER_BUCK),
- };
- //*****************************************************************************
- //
- // Determine if we need to do the zero cross workaround on this device.
- // Three criteria are used. All three must be true.
- // 1. Are the bucks enabled?
- // 2. Is the chip rev appropriate for the workaround?
- // 3. Has a timer been allocated to do the workaround?
- // 4. Are certain peripherals powered up?
- //
- // Saves the bitmask to the global g_buckZX_chk.
- // Bitmask bits are defined as: CHKBUCKZX_BUCKS, CHKBUCKZX_REV, CHKBUCKZX_TIMER.
- //
- // Returns true if all criteria are met, false otherwise.
- // g_buckZX_chk can be probed to determine which criteria passed or failed.
- //
- //*****************************************************************************
- static bool
- buckZX_chk(void)
- {
- uint32_t ui32SupplySrc;
- //
- // Is this chip rev appropriate to do the workaround?
- //
- g_buckZX_chk = AM_BFM(MCUCTRL, CHIPREV, REVMAJ) == AM_REG_MCUCTRL_CHIPREV_REVMAJ_B ?
- CHKBUCKZX_REV : 0x0;
- //
- // Has a timer been configured to handle the workaround?
- //
- g_buckZX_chk |= ( g_ui32BuckTimer - 1 ) <= BUCK_TIMER_MAX ?
- CHKBUCKZX_TIMER : 0x0;
- //
- // Are either or both of the bucks actually enabled?
- //
- ui32SupplySrc = AM_REG(PWRCTRL, SUPPLYSRC);
- g_buckZX_chk |= (ui32SupplySrc &
- (AM_REG_PWRCTRL_SUPPLYSRC_COREBUCKEN_M |
- AM_REG_PWRCTRL_SUPPLYSRC_MEMBUCKEN_M) ) ?
- CHKBUCKZX_BUCKS : 0x0;
- //
- // Finally, if any peripheral is already powered up, we don't need to do the
- // ZX workaround because in this case the bucks remain in active mode.
- //
- ui32SupplySrc = AM_REG(PWRCTRL, DEVICEEN);
- g_buckZX_chk |= ( ui32SupplySrc &
- (AM_REG_PWRCTRL_DEVICEEN_PDM_M |
- AM_REG_PWRCTRL_DEVICEEN_UART1_M |
- AM_REG_PWRCTRL_DEVICEEN_UART0_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER5_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER4_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER3_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER2_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER1_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_MASTER0_M |
- AM_REG_PWRCTRL_DEVICEEN_IO_SLAVE_M) ) ?
- 0x0 : CHKBUCKZX_DEVEN;
- //
- // If all 4 criteria were met, we're good to do the workaround.
- //
- return ( g_buckZX_chk ==
- (CHKBUCKZX_BUCKS | CHKBUCKZX_REV |
- CHKBUCKZX_TIMER | CHKBUCKZX_DEVEN) ) ? true : false;
- }
- //*****************************************************************************
- //
- // Set the buck zero cross settings to the values given.
- //
- // ui32Flags, one or more of the following:
- // SETBUCKZX_USE_PROVIDED_SETTINGS - Use the values provided in the parameters
- // to set the trim value(s).
- // SETBUCKZX_USE_SAVED_SETTINGS - Use the values that were previously saved
- // to set the trim value(s).
- // SETBUCKZX_SAVE_CURR_SETTINGS - Save the current trim values before
- // setting the new ones.
- // SETBUCKZX_RESTORE_CORE_ONLY - Restore the Core trim and save the current
- // value of the core buck trim iff
- // SETBUCKZX_SAVE_CURR_SETTINGS is set.
- // SETBUCKZX_RESTORE_MEM_ONLY - Restore the Mem trim and save the current
- // value of the mem buck trim iff
- // SETBUCKZX_SAVE_CURR_SETTINGS is set.
- // SETBUCKZX_RESTORE_BOTH - Restore both buck trims and save the
- // current value of both iff
- // SETBUCKZX_SAVE_CURR_SETTINGS is set.
- //
- //*****************************************************************************
- #define SETBUCKZX_USE_PROVIDED_SETTINGS 0x01
- #define SETBUCKZX_USE_SAVED_SETTINGS 0x02
- #define SETBUCKZX_SAVE_CURR_SETTINGS 0x04
- #define SETBUCKZX_RESTORE_CORE_ONLY 0x10
- #define SETBUCKZX_RESTORE_MEM_ONLY 0x20
- #define SETBUCKZX_RESTORE_BOTH ( SETBUCKZX_RESTORE_CORE_ONLY | \
- SETBUCKZX_RESTORE_MEM_ONLY )
- static void
- setBuckZX(uint32_t ui32CoreBuckZX, uint32_t ui32MemBuckZX, uint32_t ui32Flags)
- {
- uint32_t ui32SaveCore, ui32SaveMem, ui32NewCore, ui32NewMem;
- bool bDoRestore = false;
- //
- // Begin critical section.
- //
- AM_CRITICAL_BEGIN_ASM
- //
- // Get the current zero cross trim values.
- //
- ui32SaveCore = AM_BFR(MCUCTRL, BUCK3, COREBUCKZXTRIM);
- ui32SaveMem = AM_BFR(MCUCTRL, BUCK3, MEMBUCKZXTRIM);
- //
- // Determine which values will be restored.
- //
- if ( ui32Flags & SETBUCKZX_USE_SAVED_SETTINGS )
- {
- //
- // Use saved settings
- //
- ui32NewCore = g_ui32SaveCoreBuckZX;
- ui32NewMem = g_ui32SaveMemBuckZX;
- bDoRestore = true;
- }
- else if ( ui32Flags & SETBUCKZX_USE_PROVIDED_SETTINGS )
- {
- //
- // Use settings provided in the call parameters
- //
- ui32NewCore = ui32CoreBuckZX;
- ui32NewMem = ui32MemBuckZX;
- bDoRestore = true;
- }
- //
- // Restore the buck Core and Mem trim registers.
- //
- if ( bDoRestore )
- {
- if ( ui32Flags & SETBUCKZX_RESTORE_CORE_ONLY )
- {
- AM_BFW(MCUCTRL, BUCK3, COREBUCKZXTRIM, ui32NewCore);
- }
- if ( ui32Flags & SETBUCKZX_RESTORE_MEM_ONLY )
- {
- AM_BFW(MCUCTRL, BUCK3, MEMBUCKZXTRIM, ui32NewMem);
- }
- }
- if ( ui32Flags & SETBUCKZX_SAVE_CURR_SETTINGS )
- {
- //
- // Save off the zero cross values as read on entry to the function.
- //
- if ( ui32Flags & SETBUCKZX_RESTORE_CORE_ONLY )
- {
- g_ui32SaveCoreBuckZX = ui32SaveCore;
- }
- if ( ui32Flags & SETBUCKZX_RESTORE_MEM_ONLY )
- {
- g_ui32SaveMemBuckZX = ui32SaveMem;
- }
- }
- //
- // Done with critical section.
- //
- AM_CRITICAL_END_ASM
- }
- //*****************************************************************************
- //
- //! @brief Place the core into sleep or deepsleep.
- //!
- //! @param bSleepDeep - False for Normal or True Deep sleep.
- //!
- //! This function puts the MCU to sleep or deepsleep depending on bSleepDeep.
- //!
- //! Valid values for bSleepDeep are:
- //!
- //! AM_HAL_SYSCTRL_SLEEP_NORMAL
- //! AM_HAL_SYSCTRL_SLEEP_DEEP
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_sleep(bool bSleepDeep)
- {
- uint32_t ui32Critical;
- // uint32_t ui32DebugGpioSleep = g_ui32DebugGpioSleep - 1;
- bool bBuckZX_chk;
- volatile uint32_t ui32BuckTimer;
- //
- // Disable interrupts and save the previous interrupt state.
- //
- ui32Critical = am_hal_interrupt_master_disable();
- //
- // If the user selected DEEPSLEEP and the TPIU is off, attempt to enter
- // DEEP SLEEP.
- //
- if ((bSleepDeep == AM_HAL_SYSCTRL_SLEEP_DEEP) &&
- (AM_BFM(MCUCTRL, TPIUCTRL, ENABLE) == AM_REG_MCUCTRL_TPIUCTRL_ENABLE_DIS))
- {
- //
- // Prepare the core for deepsleep (write 1 to the DEEPSLEEP bit).
- //
- AM_BFW(SYSCTRL, SCR, SLEEPDEEP, 1);
- //
- // Check if special buck handling is needed
- //
- bBuckZX_chk = buckZX_chk();
- if ( bBuckZX_chk )
- {
- ui32BuckTimer = g_ui32BuckTimer - 1;
- //
- // Before going to sleep, clear the buck timers.
- // This will also handle the case where we're going back to
- // sleep before the buck sequence has even completed.
- //
- am_hal_ctimer_clear(ui32BuckTimer, AM_HAL_CTIMER_BOTH);
- //
- // Set CMPR0 of both timerA and timerB to the period value
- //
- #define TIMER_PERIOD_BUCKS 1
- am_hal_ctimer_period_set(ui32BuckTimer,
- AM_HAL_CTIMER_BOTH,
- TIMER_PERIOD_BUCKS |
- (TIMER_PERIOD_BUCKS << 16),
- 0);
- //
- // Disable bucks before going to sleep.
- //
- am_hal_pwrctrl_bucks_disable();
- }
- //
- // Execute the sleep instruction.
- //
- AM_ASM_WFI;
- //
- // Return from sleep
- //
- if ( bBuckZX_chk )
- {
- //
- // Adjust the core and mem trims
- //
- setBuckZX(COREZXVALUE, MEMZXVALUE,
- SETBUCKZX_USE_PROVIDED_SETTINGS |
- SETBUCKZX_RESTORE_BOTH );
- //
- // Delay for 2us before enabling bucks.
- //
- am_hal_flash_delay( FLASH_CYCLES_US(2) );
- //
- // Turn on the bucks
- //
- am_hal_pwrctrl_bucks_enable();
- //
- // Get the actual timer number
- //
- ui32BuckTimer = g_ui32BuckTimer - 1;
- //
- // Initialize the complete flag
- //
- g_bBuckRestoreComplete = false;
- //
- // Initialize the input flags
- //
- g_ui32BuckInputs = 0;
- //
- // Delay for 5us to make sure we're receiving clean buck signals.
- //
- am_hal_flash_delay( FLASH_CYCLES_US(5) );
- //
- // Start timers (set the enable bit, clear the clear bit)
- //
- am_hal_ctimer_start(ui32BuckTimer, AM_HAL_CTIMER_BOTH);
- }
- else
- {
- //
- // Since we're not doing anything, we're done, so set the done flag.
- //
- g_bBuckRestoreComplete = true;
- }
- }
- else
- {
- //
- // Prepare the core for normal sleep (write 0 to the DEEPSLEEP bit).
- //
- AM_BFW(SYSCTRL, SCR, SLEEPDEEP, 0);
- //
- // Go to sleep.
- //
- AM_ASM_WFI;
- }
- //
- // Restore the interrupt state.
- //
- am_hal_interrupt_master_set(ui32Critical);
- }
- //*****************************************************************************
- //
- //! @brief Enable the floating point module.
- //!
- //! Call this function to enable the ARM hardware floating point module.
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_fpu_enable(void)
- {
- //
- // Enable access to the FPU in both privileged and user modes.
- // NOTE: Write 0s to all reserved fields in this register.
- //
- AM_REG(SYSCTRL, CPACR) = (AM_REG_SYSCTRL_CPACR_CP11(0x3) |
- AM_REG_SYSCTRL_CPACR_CP10(0x3));
- }
- //*****************************************************************************
- //
- //! @brief Disable the floating point module.
- //!
- //! Call this function to disable the ARM hardware floating point module.
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_fpu_disable(void)
- {
- //
- // Disable access to the FPU in both privileged and user modes.
- // NOTE: Write 0s to all reserved fields in this register.
- //
- AM_REG(SYSCTRL, CPACR) = 0x00000000 &
- ~(AM_REG_SYSCTRL_CPACR_CP11(0x3) |
- AM_REG_SYSCTRL_CPACR_CP10(0x3));
- }
- //*****************************************************************************
- //
- //! @brief Enable stacking of FPU registers on exception entry.
- //!
- //! @param bLazy - Set to "true" to enable "lazy stacking".
- //!
- //! This function allows the core to save floating-point information to the
- //! stack on exception entry. Setting the bLazy option enables "lazy stacking"
- //! for interrupt handlers. Normally, mixing floating-point code and interrupt
- //! driven routines causes increased interrupt latency, because the core must
- //! save extra information to the stack upon exception entry. With the lazy
- //! stacking option enabled, the core will skip the saving of floating-point
- //! registers when possible, reducing average interrupt latency.
- //!
- //! @note This function should be called before the floating-point module is
- //! used in interrupt-driven code. If it is not called, the core will not have
- //! any way to save context information for floating-point variables on
- //! exception entry.
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_fpu_stacking_enable(bool bLazy)
- {
- if ( bLazy )
- {
- //
- // Enable automatic saving of FPU registers on exception entry, using lazy
- // context saving.
- //
- AM_REG(SYSCTRL, FPCCR) |= (AM_REG_SYSCTRL_FPCCR_ASPEN(0x1) |
- AM_REG_SYSCTRL_FPCCR_LSPEN(0x1));
- }
- else
- {
- //
- // Enable automatic saving of FPU registers on exception entry.
- //
- AM_REG(SYSCTRL, FPCCR) |= AM_REG_SYSCTRL_FPCCR_ASPEN(0x1);
- }
- }
- //*****************************************************************************
- //
- //! @brief Disable FPU register stacking on exception entry.
- //!
- //! This function disables all stacking of floating point registers for
- //! interrupt handlers.
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_fpu_stacking_disable(void)
- {
- //
- // Enable automatic saving of FPU registers on exception entry, using lazy
- // context saving.
- //
- AM_REG(SYSCTRL, FPCCR) &= ~(AM_REG_SYSCTRL_FPCCR_ASPEN(0x1) |
- AM_REG_SYSCTRL_FPCCR_LSPEN(0x1));
- }
- //*****************************************************************************
- //
- //! @brief Issue a system wide reset using the AIRCR bit in the M4 system ctrl.
- //!
- //! This function issues a system wide reset (Apollo POR level reset).
- //!
- //! @return None.
- //
- //*****************************************************************************
- void
- am_hal_sysctrl_aircr_reset(void)
- {
- //
- // Set the system reset bit in the AIRCR register
- //
- AM_REG(SYSCTRL, AIRCR) = AM_REG_SYSCTRL_AIRCR_VECTKEY(0x5FA) |
- AM_REG_SYSCTRL_AIRCR_SYSRESETREQ(1);
- }
- //*****************************************************************************
- //
- //! @brief Buck CTimer ISR initializer.
- //!
- //! @param ui32BuckTimerNumber - Timer number to be used for handling the buck.
- //! Must be 0-3.
- //!
- //! If called with an invalid timer (that is, not 0 - 3, or greater than
- //! BUCK_TIMER_MAX), then the workaround will not be enabled.
- //!
- //! Instead, the bucks will be initialized with a value that will avoid the
- //! issues described in the Errata (ERR019). However, this will cause a
- //! less efficient energy usage condtion.
- //!
- //! @return 0.
- //
- //*****************************************************************************
- uint32_t
- am_hal_sysctrl_buck_ctimer_isr_init(uint32_t ui32BuckTimerNumber)
- {
- uint32_t ui32RetVal = 0;
- //
- // Initialize the input flags
- //
- g_ui32BuckInputs = 0;
- //
- // Initialize operation complete flag
- //
- g_bBuckRestoreComplete = false;
- //
- // Initialize to assume there is no valid timer.
- //
- g_ui32BuckTimer = 0;
- if ( ui32BuckTimerNumber > BUCK_TIMER_MAX )
- {
- if ( ( ui32BuckTimerNumber & 0xFFFF0000 ) ==
- AM_HAL_SYSCTRL_BUCK_CTIMER_ZX_CONSTANT )
- {
- //
- // The caller is asking for the hard option, which changes the
- // settings to the more noise-immune, if less efficient, settings.
- // While we're at it, go ahead and save off the current settings.
- //
- if ( (ui32BuckTimerNumber & 0x0000FFFF) == 0 )
- {
- setBuckZX(COREZXVALUE, MEMZXVALUE,
- SETBUCKZX_USE_PROVIDED_SETTINGS |
- SETBUCKZX_SAVE_CURR_SETTINGS |
- SETBUCKZX_RESTORE_BOTH );
- }
- else
- {
- uint32_t ui32Core, ui32Mem;
- //
- // Use the setting provided in the parameter.
- //
- ui32Core = (((ui32BuckTimerNumber & 0x001F) >> 0) - 1) & 0xF;
- ui32Mem = (((ui32BuckTimerNumber & 0x1F00) >> 8) - 1) & 0xF;
- setBuckZX(ui32Core, ui32Mem,
- SETBUCKZX_USE_PROVIDED_SETTINGS |
- SETBUCKZX_SAVE_CURR_SETTINGS |
- SETBUCKZX_RESTORE_BOTH );
- }
- }
- }
- else
- {
- //
- // Save off the current trim settings (but don't change any settings).
- //
- setBuckZX(0, 0, SETBUCKZX_SAVE_CURR_SETTINGS | SETBUCKZX_RESTORE_BOTH);
- //
- // The timer number will be maintained as (n + 1). Therefore, a value
- // of 0 saved in the global is an invalid timer. 1=timer0, 2=timer1...
- //
- g_ui32BuckTimer = ui32BuckTimerNumber + 1;
- //
- // Register the timer ISRs
- //
- am_hal_ctimer_int_register( AM_HAL_CTIMER_INT_TIMERA0C0 <<
- (ui32BuckTimerNumber * 2),
- am_hal_sysctrl_buckA_ctimer_isr );
- am_hal_ctimer_int_register( AM_HAL_CTIMER_INT_TIMERB0C0 <<
- (ui32BuckTimerNumber * 2),
- am_hal_sysctrl_buckB_ctimer_isr );
- //
- // Determine which timer input (A or B) is core buck and which is mem
- // buck based on the timer number.
- // For CTIMER 0 & 1: Timer A is mem buck, Timer B is core buck
- // For CTIMER 2 & 3: Timer A is core buck, Timer B is mem buck
- //
- if ( (ui32BuckTimerNumber == 0) || (ui32BuckTimerNumber == 1) )
- {
- //
- // Indicate that TimerB is core buck.
- //
- g_ui32CoreBuck = COREBUCK_TIMERB;
- }
- else
- {
- //
- // Indicate that TimerA is core buck
- //
- g_ui32CoreBuck = COREBUCK_TIMERA;
- }
- //
- // Clear and configure the timers
- //
- am_hal_ctimer_clear(ui32BuckTimerNumber, AM_HAL_CTIMER_BOTH);
- am_hal_ctimer_config(ui32BuckTimerNumber,
- (am_hal_ctimer_config_t*)&g_sBuckTimer);
- //
- // Enable the interrupts for timers A and B
- //
- am_hal_ctimer_int_enable( (AM_HAL_CTIMER_INT_TIMERA0C0 |
- AM_HAL_CTIMER_INT_TIMERB0C0 ) <<
- (ui32BuckTimerNumber * 2) );
- //
- // Enable the timer interrupt in the NVIC.
- //
- am_hal_interrupt_enable(AM_HAL_INTERRUPT_CTIMER);
- }
- return ui32RetVal;
- }
- //*****************************************************************************
- //
- // Get buck update complete status.
- //
- //*****************************************************************************
- bool
- am_hal_sysctrl_buck_update_complete(void)
- {
- return g_bBuckRestoreComplete;
- }
- //*****************************************************************************
- //
- // Buck CTIMER ISR (for handling buck switching via TimerA).
- //
- // Note: This handler assumes that the interrupt is cleared in am_ctimer_isr().
- //
- //*****************************************************************************
- static void
- am_hal_sysctrl_buckA_ctimer_isr(void)
- {
- //
- // Begin critical section.
- // Although a relatively long time, the following 2us delay is critically
- // timed for re-trimming the buck and thus cannot be extended. Therefore,
- // we must keep it inside the critical section.
- //
- AM_CRITICAL_BEGIN_ASM
- //
- // Delay for 2us.
- //
- am_hal_flash_delay( FLASH_CYCLES_US(2) );
- //
- // Determine which buck (core or mem) needs to be updated.
- //
- if ( g_ui32CoreBuck == COREBUCK_TIMERA )
- {
- //
- // Timer A buck signal is the CORE buck.
- // Restore the core buck.
- //
- setBuckZX(0, 0, SETBUCKZX_RESTORE_CORE_ONLY |
- SETBUCKZX_USE_SAVED_SETTINGS );
- }
- else
- {
- //
- // Timer A buck signal is the MEM buck.
- // Restore the mem buck.
- //
- setBuckZX(0, 0, SETBUCKZX_RESTORE_MEM_ONLY |
- SETBUCKZX_USE_SAVED_SETTINGS );
- }
- g_ui32BuckInputs |= 0x1;
- if ( g_ui32BuckInputs == 0x3 )
- {
- g_bBuckRestoreComplete = true;
- g_ui32BuckInputs = 0;
- }
- //
- // End critical section.
- //
- AM_CRITICAL_END_ASM
- }
- //*****************************************************************************
- //
- // Buck CTIMER ISR (for handling buck switching via TimerB).
- //
- // Note: This handler assumes that the interrupt is cleared in am_ctimer_isr().
- //
- //*****************************************************************************
- static void
- am_hal_sysctrl_buckB_ctimer_isr(void)
- {
- //
- // Begin critical section.
- // Although a relatively long time, the following 2us delay is critically
- // timed for re-trimming the buck and thus cannot be extended. Therefore,
- // we must keep it inside the critical section.
- //
- AM_CRITICAL_BEGIN_ASM
- //
- // Delay for 2us.
- //
- am_hal_flash_delay( FLASH_CYCLES_US(2) );
- //
- // Determine which buck (core or mem) needs to be updated.
- //
- if ( g_ui32CoreBuck == COREBUCK_TIMERB )
- {
- //
- // Timer B buck signal is the CORE buck.
- // Restore the core buck.
- //
- setBuckZX(0, 0, SETBUCKZX_RESTORE_CORE_ONLY |
- SETBUCKZX_USE_SAVED_SETTINGS );
- }
- else
- {
- //
- // Timer B buck signal is the MEM buck.
- // Restore the mem buck.
- //
- setBuckZX(0, 0, SETBUCKZX_RESTORE_MEM_ONLY |
- SETBUCKZX_USE_SAVED_SETTINGS );
- }
- g_ui32BuckInputs |= 0x2;
- if ( g_ui32BuckInputs == 0x3 )
- {
- g_bBuckRestoreComplete = true;
- g_ui32BuckInputs = 0;
- }
- //
- // End critical section.
- //
- AM_CRITICAL_END_ASM
- }
- //*****************************************************************************
- //
- // End Doxygen group.
- //! @}
- //
- //*****************************************************************************
|