//***************************************************************************** // // am_hal_burst.c //! @file //! //! @brief Functions for controlling Burst Mode operation. //! //! @addtogroup burstmode3p //! @ingroup apollo3phal //! @{ // //***************************************************************************** //***************************************************************************** // // Copyright (c) 2020, 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. // // Third party software included in this distribution is subject to the // additional license terms as defined in the /docs/licenses directory. // // 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 2.4.2 of the AmbiqSuite Development Package. // //***************************************************************************** #include #include #include "am_mcu_apollo.h" // // Globals. // bool g_am_hal_burst_mode_available = false; // **************************************************************************** // // am_hal_burst_mode_initialize() // Burst mode initialization function // // **************************************************************************** uint32_t am_hal_burst_mode_initialize(am_hal_burst_avail_e *peBurstAvail) { uint32_t ui32Status; // // Check if the Burst Mode feature is available based on the SKU. // if ( 0 == MCUCTRL->SKU_b.ALLOWBURST ) { // // Burst mode is not available. // g_am_hal_burst_mode_available = false; *peBurstAvail = AM_HAL_BURST_NOTAVAIL; return AM_HAL_STATUS_INVALID_OPERATION; } // // Enable the Burst Feature Event (DEVPWREVENTEN). // PWRCTRL->DEVPWREVENTEN_b.BURSTEVEN = 1; // // BLE buck is shared by Burst as well // Enable the BLE buck trim values if in use // if (PWRCTRL->SUPPLYSRC_b.BLEBUCKEN) { am_hal_pwrctrl_blebuck_trim(); } // // Enable the Burst Functionality (FEATUREENABLE). // MCUCTRL->FEATUREENABLE_b.BURSTREQ = 1; ui32Status = am_hal_flash_delay_status_check(10000, (uint32_t)&MCUCTRL->FEATUREENABLE, MCUCTRL_FEATUREENABLE_BURSTACK_Msk, MCUCTRL_FEATUREENABLE_BURSTACK_Msk, true); if ( ui32Status != AM_HAL_STATUS_SUCCESS ) { g_am_hal_burst_mode_available = false; *peBurstAvail = AM_HAL_BURST_NOTAVAIL; return ui32Status; } if ( 0 == MCUCTRL->FEATUREENABLE_b.BURSTAVAIL ) { // // Burst mode is not available. // g_am_hal_burst_mode_available = false; *peBurstAvail = AM_HAL_BURST_NOTAVAIL; return AM_HAL_STATUS_INVALID_OPERATION; } // // Check the ACK for the Burst Functionality. // if ( MCUCTRL->FEATUREENABLE_b.BURSTACK == 0 ) { // // If NACK, return status. // g_am_hal_burst_mode_available = false; *peBurstAvail = AM_HAL_BURST_NOTAVAIL; return AM_HAL_STATUS_INVALID_OPERATION; } // // Return Availability // g_am_hal_burst_mode_available = true; *peBurstAvail = AM_HAL_BURST_AVAIL; return AM_HAL_STATUS_SUCCESS; } // **************************************************************************** // // am_hal_burst_mode_enable() // Burst mode enable function // // **************************************************************************** uint32_t am_hal_burst_mode_enable(am_hal_burst_mode_e *peBurstStatus) { uint32_t ui32Status; // // Check if Burst Mode is allowed and return status if it is not. // if (!g_am_hal_burst_mode_available) { *peBurstStatus = AM_HAL_NORMAL_MODE; return AM_HAL_STATUS_INVALID_OPERATION; } // // Request Burst Mode Enable (FREQCTRL) // CLKGEN->FREQCTRL_b.BURSTREQ = CLKGEN_FREQCTRL_BURSTREQ_EN; // while (0 == AM_BFR(CLKGEN, FREQCTRL, BURSTACK)); ui32Status = am_hal_flash_delay_status_check(10000, (uint32_t)&CLKGEN->FREQCTRL, CLKGEN_FREQCTRL_BURSTSTATUS_Msk, CLKGEN_FREQCTRL_BURSTSTATUS_Msk, true); if ( ui32Status != AM_HAL_STATUS_SUCCESS ) { *peBurstStatus = AM_HAL_NORMAL_MODE; return ui32Status; } // // Check that the Burst Request was ACK'd. // if ( 0 == CLKGEN->FREQCTRL_b.BURSTACK ) { *peBurstStatus = AM_HAL_NORMAL_MODE; return AM_HAL_STATUS_FAIL; } // // Check the Burst Mode Status (FREQCTRL) // if ( CLKGEN->FREQCTRL_b.BURSTSTATUS > 0) { *peBurstStatus = AM_HAL_BURST_MODE; } else { *peBurstStatus = AM_HAL_NORMAL_MODE; } return AM_HAL_STATUS_SUCCESS; } // **************************************************************************** // // am_hal_burst_mode_disable() // Burst mode disable function // // **************************************************************************** uint32_t am_hal_burst_mode_disable(am_hal_burst_mode_e *peBurstStatus) { uint32_t ui32Status; // // Request Burst Mode Enable (FREQCTRL) // // // Safely disable burst mode. // AM_CRITICAL_BEGIN am_hal_flash_store_ui32((uint32_t*)&CLKGEN->FREQCTRL, CLKGEN_FREQCTRL_BURSTREQ_DIS); AM_CRITICAL_END // // Disable the Burst Feature Event (DEVPWREVENTEN). // PWRCTRL->DEVPWREVENTEN_b.BURSTEVEN = 0; ui32Status = am_hal_flash_delay_status_check(10000, (uint32_t)&CLKGEN->FREQCTRL, CLKGEN_FREQCTRL_BURSTSTATUS_Msk, 0, true); if ( ui32Status != AM_HAL_STATUS_SUCCESS ) { *peBurstStatus = AM_HAL_NORMAL_MODE; return ui32Status; } // // Check the Burst Mode Status (FREQCTRL) // // // Check the Burst Mode Status (FREQCTRL) // if ( CLKGEN->FREQCTRL_b.BURSTSTATUS > 0 ) { *peBurstStatus = AM_HAL_BURST_MODE; } else { *peBurstStatus = AM_HAL_NORMAL_MODE; } return AM_HAL_STATUS_SUCCESS; } //***************************************************************************** // // am_hal_burst_mode_status() - Return current burst mode state. // // Implemented as a macro, this function returns the current burst mode state. // AM_HAL_BURST_MODE // AM_HAL_NORMAL_MODE // //***************************************************************************** //***************************************************************************** // // End Doxygen group. //! @} // //*****************************************************************************