gecko: service files updated | Update to GSDK 4.4.0
Updated the files present in device_init, hfxo_manager, power_manager and sleeptimer folder as per latest version of gecko_sdk. Purpose of this PR is to align the codebase of hal_silabs with gecko_sdk 4.4.0 Signed-off-by: Sateesh Kotapati <sateesh.kotapati@silabs.com>
This commit is contained in:
parent
11ab59175a
commit
2ea874714e
|
@ -68,7 +68,7 @@
|
|||
// <cmuDPLLLockMode_Freq=> Frequency-Lock Loop
|
||||
// <cmuDPLLLockMode_Phase=> Phase-Lock Loop
|
||||
// <i> Default: cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Phase
|
||||
|
||||
// <q SL_DEVICE_INIT_DPLL_AUTORECOVER> Automatic Lock Recovery
|
||||
// <i> Default: 1
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_HFXO Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
#define SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_MODE> Mode
|
||||
// <i>
|
||||
// <cmuHfxoOscMode_Crystal=> Crystal oscillator
|
||||
// <cmuHfxoOscMode_ExternalSine=> External sine wave
|
||||
// <i> Default: cmuHfxoOscMode_Crystal
|
||||
#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_FREQ> Frequency <38000000-40000000>
|
||||
// <i> Default: 38400000
|
||||
#define SL_DEVICE_INIT_HFXO_FREQ 38400000
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_PRECISION> HFXO precision in PPM <0-65535>
|
||||
// <i> Default: 50
|
||||
#define SL_DEVICE_INIT_HFXO_PRECISION 50
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_CTUNE> CTUNE <0-255>
|
||||
// <i> Default: 140
|
||||
#define SL_DEVICE_INIT_HFXO_CTUNE 140
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_HFXO_CONFIG_H
|
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_DCDC Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
#define SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_ENABLE> Enable DC/DC Converter
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_ENABLE 1
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_BYPASS> Set DC/DC Converter in Bypass Mode
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_BYPASS 0
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE> Override for DCDC PFMX Mode Peak Current Setting
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE 1
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_PFMX_IPKVAL> DCDC PFMX Mode Peak Current Setting <0-15>
|
||||
// <i>
|
||||
// <i> Default: DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL 12
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_DCDC_CONFIG_H
|
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_DCDC Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
#define SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_ENABLE> Enable DC/DC Converter
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_ENABLE 1
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_BYPASS> Set DC/DC Converter in Bypass Mode
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_BYPASS 0
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE> Override for DCDC PFMX Mode Peak Current Setting
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE 1
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_PFMX_IPKVAL> DCDC PFMX Mode Peak Current Setting <0-15>
|
||||
// <i>
|
||||
// <i> Default: DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL 9
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_DCDC_CONFIG_H
|
|
@ -68,7 +68,7 @@
|
|||
// <cmuDPLLLockMode_Freq=> Frequency-Lock Loop
|
||||
// <cmuDPLLLockMode_Phase=> Phase-Lock Loop
|
||||
// <i> Default: cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Phase
|
||||
|
||||
// <q SL_DEVICE_INIT_DPLL_AUTORECOVER> Automatic Lock Recovery
|
||||
// <i> Default: 1
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_HFXO Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
#define SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_MODE> Mode
|
||||
// <i>
|
||||
// <cmuHfxoOscMode_Crystal=> Crystal oscillator
|
||||
// <cmuHfxoOscMode_ExternalSine=> External sine wave
|
||||
// <i> Default: cmuHfxoOscMode_Crystal
|
||||
#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_FREQ> Frequency <38000000-40000000>
|
||||
// <i> Default: 39000000
|
||||
#define SL_DEVICE_INIT_HFXO_FREQ 39000000
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_PRECISION> HFXO precision in PPM <0-65535>
|
||||
// <i> Default: 50
|
||||
#define SL_DEVICE_INIT_HFXO_PRECISION 50
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_CTUNE> CTUNE <0-255>
|
||||
// <i> Default: 140
|
||||
#define SL_DEVICE_INIT_HFXO_CTUNE 140
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_HFXO_CONFIG_H
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_DCDC Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
#define SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
|
||||
#include "sl_device_init_dcdc.h"
|
||||
#include "em_device.h"
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_ENABLE> Enable DC/DC Converter
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_ENABLE 1
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_TYPE> DC/DC Type
|
||||
// <SL_DEVICE_INIT_DCDC_TYPE_BUCK=> Buck
|
||||
// <SL_DEVICE_INIT_DCDC_TYPE_BOOST=> Boost
|
||||
// <i>
|
||||
// <i> Default: SL_DEVICE_INIT_DCDC_TYPE_BUCK
|
||||
#define SL_DEVICE_INIT_DCDC_TYPE SL_DEVICE_INIT_DCDC_TYPE_BOOST
|
||||
|
||||
// <h> DC/DC Buck Settings
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_BYPASS> Set DC/DC Converter in Bypass Mode
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_BYPASS 0
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE> Override for DCDC PFMX Mode Peak Current Setting
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE 0
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_PFMX_IPKVAL> DCDC PFMX Mode Peak Current Setting <0-15>
|
||||
// <i>
|
||||
// <i> Default: DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_DCDC_CONFIG_H
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_DCDC Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
#define SL_DEVICE_INIT_DCDC_CONFIG_H
|
||||
|
||||
#include "sl_device_init_dcdc.h"
|
||||
#include "em_device.h"
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_ENABLE> Enable DC/DC Converter
|
||||
// <i>
|
||||
// <i> Default: 1
|
||||
#define SL_DEVICE_INIT_DCDC_ENABLE 1
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_TYPE> DC/DC Type
|
||||
// <SL_DEVICE_INIT_DCDC_TYPE_BUCK=> Buck
|
||||
// <SL_DEVICE_INIT_DCDC_TYPE_BOOST=> Boost
|
||||
// <i>
|
||||
// <i> Default: SL_DEVICE_INIT_DCDC_TYPE_BUCK
|
||||
#define SL_DEVICE_INIT_DCDC_TYPE SL_DEVICE_INIT_DCDC_TYPE_BUCK
|
||||
|
||||
// <h> DC/DC Buck Settings
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_BYPASS> Set DC/DC Converter in Bypass Mode
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_BYPASS 0
|
||||
|
||||
// <q SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE> Override for DCDC PFMX Mode Peak Current Setting
|
||||
// <i>
|
||||
// <i> Default: 0
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL_OVERRIDE 0
|
||||
|
||||
// <o SL_DEVICE_INIT_DCDC_PFMX_IPKVAL> DCDC PFMX Mode Peak Current Setting <0-15>
|
||||
// <i>
|
||||
// <i> Default: DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
#define SL_DEVICE_INIT_DCDC_PFMX_IPKVAL DCDC_PFMXCTRL_IPKVAL_DEFAULT
|
||||
|
||||
// </h>
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_DCDC_CONFIG_H
|
|
@ -68,7 +68,7 @@
|
|||
// <cmuDPLLLockMode_Freq=> Frequency-Lock Loop
|
||||
// <cmuDPLLLockMode_Phase=> Phase-Lock Loop
|
||||
// <i> Default: cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Freq
|
||||
#define SL_DEVICE_INIT_DPLL_LOCKMODE cmuDPLLLockMode_Phase
|
||||
|
||||
// <q SL_DEVICE_INIT_DPLL_AUTORECOVER> Automatic Lock Recovery
|
||||
// <i> Default: 1
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DEVICE_INIT_HFXO Config
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2022 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
#define SL_DEVICE_INIT_HFXO_CONFIG_H
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_MODE> Mode
|
||||
// <i>
|
||||
// <cmuHfxoOscMode_Crystal=> Crystal oscillator
|
||||
// <cmuHfxoOscMode_ExternalSine=> External sine wave
|
||||
// <i> Default: cmuHfxoOscMode_Crystal
|
||||
#define SL_DEVICE_INIT_HFXO_MODE cmuHfxoOscMode_Crystal
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_FREQ> Frequency <38000000-40000000>
|
||||
// <i> Default: 38400000
|
||||
#define SL_DEVICE_INIT_HFXO_FREQ 38400000
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_PRECISION> HFXO precision in PPM <0-65535>
|
||||
// <i> Default: 50
|
||||
#define SL_DEVICE_INIT_HFXO_PRECISION 50
|
||||
|
||||
// <o SL_DEVICE_INIT_HFXO_CTUNE> CTUNE <0-255>
|
||||
// <i> Default: 140
|
||||
#define SL_DEVICE_INIT_HFXO_CTUNE 140
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
|
||||
#endif // SL_DEVICE_INIT_HFXO_CONFIG_H
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup device_init
|
||||
* @{
|
||||
|
@ -54,6 +58,13 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Defines
|
||||
|
||||
/// @brief DC/DC Converter Type
|
||||
#define SL_DEVICE_INIT_DCDC_TYPE_BUCK 0 ///< Buck Type
|
||||
#define SL_DEVICE_INIT_DCDC_TYPE_BOOST 1 ///< Boost Type
|
||||
|
||||
/**
|
||||
* Initialize DCDC
|
||||
*
|
||||
|
@ -70,4 +81,8 @@ sl_status_t sl_device_init_dcdc(void);
|
|||
* @} device_init
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_DEVICE_INIT_DCDC_H
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup device_init
|
||||
* @{
|
||||
|
@ -67,4 +71,8 @@ sl_status_t sl_device_init_dpll(void);
|
|||
* @} device_init
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_DEVICE_INIT_DPLL_H
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup device_init
|
||||
* @{
|
||||
|
@ -63,4 +67,8 @@ sl_status_t sl_device_init_hfrco(void);
|
|||
* @} device_init
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_DEVICE_INIT_HFRCO_H
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup device_init
|
||||
* @{
|
||||
|
@ -77,4 +81,8 @@ sl_status_t sl_device_init_hfxo(void);
|
|||
* @} device_init
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_DEVICE_INIT_HFXO_H
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include "sl_status.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup device_init
|
||||
* @{
|
||||
|
@ -67,4 +71,8 @@ sl_status_t sl_device_init_lfrco(void);
|
|||
* @} device_init
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SL_DEVICE_INIT_LFRCO_H
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
sl_status_t sl_device_init_dcdc(void)
|
||||
{
|
||||
#if !defined(SL_DEVICE_INIT_DCDC_TYPE) || (defined(SL_DEVICE_INIT_DCDC_TYPE) && (SL_DEVICE_INIT_DCDC_TYPE == SL_DEVICE_INIT_DCDC_TYPE_BUCK))
|
||||
#if SL_DEVICE_INIT_DCDC_ENABLE
|
||||
EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_DEFAULT;
|
||||
#if SL_DEVICE_INIT_DCDC_BYPASS
|
||||
|
@ -46,6 +47,11 @@ sl_status_t sl_device_init_dcdc(void)
|
|||
#else // SL_DEVICE_INIT_DCDC_ENABLE
|
||||
EMU_DCDCPowerOff();
|
||||
#endif // SL_DEVICE_INIT_DCDC_ENABLE
|
||||
|
||||
#else // SL_DEVICE_INIT_DCDC_TYPE
|
||||
#if SL_DEVICE_INIT_DCDC_ENABLE
|
||||
EMU_DCDCBoostInit_TypeDef dcdcBoostInit = EMU_DCDCBOOSTINIT_DEFAULT;
|
||||
EMU_DCDCBoostInit(&dcdcBoostInit);
|
||||
#endif
|
||||
#endif //SL_DEVICE_INIT_DCDC_TYPE
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ sl_status_t sl_device_init_dpll(void)
|
|||
// The CMU should not be running from the HFRCO. If necessary, the CMU
|
||||
// should switch to the FSRCO until after the DPLL has locked to avoid
|
||||
// over-clocking due to overshoot.
|
||||
CMU_ClockSelectSet(cmuClock_SYSCLK, cmuSelect_FSRCO);
|
||||
CMU_CLOCK_SELECT_SET(SYSCLK, FSRCO);
|
||||
}
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
|
||||
|
@ -62,7 +62,7 @@ sl_status_t sl_device_init_dpll(void)
|
|||
bool success = CMU_DPLLLock(&dpll_init);
|
||||
|
||||
if (selected_sysclk == cmuSelect_HFRCODPLL) {
|
||||
CMU_ClockSelectSet(cmuClock_SYSCLK, selected_sysclk);
|
||||
CMU_CLOCK_SELECT_SET(SYSCLK, HFRCODPLL);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
|
|
|
@ -41,6 +41,10 @@ sl_status_t sl_device_init_hfxo(void)
|
|||
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
|
||||
hfxoInit.mode = SL_DEVICE_INIT_HFXO_MODE;
|
||||
|
||||
if (SL_DEVICE_INIT_HFXO_MODE == cmuHfxoOscMode_ExternalSine) {
|
||||
hfxoInit = (CMU_HFXOInit_TypeDef)CMU_HFXOINIT_EXTERNAL_SINE;
|
||||
}
|
||||
|
||||
int ctune = -1;
|
||||
|
||||
#if defined(_DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK)
|
||||
|
@ -72,11 +76,12 @@ sl_status_t sl_device_init_hfxo(void)
|
|||
} else if (ctune > ((int)(_HFXO_XTALCTRL_CTUNEXOANA_MASK >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT))) {
|
||||
ctune = (int)(_HFXO_XTALCTRL_CTUNEXOANA_MASK >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT);
|
||||
}
|
||||
hfxoInit.ctuneXoAna = ctune;
|
||||
hfxoInit.ctuneXoAna = (uint8_t)ctune;
|
||||
}
|
||||
|
||||
SystemHFXOClockSet(SL_DEVICE_INIT_HFXO_FREQ);
|
||||
CMU_HFXOInit(&hfxoInit);
|
||||
CMU_HFXOPrecisionSet(SL_DEVICE_INIT_HFXO_PRECISION);
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
|
|
@ -1,84 +1,102 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager API definition.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SLI_HFXO_MANAGER_H
|
||||
#define SLI_HFXO_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO Manager module hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_init_hardware(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just before starting HFXO, to save current tick count.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_begin_startup_measurement(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just after HFXO becomes ready, to save current tick count
|
||||
* and calculate HFXO startup time.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_end_startup_measurement(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time average value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_startup_time(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time latest value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_latest_startup_time(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Checks if HFXO is ready and, if needed, waits for it to be.
|
||||
*
|
||||
* @param wait True, to wait for HFXO to be ready.
|
||||
* False, otherwise.
|
||||
*
|
||||
* @return True, if HFXO is ready.
|
||||
* False, otherwise.
|
||||
*
|
||||
* @note This will also make sure we are not in the process of restarting HFXO
|
||||
* with different settings.
|
||||
******************************************************************************/
|
||||
bool sli_hfxo_manager_is_hfxo_ready(bool wait);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SLI_HFXO_MANAGER_H */
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager API definition.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef SLI_HFXO_MANAGER_H
|
||||
#define SLI_HFXO_MANAGER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_SLEEPTIMER_PRESENT) && defined(SYSRTC_PRESENT)
|
||||
#include "sli_sleeptimer.h"
|
||||
#if (SL_SLEEPTIMER_PERIPHERAL == SL_SLEEPTIMER_PERIPHERAL_SYSRTC)
|
||||
#define HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO Manager module hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_init_hardware(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just before starting HFXO, to save current tick count.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_begin_startup_measurement(void);
|
||||
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
/***************************************************************************//**
|
||||
* Function to call when a SYSRTC compare match event produces a PRS signal to
|
||||
start HFXO.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_retrieve_begining_startup_measurement(void);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just after HFXO becomes ready, to save current tick count
|
||||
* and calculate HFXO startup time.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_end_startup_measurement(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time average value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_startup_time(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time latest value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_latest_startup_time(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Checks if HFXO is ready and, if needed, waits for it to be.
|
||||
*
|
||||
* @param wait True, to wait for HFXO to be ready.
|
||||
* False, otherwise.
|
||||
*
|
||||
* @return True, if HFXO is ready.
|
||||
* False, otherwise.
|
||||
*
|
||||
* @note This will also make sure we are not in the process of restarting HFXO
|
||||
* with different settings.
|
||||
******************************************************************************/
|
||||
bool sli_hfxo_manager_is_hfxo_ready(bool wait);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SLI_HFXO_MANAGER_H */
|
||||
|
|
|
@ -1,196 +1,235 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager API implementation.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_device.h"
|
||||
#include "sl_hfxo_manager.h"
|
||||
#include "sli_hfxo_manager.h"
|
||||
#include "sli_hfxo_manager_internal.h"
|
||||
#include "sl_sleeptimer.h"
|
||||
#include "sl_assert.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
// Table size of HFXO wake-up time measurement
|
||||
#define HFXO_STARTUP_TIME_TABLE_SIZE 10
|
||||
|
||||
// Default time value in microseconds required to wake-up the hfxo oscillator.
|
||||
#define HFXO_STARTUP_TIME_DEFAULT_VALUE_US (600u)
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** DATA TYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Time in ticks required for HFXO start-up after wake-up from sleep.
|
||||
static uint32_t hfxo_startup_time_tick = 0;
|
||||
|
||||
static uint32_t hfxo_last_startup_time = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_table[HFXO_STARTUP_TIME_TABLE_SIZE];
|
||||
|
||||
static uint8_t hfxo_startup_time_table_index = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_sum_average = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_tc_inital = 0;
|
||||
|
||||
static bool hfxo_measurement_on = false;
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO Manager module hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sl_hfxo_manager_init_hardware(void)
|
||||
{
|
||||
sli_hfxo_manager_init_hardware();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize HFXO Manager module.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_hfxo_manager_init(void)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
// Initialize Sleeptimer module in case not already done.
|
||||
status = sl_sleeptimer_init();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Set HFXO startup time to conservative default value
|
||||
hfxo_startup_time_tick = (((HFXO_STARTUP_TIME_DEFAULT_VALUE_US * sl_sleeptimer_get_timer_frequency()) + (1000000 - 1)) / 1000000);
|
||||
for (uint8_t i = 0; i < HFXO_STARTUP_TIME_TABLE_SIZE; i++) {
|
||||
hfxo_startup_time_table[i] = hfxo_startup_time_tick;
|
||||
hfxo_startup_time_sum_average += hfxo_startup_time_tick;
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates Sleepy Crystal settings.
|
||||
*
|
||||
* @param settings Pointer to settings structure
|
||||
*
|
||||
* @return Status Code.
|
||||
*
|
||||
* @note Those settings are temporarily used to force oscillation on sleepy
|
||||
* crystal.
|
||||
* Default values should be enough to wake-up sleepy crystals. Otherwise,
|
||||
* this function can be used.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_hfxo_manager_update_sleepy_xtal_settings(sl_hfxo_manager_sleepy_xtal_settings_t *settings)
|
||||
{
|
||||
return sli_hfxo_manager_update_sleepy_xtal_settings_hardware(settings);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* When this callback function is called, it means that HFXO failed twice in
|
||||
* a row to start with normal configurations. This may mean that there is a
|
||||
* bad crystal. When getting this callback, HFXO is running but its properties
|
||||
* (frequency, precision) are not guaranteed. This should be considered as an
|
||||
* error situation.
|
||||
******************************************************************************/
|
||||
__WEAK void sl_hfxo_manager_notify_consecutive_failed_startups(void)
|
||||
{
|
||||
EFM_ASSERT(false);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
********************** GLOBAL INTERNAL FUNCTIONS **************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just before starting HFXO, to save current tick count.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_begin_startup_measurement(void)
|
||||
{
|
||||
hfxo_measurement_on = true;
|
||||
hfxo_startup_time_tc_inital = sl_sleeptimer_get_tick_count();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just after HFXO becomes ready, to save current tick count
|
||||
* and calculate HFXO startup time.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_end_startup_measurement(void)
|
||||
{
|
||||
if (hfxo_measurement_on == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Complete HFXO restore time measurement
|
||||
hfxo_last_startup_time = sl_sleeptimer_get_tick_count() - hfxo_startup_time_tc_inital;
|
||||
|
||||
// With low precision clock, the HFXO startup time measure could be zero.
|
||||
// In that case, ensure it's a least 1 tick.
|
||||
hfxo_last_startup_time = (hfxo_last_startup_time == 0) ? 1 : hfxo_last_startup_time;
|
||||
|
||||
// Calculate average for HFXO restore time
|
||||
hfxo_startup_time_sum_average -= (int32_t)hfxo_startup_time_table[hfxo_startup_time_table_index] - (int32_t)hfxo_last_startup_time;
|
||||
hfxo_startup_time_table[hfxo_startup_time_table_index] = hfxo_last_startup_time;
|
||||
hfxo_startup_time_tick = ((hfxo_startup_time_sum_average + (HFXO_STARTUP_TIME_TABLE_SIZE - 1) ) / HFXO_STARTUP_TIME_TABLE_SIZE);
|
||||
|
||||
// Update index of wakeup time table
|
||||
hfxo_startup_time_table_index++;
|
||||
hfxo_startup_time_table_index %= HFXO_STARTUP_TIME_TABLE_SIZE;
|
||||
|
||||
hfxo_measurement_on = false;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time average value.
|
||||
*
|
||||
* @return HFXO startup time average value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_startup_time(void)
|
||||
{
|
||||
return hfxo_startup_time_tick;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time latest value.
|
||||
*
|
||||
* @return HFXO startup time latest value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_latest_startup_time(void)
|
||||
{
|
||||
return hfxo_last_startup_time;
|
||||
}
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager API implementation.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_device.h"
|
||||
#include "sl_hfxo_manager.h"
|
||||
#include "sli_hfxo_manager.h"
|
||||
#include "sli_hfxo_manager_internal.h"
|
||||
#include "sl_sleeptimer.h"
|
||||
#include "sl_assert.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
// Table size of HFXO wake-up time measurement
|
||||
#define HFXO_STARTUP_TIME_TABLE_SIZE 10
|
||||
|
||||
// Default time value in microseconds required to wake-up the hfxo oscillator.
|
||||
#define HFXO_STARTUP_TIME_DEFAULT_VALUE_US (600u)
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** DATA TYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Time in ticks required for HFXO start-up after wake-up from sleep.
|
||||
static uint32_t hfxo_startup_time_tick = 0;
|
||||
|
||||
static uint32_t hfxo_last_startup_time = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_table[HFXO_STARTUP_TIME_TABLE_SIZE];
|
||||
|
||||
static uint8_t hfxo_startup_time_table_index = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_sum_average = 0;
|
||||
|
||||
static uint32_t hfxo_startup_time_tc_initial = 0;
|
||||
|
||||
static bool hfxo_measurement_on = false;
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO Manager module hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sl_hfxo_manager_init_hardware(void)
|
||||
{
|
||||
sli_hfxo_manager_init_hardware();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Initialize HFXO Manager module.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_hfxo_manager_init(void)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
||||
// Initialize Sleeptimer module in case not already done.
|
||||
status = sl_sleeptimer_init();
|
||||
if (status != SL_STATUS_OK) {
|
||||
return status;
|
||||
}
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
// Additional Sleeptimer HW configuration if SYSRTC is used
|
||||
sli_sleeptimer_hal_hfxo_manager_integration_init();
|
||||
#endif
|
||||
|
||||
// Set HFXO startup time to conservative default value
|
||||
hfxo_startup_time_tick = (((HFXO_STARTUP_TIME_DEFAULT_VALUE_US * sl_sleeptimer_get_timer_frequency()) + (1000000 - 1)) / 1000000);
|
||||
for (uint8_t i = 0; i < HFXO_STARTUP_TIME_TABLE_SIZE; i++) {
|
||||
hfxo_startup_time_table[i] = hfxo_startup_time_tick;
|
||||
hfxo_startup_time_sum_average += hfxo_startup_time_tick;
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates Sleepy Crystal settings.
|
||||
*
|
||||
* @param settings Pointer to settings structure
|
||||
*
|
||||
* @return Status Code.
|
||||
*
|
||||
* @note Those settings are temporarily used to force oscillation on sleepy
|
||||
* crystal.
|
||||
* Default values should be enough to wake-up sleepy crystals. Otherwise,
|
||||
* this function can be used.
|
||||
******************************************************************************/
|
||||
sl_status_t sl_hfxo_manager_update_sleepy_xtal_settings(sl_hfxo_manager_sleepy_xtal_settings_t *settings)
|
||||
{
|
||||
return sli_hfxo_manager_update_sleepy_xtal_settings_hardware(settings);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* When this callback function is called, it means that HFXO failed twice in
|
||||
* a row to start with normal configurations. This may mean that there is a
|
||||
* bad crystal. When getting this callback, HFXO is running but its properties
|
||||
* (frequency, precision) are not guaranteed. This should be considered as an
|
||||
* error situation.
|
||||
******************************************************************************/
|
||||
__WEAK void sl_hfxo_manager_notify_consecutive_failed_startups(void)
|
||||
{
|
||||
EFM_ASSERT(false);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
********************** GLOBAL INTERNAL FUNCTIONS **************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just before starting HFXO, to save current tick count.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_begin_startup_measurement(void)
|
||||
{
|
||||
hfxo_measurement_on = true;
|
||||
hfxo_startup_time_tc_initial = sl_sleeptimer_get_tick_count();
|
||||
}
|
||||
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
/***************************************************************************//**
|
||||
* Function to retrieve the capture channel value that was saved when
|
||||
* HFXO became enabled.
|
||||
*
|
||||
* @note SYSRTC Capture channel is used to save when HFXO becomes enabled.
|
||||
* The HFXO startup measurement will only be done based on the capture
|
||||
* channel if the capture value is valid.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_retrieve_begining_startup_measurement(void)
|
||||
{
|
||||
// ULFRCO does not have the precision to measure the HFXO startup time.
|
||||
// So just return if ULFRCO is used as source oscillator.
|
||||
if (sl_sleeptimer_get_timer_frequency() <= SystemULFRCOClockGet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t startup_time = sli_sleeptimer_get_capture();
|
||||
|
||||
if (startup_time != 0) {
|
||||
hfxo_startup_time_tc_initial = startup_time;
|
||||
hfxo_measurement_on = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Function to call just after HFXO becomes ready, to save current tick count
|
||||
* and calculate HFXO startup time.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_end_startup_measurement(void)
|
||||
{
|
||||
uint32_t default_startup_ticks;
|
||||
|
||||
if (hfxo_measurement_on == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
hfxo_last_startup_time = sl_sleeptimer_get_tick_count() - hfxo_startup_time_tc_initial;
|
||||
|
||||
// With low precision clock, the HFXO startup time measure could be zero.
|
||||
// In that case, ensure it's a least 1 tick.
|
||||
hfxo_last_startup_time = (hfxo_last_startup_time == 0) ? 1 : hfxo_last_startup_time;
|
||||
|
||||
// Skip measurement if value is out of bound
|
||||
default_startup_ticks = (((HFXO_STARTUP_TIME_DEFAULT_VALUE_US * sl_sleeptimer_get_timer_frequency()) + (1000000 - 1)) / 1000000);
|
||||
EFM_ASSERT(hfxo_last_startup_time <= default_startup_ticks);
|
||||
if (hfxo_last_startup_time > default_startup_ticks) {
|
||||
hfxo_measurement_on = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate average for HFXO restore time
|
||||
hfxo_startup_time_sum_average -= (int32_t)hfxo_startup_time_table[hfxo_startup_time_table_index] - (int32_t)hfxo_last_startup_time;
|
||||
hfxo_startup_time_table[hfxo_startup_time_table_index] = hfxo_last_startup_time;
|
||||
hfxo_startup_time_tick = ((hfxo_startup_time_sum_average + (HFXO_STARTUP_TIME_TABLE_SIZE - 1) ) / HFXO_STARTUP_TIME_TABLE_SIZE);
|
||||
|
||||
// Update index of wakeup time table
|
||||
hfxo_startup_time_table_index++;
|
||||
hfxo_startup_time_table_index %= HFXO_STARTUP_TIME_TABLE_SIZE;
|
||||
|
||||
hfxo_measurement_on = false;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time average value.
|
||||
*
|
||||
* @return HFXO startup time average value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_startup_time(void)
|
||||
{
|
||||
return hfxo_startup_time_tick;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Retrieves HFXO startup time latest value.
|
||||
*
|
||||
* @return HFXO startup time latest value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_hfxo_manager_get_latest_startup_time(void)
|
||||
{
|
||||
return hfxo_last_startup_time;
|
||||
}
|
||||
|
|
|
@ -1,365 +1,407 @@
|
|||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager HAL series 2 Devices.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "em_device.h"
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
#include "sl_assert.h"
|
||||
#include "sli_hfxo_manager.h"
|
||||
#include "sl_hfxo_manager.h"
|
||||
#include "sl_hfxo_manager_config.h"
|
||||
#include "sl_status.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Defines for hidden field FORCERAWCLK in HFXO_CTRL register
|
||||
#define _HFXO_MANAGER_CTRL_FORCERAWCLK_SHIFT 31
|
||||
#define _HFXO_MANAGER_CTRL_FORCERAWCLK_MASK 0x80000000UL
|
||||
#define HFXO_MANAGER_CTRL_FORCERAWCLK (0x1UL << _HFXO_MANAGER_CTRL_FORCERAWCLK_SHIFT)
|
||||
|
||||
// Defines for hidden PKDETCTRL register
|
||||
#ifndef _HFXO_PKDETCTRL_MASK
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG <= 2)
|
||||
#define PKDETCTRL RESERVED4[2]
|
||||
#else
|
||||
#define PKDETCTRL RESERVED3[0]
|
||||
#endif
|
||||
#endif
|
||||
#define _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT 8
|
||||
#define _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK 0xF00UL
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V105MV (0x00000000UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V132MV (0x00000001UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V157MV (0x00000002UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V184MV (0x00000003UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V210MV (0x00000004UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V236MV (0x00000005UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V262MV (0x00000006UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V289MV (0x00000007UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V315MV (0x00000008UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V341MV (0x00000009UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V367MV (0x0000000AUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V394MV (0x0000000BUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V420MV (0x0000000CUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V446MV (0x0000000DUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V472MV (0x0000000EUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V499MV (0x0000000FUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
|
||||
// IRQ Name depending on devices
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
#define HFXO_IRQ_NUMBER HFXO00_IRQn
|
||||
#define HFXO_IRQ_HANDLER_FUNCTION HFXO00_IRQHandler
|
||||
#else
|
||||
#define HFXO_IRQ_NUMBER HFXO0_IRQn
|
||||
#define HFXO_IRQ_HANDLER_FUNCTION HFXO0_IRQHandler
|
||||
#endif
|
||||
|
||||
// Default values for the Sleepy Crystal settings
|
||||
// Should be enough to guaranty HFXO startup
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_PKDETTHSTARTUPI HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V157MV
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_CTUNEANA 100u
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_COREBIAS 255u
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Error flag to indicate if we failed the startup process
|
||||
static bool error_flag = false;
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// Error retry counter
|
||||
static uint8_t error_try_cnt = 0;
|
||||
|
||||
// Error State status
|
||||
static bool in_error_state = false;
|
||||
|
||||
// Variables to save normal settings
|
||||
static uint32_t pkdettusstartupi_saved;
|
||||
static uint32_t ctunexiana_saved;
|
||||
static uint32_t ctunexoana_saved;
|
||||
static uint32_t corebiasana_saved;
|
||||
static uint32_t corebiasstartup_saved;
|
||||
static uint32_t corebiasstartupi_saved;
|
||||
|
||||
// Variables for Sleepy Crystal settings
|
||||
static uint32_t sleepy_xtal_settings_pkdettusstartupi = SLEEPY_XTAL_SETTING_DEFAULT_PKDETTHSTARTUPI; // Value already shifted
|
||||
static uint32_t sleepy_xtal_settings_ctuneana = SLEEPY_XTAL_SETTING_DEFAULT_CTUNEANA;
|
||||
static uint32_t sleepy_xtal_settings_corebias = SLEEPY_XTAL_SETTING_DEFAULT_COREBIAS;
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO ready notification callback for internal use with power manager
|
||||
******************************************************************************/
|
||||
__WEAK void sli_hfxo_manager_notify_ready_for_power_manager(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_init_hardware(void)
|
||||
{
|
||||
// Increase HFXO Interrupt priority so that it won't be masked by BASEPRI
|
||||
// and will preempt other interrupts.
|
||||
NVIC_SetPriority(HFXO_IRQ_NUMBER, 2);
|
||||
|
||||
// Enable HFXO Interrupt if HFXO is used
|
||||
#if _SILICON_LABS_32B_SERIES_2_CONFIG >= 2
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_HFXO0;
|
||||
#endif
|
||||
|
||||
HFXO0->IEN_CLR = HFXO_IEN_RDY | HFXO_IEN_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
HFXO0->IF_CLR = HFXO_IF_RDY | HFXO_IF_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
|
||||
NVIC_ClearPendingIRQ(HFXO_IRQ_NUMBER);
|
||||
NVIC_EnableIRQ(HFXO_IRQ_NUMBER);
|
||||
|
||||
HFXO0->IEN_SET = HFXO_IEN_RDY | HFXO_IEN_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates sleepy crystal settings in specific hardware registers.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_hfxo_manager_update_sleepy_xtal_settings_hardware(sl_hfxo_manager_sleepy_xtal_settings_t *settings)
|
||||
{
|
||||
(void)settings;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
EFM_ASSERT(settings->ana_ctune <= (_HFXO_XTALCTRL_CTUNEXIANA_MASK >> _HFXO_XTALCTRL_CTUNEXIANA_SHIFT));
|
||||
EFM_ASSERT(settings->core_bias_current <= (_HFXO_XTALCTRL_COREBIASANA_MASK >> _HFXO_XTALCTRL_COREBIASANA_SHIFT));
|
||||
|
||||
sleepy_xtal_settings_ctuneana = settings->ana_ctune;
|
||||
sleepy_xtal_settings_corebias = settings->core_bias_current;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
#else
|
||||
return SL_STATUS_NOT_AVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Checks if HFXO is ready and, if needed, waits for it to be.
|
||||
*
|
||||
* @note This will also make sure we are not in the process of restarting HFXO
|
||||
* with different settings.
|
||||
******************************************************************************/
|
||||
bool sli_hfxo_manager_is_hfxo_ready(bool wait)
|
||||
{
|
||||
bool ready = false;
|
||||
|
||||
do {
|
||||
ready = (((HFXO0->STATUS & HFXO_STATUS_RDY) != 0) && !error_flag) ? true : false;
|
||||
} while (!ready && wait);
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
#if (SL_HFXO_MANAGER_CUSTOM_HFXO_IRQ_HANDLER == 0)
|
||||
/*******************************************************************************
|
||||
* HFXO interrupt handler.
|
||||
*
|
||||
* @note The HFXOx_IRQHandler provided by HFXO Manager will call
|
||||
* @ref sl_hfxo_manager_irq_handler. Configure SL_HFXO_MANAGER_CUSTOM_HFXO_IRQ_HANDLER
|
||||
* if the application wants to implement its own HFXOx_IRQHandler.
|
||||
******************************************************************************/
|
||||
void HFXO_IRQ_HANDLER_FUNCTION(void)
|
||||
{
|
||||
sl_hfxo_manager_irq_handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* HFXO Manager HFXO interrupt handler.
|
||||
******************************************************************************/
|
||||
void sl_hfxo_manager_irq_handler(void)
|
||||
{
|
||||
uint32_t irq_flag = HFXO0->IF;
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
bool disondemand = (HFXO0->CTRL & _HFXO_CTRL_DISONDEMAND_MASK) ? true : false;
|
||||
bool forceen = (HFXO0->CTRL & _HFXO_CTRL_FORCEEN_MASK) ? true : false;
|
||||
#endif
|
||||
|
||||
// RDY Interrupt Flag Handling
|
||||
if (irq_flag & HFXO_IF_RDY) {
|
||||
// Clear Ready flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_RDY;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
if (error_flag) {
|
||||
// Clear error flag, i.e. we successfully stated HFXO with the modified settings
|
||||
error_flag = false;
|
||||
|
||||
// If it's the first time we succeed after an error, try back the normal settings
|
||||
if (error_try_cnt <= 1) {
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
while ((HFXO0->STATUS & HFXO_STATUS_ENS) != 0) {
|
||||
}
|
||||
|
||||
// Put back normal settings
|
||||
HFXO0->PKDETCTRL = (HFXO0->PKDETCTRL & ~_HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK) | pkdettusstartupi_saved;
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~(_HFXO_XTALCTRL_CTUNEXIANA_MASK | _HFXO_XTALCTRL_CTUNEXOANA_MASK))
|
||||
| ctunexiana_saved
|
||||
| ctunexoana_saved;
|
||||
HFXO0->XTALCFG = (HFXO0->XTALCFG & ~(_HFXO_XTALCFG_COREBIASSTARTUPI_MASK | _HFXO_XTALCFG_COREBIASSTARTUP_MASK))
|
||||
| corebiasstartup_saved
|
||||
| corebiasstartupi_saved;
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~_HFXO_XTALCTRL_COREBIASANA_MASK) | corebiasana_saved;
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
} else {
|
||||
// Call notification function to tell users that sleepy crystal settings are kept
|
||||
// This should only happen if you are in test condition or if you have a bad crystal.
|
||||
sl_hfxo_manager_notify_consecutive_failed_startups();
|
||||
in_error_state = true;
|
||||
}
|
||||
} else {
|
||||
sli_hfxo_manager_end_startup_measurement();
|
||||
|
||||
sli_hfxo_manager_notify_ready_for_power_manager();
|
||||
|
||||
// Clear counter since we successfully started HFXO with normal settings
|
||||
// or we are just keeping sleepy crystal settings indefinitely.
|
||||
error_try_cnt = 0;
|
||||
}
|
||||
#else
|
||||
sli_hfxo_manager_end_startup_measurement();
|
||||
|
||||
sli_hfxo_manager_notify_ready_for_power_manager();
|
||||
#endif
|
||||
}
|
||||
|
||||
// DNSERR Interrupt Flag Handling
|
||||
if (irq_flag & HFXO_IF_DNSERR) {
|
||||
// Clear error flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_DNSERR;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// We should not fail twice in a row
|
||||
EFM_ASSERT(error_flag == false);
|
||||
|
||||
// Update global variables related to error.
|
||||
error_flag = true;
|
||||
error_try_cnt++;
|
||||
|
||||
// Save current settings
|
||||
pkdettusstartupi_saved = (HFXO0->PKDETCTRL & _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK);
|
||||
ctunexiana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_CTUNEXIANA_MASK);
|
||||
ctunexoana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_CTUNEXOANA_MASK);
|
||||
corebiasana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_COREBIASANA_MASK);
|
||||
corebiasstartup_saved = (HFXO0->XTALCFG & _HFXO_XTALCFG_COREBIASSTARTUP_MASK);
|
||||
corebiasstartupi_saved = (HFXO0->XTALCFG & _HFXO_XTALCFG_COREBIASSTARTUPI_MASK);
|
||||
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
// Use FORCERAWCLK bit to exit error state when disabling
|
||||
HFXO0->CTRL_SET = HFXO_MANAGER_CTRL_FORCERAWCLK;
|
||||
while ((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0U) {
|
||||
}
|
||||
HFXO0->CTRL_CLR = HFXO_MANAGER_CTRL_FORCERAWCLK;
|
||||
|
||||
// Change settings:
|
||||
//Reduce Peak Detection Threshold for Startup Intermediate stage to 2 (V157MV)
|
||||
HFXO0->PKDETCTRL = (HFXO0->PKDETCTRL & ~_HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK) | sleepy_xtal_settings_pkdettusstartupi;
|
||||
// Reduce CTUNE values for steady stage
|
||||
if (((ctunexiana_saved >> _HFXO_XTALCTRL_CTUNEXIANA_SHIFT) > 100)
|
||||
|| ((ctunexoana_saved >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT) > 100)) {
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~(_HFXO_XTALCTRL_CTUNEXIANA_MASK | _HFXO_XTALCTRL_CTUNEXOANA_MASK))
|
||||
| (sleepy_xtal_settings_ctuneana << _HFXO_XTALCTRL_CTUNEXIANA_SHIFT)
|
||||
| (sleepy_xtal_settings_ctuneana << _HFXO_XTALCTRL_CTUNEXOANA_SHIFT);
|
||||
}
|
||||
// Increase core bias current at all stages
|
||||
HFXO0->XTALCFG = (HFXO0->XTALCFG & ~(_HFXO_XTALCFG_COREBIASSTARTUPI_MASK | _HFXO_XTALCFG_COREBIASSTARTUP_MASK))
|
||||
| ((sleepy_xtal_settings_corebias >> 2) << _HFXO_XTALCFG_COREBIASSTARTUPI_SHIFT)
|
||||
| ((sleepy_xtal_settings_corebias >> 2) << _HFXO_XTALCFG_COREBIASSTARTUP_SHIFT);
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~_HFXO_XTALCTRL_COREBIASANA_MASK)
|
||||
| (sleepy_xtal_settings_corebias << _HFXO_XTALCTRL_COREBIASANA_SHIFT);
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (irq_flag & HFXO_IF_COREBIASOPTERR) {
|
||||
// Clear Core Bias Optimization error flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_COREBIASOPTERR;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// In case the Core Bias Optimization fails during error handling,
|
||||
// we disable it
|
||||
if (in_error_state == true) {
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
while ((HFXO0->STATUS & HFXO_STATUS_ENS) != 0) {
|
||||
}
|
||||
|
||||
// Skip Core Bias Optimization in case of error
|
||||
HFXO0->XTALCTRL_SET = HFXO_XTALCTRL_SKIPCOREBIASOPT;
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // _SILICON_LABS_32B_SERIES_2
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief HFXO Manager HAL series 2 Devices.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include "em_device.h"
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
#include "sl_assert.h"
|
||||
#include "sli_hfxo_manager.h"
|
||||
#include "sl_hfxo_manager.h"
|
||||
#include "sl_hfxo_manager_config.h"
|
||||
#include "sl_status.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/*******************************************************************************
|
||||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if (defined(SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT) \
|
||||
&& (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1) \
|
||||
&& defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT))
|
||||
#error Component power_manager_deepsleep_blocking_hfxo_restore is not compatible with SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT configuration
|
||||
#endif
|
||||
|
||||
// Defines for hidden field FORCERAWCLK in HFXO_CTRL register
|
||||
#define _HFXO_MANAGER_CTRL_FORCERAWCLK_SHIFT 31
|
||||
#define _HFXO_MANAGER_CTRL_FORCERAWCLK_MASK 0x80000000UL
|
||||
#define HFXO_MANAGER_CTRL_FORCERAWCLK (0x1UL << _HFXO_MANAGER_CTRL_FORCERAWCLK_SHIFT)
|
||||
|
||||
// Defines for hidden PKDETCTRL register
|
||||
#define HFXO_MANAGER_PKDETCTRL (*((volatile uint32_t *)(HFXO0_BASE + 0x34UL)))
|
||||
#define _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT 8
|
||||
#define _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK 0xF00UL
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V105MV (0x00000000UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V132MV (0x00000001UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V157MV (0x00000002UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V184MV (0x00000003UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V210MV (0x00000004UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V236MV (0x00000005UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V262MV (0x00000006UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V289MV (0x00000007UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V315MV (0x00000008UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V341MV (0x00000009UL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V367MV (0x0000000AUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V394MV (0x0000000BUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V420MV (0x0000000CUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V446MV (0x0000000DUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V472MV (0x0000000EUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
#define HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V499MV (0x0000000FUL << _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_SHIFT)
|
||||
|
||||
// IRQ Name depending on devices
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
#define HFXO_IRQ_NUMBER HFXO00_IRQn
|
||||
#define HFXO_IRQ_HANDLER_FUNCTION HFXO00_IRQHandler
|
||||
#else
|
||||
#define HFXO_IRQ_NUMBER HFXO0_IRQn
|
||||
#define HFXO_IRQ_HANDLER_FUNCTION HFXO0_IRQHandler
|
||||
#endif
|
||||
|
||||
// Default values for the Sleepy Crystal settings
|
||||
// Should be enough to guaranty HFXO startup
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_PKDETTHSTARTUPI HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_V157MV
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_CTUNEANA 100u
|
||||
#define SLEEPY_XTAL_SETTING_DEFAULT_COREBIAS 255u
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
// Error flag to indicate if we failed the startup process
|
||||
static bool error_flag = false;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// Error retry counter
|
||||
static uint8_t error_try_cnt = 0;
|
||||
|
||||
// Error State status
|
||||
static bool in_error_state = false;
|
||||
|
||||
// Variables to save normal settings
|
||||
static uint32_t pkdettusstartupi_saved;
|
||||
static uint32_t ctunexiana_saved;
|
||||
static uint32_t ctunexoana_saved;
|
||||
static uint32_t corebiasana_saved;
|
||||
static uint32_t corebiasstartup_saved;
|
||||
static uint32_t corebiasstartupi_saved;
|
||||
|
||||
// Variables for Sleepy Crystal settings
|
||||
static uint32_t sleepy_xtal_settings_pkdettusstartupi = SLEEPY_XTAL_SETTING_DEFAULT_PKDETTHSTARTUPI; // Value already shifted
|
||||
static uint32_t sleepy_xtal_settings_ctuneana = SLEEPY_XTAL_SETTING_DEFAULT_CTUNEANA;
|
||||
static uint32_t sleepy_xtal_settings_corebias = SLEEPY_XTAL_SETTING_DEFAULT_COREBIAS;
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO ready notification callback for internal use with power manager
|
||||
******************************************************************************/
|
||||
__WEAK void sli_hfxo_manager_notify_ready_for_power_manager(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* HFXO PRS ready notification callback for internal use with power manager
|
||||
******************************************************************************/
|
||||
__WEAK void sli_hfxo_notify_ready_for_power_manager_from_prs(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Hardware specific initialization.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_manager_init_hardware(void)
|
||||
{
|
||||
// Increase HFXO Interrupt priority so that it won't be masked by BASEPRI
|
||||
// and will preempt other interrupts.
|
||||
NVIC_SetPriority(HFXO_IRQ_NUMBER, 2);
|
||||
|
||||
// Enable HFXO Interrupt if HFXO is used
|
||||
#if _SILICON_LABS_32B_SERIES_2_CONFIG >= 2
|
||||
CMU->CLKEN0_SET = CMU_CLKEN0_HFXO0;
|
||||
#endif
|
||||
|
||||
HFXO0->IEN_CLR = HFXO_IEN_RDY | HFXO_IEN_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
HFXO0->IEN_CLR = HFXO_IEN_PRSRDY;
|
||||
#endif
|
||||
|
||||
HFXO0->IF_CLR = HFXO_IF_RDY | HFXO_IF_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
HFXO0->IF_CLR = HFXO_IF_PRSRDY;
|
||||
#endif
|
||||
|
||||
NVIC_ClearPendingIRQ(HFXO_IRQ_NUMBER);
|
||||
NVIC_EnableIRQ(HFXO_IRQ_NUMBER);
|
||||
|
||||
HFXO0->IEN_SET = HFXO_IEN_RDY | HFXO_IEN_DNSERR | HFXO_IEN_COREBIASOPTERR;
|
||||
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
HFXO0->IEN_SET = HFXO_IEN_PRSRDY;
|
||||
HFXO0->CTRL &= ~(_HFXO_CTRL_DISONDEMANDPRS_MASK & HFXO_CTRL_DISONDEMANDPRS_DEFAULT);
|
||||
HFXO0->CTRL |= HFXO_CTRL_PRSSTATUSSEL1_ENS;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Updates sleepy crystal settings in specific hardware registers.
|
||||
******************************************************************************/
|
||||
sl_status_t sli_hfxo_manager_update_sleepy_xtal_settings_hardware(sl_hfxo_manager_sleepy_xtal_settings_t *settings)
|
||||
{
|
||||
(void)settings;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
EFM_ASSERT(settings->ana_ctune <= (_HFXO_XTALCTRL_CTUNEXIANA_MASK >> _HFXO_XTALCTRL_CTUNEXIANA_SHIFT));
|
||||
EFM_ASSERT(settings->core_bias_current <= (_HFXO_XTALCTRL_COREBIASANA_MASK >> _HFXO_XTALCTRL_COREBIASANA_SHIFT));
|
||||
|
||||
sleepy_xtal_settings_ctuneana = settings->ana_ctune;
|
||||
sleepy_xtal_settings_corebias = settings->core_bias_current;
|
||||
|
||||
return SL_STATUS_OK;
|
||||
#else
|
||||
return SL_STATUS_NOT_AVAILABLE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Checks if HFXO is ready and, if needed, waits for it to be.
|
||||
*
|
||||
* @note This will also make sure we are not in the process of restarting HFXO
|
||||
* with different settings.
|
||||
******************************************************************************/
|
||||
bool sli_hfxo_manager_is_hfxo_ready(bool wait)
|
||||
{
|
||||
bool ready = false;
|
||||
|
||||
do {
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
ready = (((HFXO0->STATUS & (HFXO_STATUS_RDY | HFXO_STATUS_PRSRDY)) != 0) && !error_flag) ? true : false;
|
||||
#else
|
||||
ready = (((HFXO0->STATUS & HFXO_STATUS_RDY) != 0) && !error_flag) ? true : false;
|
||||
#endif
|
||||
} while (!ready && wait);
|
||||
|
||||
return ready;
|
||||
}
|
||||
|
||||
#if (SL_HFXO_MANAGER_CUSTOM_HFXO_IRQ_HANDLER == 0)
|
||||
/*******************************************************************************
|
||||
* HFXO interrupt handler.
|
||||
*
|
||||
* @note The HFXOx_IRQHandler provided by HFXO Manager will call
|
||||
* @ref sl_hfxo_manager_irq_handler. Configure SL_HFXO_MANAGER_CUSTOM_HFXO_IRQ_HANDLER
|
||||
* if the application wants to implement its own HFXOx_IRQHandler.
|
||||
******************************************************************************/
|
||||
void HFXO_IRQ_HANDLER_FUNCTION(void)
|
||||
{
|
||||
sl_hfxo_manager_irq_handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* HFXO Manager HFXO interrupt handler.
|
||||
******************************************************************************/
|
||||
void sl_hfxo_manager_irq_handler(void)
|
||||
{
|
||||
uint32_t irq_flag = HFXO0->IF;
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
bool disondemand = (HFXO0->CTRL & _HFXO_CTRL_DISONDEMAND_MASK) ? true : false;
|
||||
bool forceen = (HFXO0->CTRL & _HFXO_CTRL_FORCEEN_MASK) ? true : false;
|
||||
#endif
|
||||
|
||||
#if defined(HFXO_MANAGER_SLEEPTIMER_SYSRTC_INTEGRATION_ON)
|
||||
if (irq_flag & HFXO_IF_PRSRDY) {
|
||||
// Clear PRS RDY flag and EM23ONDEMAND
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_PRSRDY;
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_EM23ONDEMAND;
|
||||
|
||||
sli_hfxo_manager_retrieve_begining_startup_measurement();
|
||||
|
||||
// Notify power manager HFXO is ready
|
||||
sli_hfxo_notify_ready_for_power_manager_from_prs();
|
||||
sli_hfxo_manager_notify_ready_for_power_manager();
|
||||
|
||||
// Update sleep on isr exit flag
|
||||
sli_sleeptimer_update_sleep_on_isr_exit(true);
|
||||
|
||||
// Reset PRS signal through Sleeptimer
|
||||
sli_sleeptimer_reset_prs_signal();
|
||||
}
|
||||
#endif
|
||||
|
||||
// RDY Interrupt Flag Handling
|
||||
if (irq_flag & HFXO_IF_RDY) {
|
||||
// Clear Ready flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_RDY;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
if (error_flag) {
|
||||
// Clear error flag, i.e. we successfully stated HFXO with the modified settings
|
||||
error_flag = false;
|
||||
|
||||
// If it's the first time we succeed after an error, try back the normal settings
|
||||
if (error_try_cnt <= 1) {
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
while ((HFXO0->STATUS & HFXO_STATUS_ENS) != 0) {
|
||||
}
|
||||
|
||||
// Put back normal settings
|
||||
HFXO_MANAGER_PKDETCTRL = (HFXO_MANAGER_PKDETCTRL & ~_HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK) | pkdettusstartupi_saved;
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~(_HFXO_XTALCTRL_CTUNEXIANA_MASK | _HFXO_XTALCTRL_CTUNEXOANA_MASK))
|
||||
| ctunexiana_saved
|
||||
| ctunexoana_saved;
|
||||
HFXO0->XTALCFG = (HFXO0->XTALCFG & ~(_HFXO_XTALCFG_COREBIASSTARTUPI_MASK | _HFXO_XTALCFG_COREBIASSTARTUP_MASK))
|
||||
| corebiasstartup_saved
|
||||
| corebiasstartupi_saved;
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~_HFXO_XTALCTRL_COREBIASANA_MASK) | corebiasana_saved;
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
} else {
|
||||
// Call notification function to tell users that sleepy crystal settings are kept
|
||||
// This should only happen if you are in test condition or if you have a bad crystal.
|
||||
sl_hfxo_manager_notify_consecutive_failed_startups();
|
||||
in_error_state = true;
|
||||
}
|
||||
} else {
|
||||
sli_hfxo_manager_end_startup_measurement();
|
||||
|
||||
sli_hfxo_manager_notify_ready_for_power_manager();
|
||||
|
||||
// Clear counter since we successfully started HFXO with normal settings
|
||||
// or we are just keeping sleepy crystal settings indefinitely.
|
||||
error_try_cnt = 0;
|
||||
}
|
||||
#else
|
||||
sli_hfxo_manager_end_startup_measurement();
|
||||
|
||||
sli_hfxo_manager_notify_ready_for_power_manager();
|
||||
#endif
|
||||
}
|
||||
|
||||
// DNSERR Interrupt Flag Handling
|
||||
if (irq_flag & HFXO_IF_DNSERR) {
|
||||
// Clear error flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_DNSERR;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// We should not fail twice in a row
|
||||
EFM_ASSERT(error_flag == false);
|
||||
|
||||
// Update global variables related to error.
|
||||
error_flag = true;
|
||||
error_try_cnt++;
|
||||
|
||||
// Save current settings
|
||||
pkdettusstartupi_saved = (HFXO_MANAGER_PKDETCTRL & _HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK);
|
||||
ctunexiana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_CTUNEXIANA_MASK);
|
||||
ctunexoana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_CTUNEXOANA_MASK);
|
||||
corebiasana_saved = (HFXO0->XTALCTRL & _HFXO_XTALCTRL_COREBIASANA_MASK);
|
||||
corebiasstartup_saved = (HFXO0->XTALCFG & _HFXO_XTALCFG_COREBIASSTARTUP_MASK);
|
||||
corebiasstartupi_saved = (HFXO0->XTALCFG & _HFXO_XTALCFG_COREBIASSTARTUPI_MASK);
|
||||
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
// Use FORCERAWCLK bit to exit error state when disabling
|
||||
HFXO0->CTRL_SET = HFXO_MANAGER_CTRL_FORCERAWCLK;
|
||||
while ((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0U) {
|
||||
}
|
||||
HFXO0->CTRL_CLR = HFXO_MANAGER_CTRL_FORCERAWCLK;
|
||||
|
||||
// Change settings:
|
||||
//Reduce Peak Detection Threshold for Startup Intermediate stage to 2 (V157MV)
|
||||
HFXO_MANAGER_PKDETCTRL = (HFXO_MANAGER_PKDETCTRL & ~_HFXO_MANAGER_PKDETCTRL_PKDETTHSTARTUPI_MASK) | sleepy_xtal_settings_pkdettusstartupi;
|
||||
// Reduce CTUNE values for steady stage
|
||||
if (((ctunexiana_saved >> _HFXO_XTALCTRL_CTUNEXIANA_SHIFT) > 100)
|
||||
|| ((ctunexoana_saved >> _HFXO_XTALCTRL_CTUNEXOANA_SHIFT) > 100)) {
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~(_HFXO_XTALCTRL_CTUNEXIANA_MASK | _HFXO_XTALCTRL_CTUNEXOANA_MASK))
|
||||
| (sleepy_xtal_settings_ctuneana << _HFXO_XTALCTRL_CTUNEXIANA_SHIFT)
|
||||
| (sleepy_xtal_settings_ctuneana << _HFXO_XTALCTRL_CTUNEXOANA_SHIFT);
|
||||
}
|
||||
// Increase core bias current at all stages
|
||||
HFXO0->XTALCFG = (HFXO0->XTALCFG & ~(_HFXO_XTALCFG_COREBIASSTARTUPI_MASK | _HFXO_XTALCFG_COREBIASSTARTUP_MASK))
|
||||
| ((sleepy_xtal_settings_corebias >> 2) << _HFXO_XTALCFG_COREBIASSTARTUPI_SHIFT)
|
||||
| ((sleepy_xtal_settings_corebias >> 2) << _HFXO_XTALCFG_COREBIASSTARTUP_SHIFT);
|
||||
HFXO0->XTALCTRL = (HFXO0->XTALCTRL & ~_HFXO_XTALCTRL_COREBIASANA_MASK)
|
||||
| (sleepy_xtal_settings_corebias << _HFXO_XTALCTRL_COREBIASANA_SHIFT);
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (irq_flag & HFXO_IF_COREBIASOPTERR) {
|
||||
// Clear Core Bias Optimization error flag
|
||||
HFXO0->IF_CLR = irq_flag & HFXO_IF_COREBIASOPTERR;
|
||||
|
||||
#if (SL_HFXO_MANAGER_SLEEPY_CRYSTAL_SUPPORT == 1)
|
||||
// In case the Core Bias Optimization fails during error handling,
|
||||
// we disable it
|
||||
if (in_error_state == true) {
|
||||
// Disable HFXO.
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
|
||||
while ((HFXO0->STATUS & HFXO_STATUS_ENS) != 0) {
|
||||
}
|
||||
|
||||
// Skip Core Bias Optimization in case of error
|
||||
HFXO0->XTALCTRL_SET = HFXO_XTALCTRL_SKIPCOREBIASOPT;
|
||||
|
||||
// Put back FORCEEN and DISONDEMAND state
|
||||
if (!disondemand) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_DISONDEMAND;
|
||||
} else {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_DISONDEMAND;
|
||||
}
|
||||
if (forceen) {
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
} else {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // _SILICON_LABS_32B_SERIES_2
|
||||
|
|
|
@ -41,13 +41,6 @@
|
|||
// <i> Default: 0
|
||||
#define SL_POWER_MANAGER_CUSTOM_HF_OSCILLATOR_IRQ_HANDLER 0
|
||||
|
||||
// <o SL_POWER_MANAGER_LOWEST_EM_ALLOWED> Lowest Energy mode allowed
|
||||
// <1=> EM1
|
||||
// <2=> EM2
|
||||
// <3=> EM3
|
||||
// <i> Default: 2
|
||||
#define SL_POWER_MANAGER_LOWEST_EM_ALLOWED 2
|
||||
|
||||
// <q SL_POWER_MANAGER_CONFIG_VOLTAGE_SCALING_FAST_WAKEUP> Enable fast wakeup (disable voltage scaling in EM2/3 mode)
|
||||
// <i> Enable or disable voltage scaling in EM2/3 modes (when available). This decreases wakeup time by about 30 us.
|
||||
// <i> Deprecated. It is replaced by the function sl_power_manager_em23_voltage_scaling_enable_fast_wakeup()
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#define SLI_POWER_MANAGER_H
|
||||
|
||||
#include "sl_power_manager.h"
|
||||
#include "em_device.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
@ -41,21 +40,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if !defined(SLI_DEVICE_SUPPORTS_EM1P) && defined(_SILICON_LABS_32B_SERIES_2_CONFIG) && _SILICON_LABS_32B_SERIES_2_CONFIG >= 2
|
||||
#define SLI_DEVICE_SUPPORTS_EM1P
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
void sli_power_manager_update_hf_clock_settings_preservation_requirement(bool add);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Adds requirement on the preservation of the High Frequency Clocks settings.
|
||||
|
@ -64,14 +53,7 @@ void sli_power_manager_update_hf_clock_settings_preservation_requirement(bool ad
|
|||
*
|
||||
* @note Must be used together with adding an EM2 requirement.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_power_manager_add_hf_clock_settings_preservation_requirement(void)
|
||||
{
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
sli_power_manager_update_hf_clock_settings_preservation_requirement(true);
|
||||
#else
|
||||
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
|
||||
#endif
|
||||
}
|
||||
void sli_power_manager_add_hf_clock_settings_preservation_requirement(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Removes requirement on the preservation of the High Frequency Clocks settings.
|
||||
|
@ -80,14 +62,7 @@ __STATIC_INLINE void sli_power_manager_add_hf_clock_settings_preservation_requir
|
|||
*
|
||||
* @note Must be used together with removing an EM2 requirement.
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void sli_power_manager_remove_hf_clock_settings_preservation_requirement(void)
|
||||
{
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
sli_power_manager_update_hf_clock_settings_preservation_requirement(false);
|
||||
#else
|
||||
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
|
||||
#endif
|
||||
}
|
||||
void sli_power_manager_remove_hf_clock_settings_preservation_requirement(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Informs the power manager module that the high accuracy/high frequency clock
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
#include "sl_assert.h"
|
||||
#include "sl_atomic.h"
|
||||
|
||||
#include "em_device.h"
|
||||
#if !defined(_SILICON_LABS_32B_SERIES_3)
|
||||
#include "em_emu.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
@ -44,16 +49,15 @@
|
|||
********************************* DEFINES *********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if ((SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1) \
|
||||
&& (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 2) \
|
||||
&& (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 3))
|
||||
#error "Lowest Energy mode allowed is invalid."
|
||||
#endif
|
||||
|
||||
// Default overhead value for the wake-up time used for the schedule wake-up
|
||||
// functionality.
|
||||
#define SCHEDULE_WAKEUP_DEFAULT_RESTORE_TIME_OVERHEAD_TICK 0
|
||||
|
||||
// Determine if the device supports EM1P
|
||||
#if !defined(SLI_DEVICE_SUPPORTS_EM1P) && defined(_SILICON_LABS_32B_SERIES_2_CONFIG) && _SILICON_LABS_32B_SERIES_2_CONFIG >= 2
|
||||
#define SLI_DEVICE_SUPPORTS_EM1P
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
@ -67,7 +71,7 @@ static sl_power_manager_em_t current_em = SL_POWER_MANAGER_EM0;
|
|||
// Events subscribers lists
|
||||
static sl_slist_node_t *power_manager_em_transition_event_list = NULL;
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// Store the sleeptimer module clock frequency for conversion calculation
|
||||
static uint32_t sleeptimer_frequency;
|
||||
|
||||
|
@ -156,7 +160,7 @@ bool sl_power_manager_is_ok_to_sleep(void);
|
|||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
static sl_power_manager_em_t get_lowest_em(void);
|
||||
|
||||
static void evaluate_wakeup(sl_power_manager_em_t to);
|
||||
|
@ -174,6 +178,12 @@ static void clock_restore(void);
|
|||
static void power_manager_notify_em_transition(sl_power_manager_em_t from,
|
||||
sl_power_manager_em_t to);
|
||||
|
||||
// Use PriMask to enter critical section by disabling interrupts.
|
||||
static CORE_irqState_t enter_critical_with_primask();
|
||||
|
||||
// Exit critical section by re-enabling interrupts in PriMask.
|
||||
static void exit_critical_with_primask(CORE_irqState_t primask_state);
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
@ -195,13 +205,22 @@ sl_status_t sl_power_manager_init(void)
|
|||
CORE_EXIT_CRITICAL();
|
||||
return status;
|
||||
}
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) \
|
||||
&& !defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
// Additional Sleeptimer HW configuration if the "power_manager_deepsleep" component is used
|
||||
sli_sleeptimer_hal_power_manager_integration_init();
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_DEBUG == 1)
|
||||
sli_power_manager_debug_init();
|
||||
#endif
|
||||
sl_slist_init(&power_manager_em_transition_event_list);
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// If lowest energy mode is not restricted to EM1, determine and set lowest energy mode
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
sli_sleeptimer_set_pm_em_requirement();
|
||||
#endif
|
||||
// Set the default wake-up overhead value
|
||||
wakeup_time_config_overhead_tick = SCHEDULE_WAKEUP_DEFAULT_RESTORE_TIME_OVERHEAD_TICK;
|
||||
|
||||
|
@ -213,7 +232,7 @@ sl_status_t sl_power_manager_init(void)
|
|||
// Do all necessary hardware initialization.
|
||||
sli_power_manager_init_hardware();
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// Set the HF minimum offtime in sleeptimer ticks
|
||||
high_frequency_min_offtime_tick = sli_power_manager_get_default_high_frequency_minimum_offtime();
|
||||
#endif
|
||||
|
@ -229,19 +248,19 @@ sl_status_t sl_power_manager_init(void)
|
|||
******************************************************************************/
|
||||
void sl_power_manager_sleep(void)
|
||||
{
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
CORE_irqState_t primask_state;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
primask_state = enter_critical_with_primask();
|
||||
|
||||
sli_power_manager_suspend_log_transmission();
|
||||
|
||||
if (sl_power_manager_is_ok_to_sleep() != true) {
|
||||
sli_power_manager_resume_log_transmission();
|
||||
CORE_EXIT_CRITICAL();
|
||||
exit_critical_with_primask(primask_state);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
sl_power_manager_em_t lowest_em;
|
||||
|
||||
// Go to another energy mode (same, higher to lower or lower to higher)
|
||||
|
@ -308,8 +327,8 @@ void sl_power_manager_sleep(void)
|
|||
// For internal Silicon Labs use only
|
||||
sli_power_manager_on_wakeup();
|
||||
|
||||
CORE_EXIT_CRITICAL();
|
||||
CORE_ENTER_CRITICAL();
|
||||
exit_critical_with_primask(primask_state);
|
||||
primask_state = enter_critical_with_primask();
|
||||
|
||||
// In case the HF restore was completed from the HFXO ISR,
|
||||
// and notification not done elsewhere, do it here
|
||||
|
@ -339,8 +358,8 @@ void sl_power_manager_sleep(void)
|
|||
// If possible, go back to sleep in EM1 while waiting for HF accuracy restore
|
||||
while (!sli_power_manager_is_high_freq_accuracy_clk_ready(false)) {
|
||||
sli_power_manager_apply_em(SL_POWER_MANAGER_EM1);
|
||||
CORE_EXIT_CRITICAL();
|
||||
CORE_ENTER_CRITICAL();
|
||||
exit_critical_with_primask(primask_state);
|
||||
primask_state = enter_critical_with_primask();
|
||||
}
|
||||
sli_power_manager_restore_states();
|
||||
is_states_saved = false;
|
||||
|
@ -356,8 +375,8 @@ void sl_power_manager_sleep(void)
|
|||
// Apply EM1 energy mode
|
||||
sli_power_manager_apply_em(SL_POWER_MANAGER_EM1);
|
||||
|
||||
CORE_EXIT_CRITICAL();
|
||||
CORE_ENTER_CRITICAL();
|
||||
exit_critical_with_primask(primask_state);
|
||||
primask_state = enter_critical_with_primask();
|
||||
} while (sl_power_manager_sleep_on_isr_exit() == true);
|
||||
#endif
|
||||
|
||||
|
@ -367,7 +386,7 @@ void sl_power_manager_sleep(void)
|
|||
|
||||
sli_power_manager_resume_log_transmission();
|
||||
|
||||
CORE_EXIT_CRITICAL();
|
||||
exit_critical_with_primask(primask_state);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
|
@ -382,13 +401,14 @@ void sl_power_manager_sleep(void)
|
|||
*
|
||||
* @note Need to be call inside a critical section.
|
||||
*
|
||||
* @note This function will do nothing when SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_update_em_requirement(sl_power_manager_em_t em,
|
||||
bool add)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// EM0 is not allowed
|
||||
EFM_ASSERT((em > SL_POWER_MANAGER_EM0) && (em < SL_POWER_MANAGER_EM3));
|
||||
|
||||
|
@ -429,7 +449,6 @@ void sli_power_manager_update_em_requirement(sl_power_manager_em_t em,
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
/***************************************************************************//**
|
||||
* Updates requirement on preservation of High Frequency Clocks settings.
|
||||
*
|
||||
|
@ -438,7 +457,7 @@ void sli_power_manager_update_em_requirement(sl_power_manager_em_t em,
|
|||
******************************************************************************/
|
||||
void sli_power_manager_update_hf_clock_settings_preservation_requirement(bool add)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if (defined(SLI_DEVICE_SUPPORTS_EM1P) && !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT))
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
|
@ -461,7 +480,38 @@ void sli_power_manager_update_hf_clock_settings_preservation_requirement(bool ad
|
|||
(void)add;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Adds requirement on the preservation of the High Frequency Clocks settings.
|
||||
*
|
||||
* @note FOR INTERNAL USE ONLY.
|
||||
*
|
||||
* @note Must be used together with adding an EM2 requirement.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_add_hf_clock_settings_preservation_requirement(void)
|
||||
{
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
sli_power_manager_update_hf_clock_settings_preservation_requirement(true);
|
||||
#else
|
||||
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Removes requirement on the preservation of the High Frequency Clocks settings.
|
||||
*
|
||||
* @note FOR INTERNAL USE ONLY.
|
||||
*
|
||||
* @note Must be used together with removing an EM2 requirement.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_remove_hf_clock_settings_preservation_requirement(void)
|
||||
{
|
||||
#if defined(SLI_DEVICE_SUPPORTS_EM1P)
|
||||
sli_power_manager_update_hf_clock_settings_preservation_requirement(false);
|
||||
#else
|
||||
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Gets the wake-up restore process time.
|
||||
|
@ -472,7 +522,7 @@ void sli_power_manager_update_hf_clock_settings_preservation_requirement(bool ad
|
|||
******************************************************************************/
|
||||
uint32_t sli_power_manager_get_restore_delay(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
uint32_t wakeup_delay = 0;
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
|
@ -501,7 +551,7 @@ uint32_t sli_power_manager_get_restore_delay(void)
|
|||
******************************************************************************/
|
||||
void sli_power_manager_initiate_restore(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
|
@ -513,6 +563,16 @@ void sli_power_manager_initiate_restore(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Gets the status of power manager variable is_sleeping_waiting_for_clock_restore.
|
||||
******************************************************************************/
|
||||
bool sli_power_manager_get_clock_restore_status(void)
|
||||
{
|
||||
return is_sleeping_waiting_for_clock_restore;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Registers a callback to be called on given Energy Mode transition(s).
|
||||
*
|
||||
|
@ -547,12 +607,13 @@ void sl_power_manager_unsubscribe_em_transition_event(sl_power_manager_em_transi
|
|||
*
|
||||
* @return Current overhead value for early wake-up time.
|
||||
*
|
||||
* @note This function will return 0 in case SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
int32_t sl_power_manager_schedule_wakeup_get_restore_overhead_tick(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
int32_t overhead_tick;
|
||||
|
||||
sl_atomic_load(overhead_tick, wakeup_time_config_overhead_tick);
|
||||
|
@ -572,12 +633,13 @@ int32_t sl_power_manager_schedule_wakeup_get_restore_overhead_tick(void)
|
|||
* @note The overhead value can also be negative to remove time from the restore
|
||||
* process.
|
||||
*
|
||||
* @note This function will do nothing when SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
void sl_power_manager_schedule_wakeup_set_restore_overhead_tick(int32_t overhead_tick)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
sl_atomic_store(wakeup_time_config_overhead_tick, overhead_tick);
|
||||
#else
|
||||
(void)overhead_tick;
|
||||
|
@ -599,12 +661,13 @@ void sl_power_manager_schedule_wakeup_set_restore_overhead_tick(int32_t overhead
|
|||
* the oscillator on until the next scheduled oscillator enabled. This
|
||||
* threshold value is what we refer as the minimum off-time.
|
||||
*
|
||||
* @note This function will return 0 in case SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
uint32_t sl_power_manager_schedule_wakeup_get_minimum_offtime_tick(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
uint32_t offtime_tick;
|
||||
|
||||
sl_atomic_load(offtime_tick, high_frequency_min_offtime_tick);
|
||||
|
@ -630,19 +693,20 @@ uint32_t sl_power_manager_schedule_wakeup_get_minimum_offtime_tick(void)
|
|||
* the oscillator on until the next scheduled oscillator enabled. This
|
||||
* threshold value is what we refer as the minimum off-time.
|
||||
*
|
||||
* @note This function will do nothing when SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
void sl_power_manager_schedule_wakeup_set_minimum_offtime_tick(uint32_t minimum_offtime_tick)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
sl_atomic_store(high_frequency_min_offtime_tick, minimum_offtime_tick);
|
||||
#else
|
||||
(void)minimum_offtime_tick;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Converts microseconds time in sleeptimer ticks.
|
||||
******************************************************************************/
|
||||
|
@ -689,12 +753,12 @@ __WEAK bool sl_power_manager_sleep_on_isr_exit(void)
|
|||
* false otherwise.
|
||||
*
|
||||
* @note This function will always return false in case
|
||||
* SL_POWER_MANAGER_LOWEST_EM_ALLOWED config is set to EM1, since we will
|
||||
* never sleep at a lower level than EM1.
|
||||
* a requirement is added on SL_POWER_MANAGER_EM1,
|
||||
* since we will never sleep at a lower level than EM1.
|
||||
*****************************************************************************/
|
||||
bool sl_power_manager_is_latest_wakeup_internal(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
bool sleep;
|
||||
|
||||
|
@ -714,7 +778,7 @@ bool sl_power_manager_is_latest_wakeup_internal(void)
|
|||
************************** LOCAL FUNCTIONS ********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Get lowest energy mode to apply given the requirements on the different
|
||||
* energy modes.
|
||||
|
@ -730,7 +794,7 @@ static sl_power_manager_em_t get_lowest_em(void)
|
|||
sl_power_manager_em_t em;
|
||||
|
||||
// Retrieve lowest Energy mode allowed given the requirements
|
||||
for (em_ix = 1; (em_ix < SL_POWER_MANAGER_LOWEST_EM_ALLOWED) && (requirement_em_table[em_ix - 1] == 0); em_ix++) {
|
||||
for (em_ix = 1; (em_ix < 3) && (requirement_em_table[em_ix - 1] == 0); em_ix++) {
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -802,6 +866,33 @@ static void power_manager_notify_em_transition(sl_power_manager_em_t from,
|
|||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enter critical section by disabling interrupts using PriMask.
|
||||
*
|
||||
* @return primask Initial primask state.
|
||||
*
|
||||
* @note @ref sl_power_manager_sleep() function should use PriMask to disable
|
||||
* interrupts.
|
||||
******************************************************************************/
|
||||
static CORE_irqState_t enter_critical_with_primask(void)
|
||||
{
|
||||
CORE_irqState_t irqState = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
|
||||
return irqState;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Exit critical section by re-enabling interrupts using PriMask.
|
||||
*
|
||||
* @param primask_state Initial primask state.
|
||||
******************************************************************************/
|
||||
static void exit_critical_with_primask(CORE_irqState_t primask_state)
|
||||
{
|
||||
if (primask_state == 0U) {
|
||||
__enable_irq();
|
||||
}
|
||||
}
|
||||
/***************************************************************************//**
|
||||
* Evaluates scheduled wakeup and restart timer based on the wakeup time.
|
||||
* If the remaining time is shorter than the wakeup time then add a requirement
|
||||
|
@ -809,7 +900,7 @@ static void power_manager_notify_em_transition(sl_power_manager_em_t from,
|
|||
*
|
||||
* @note Must be called in a critical section.
|
||||
******************************************************************************/
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
static void evaluate_wakeup(sl_power_manager_em_t to)
|
||||
{
|
||||
sl_status_t status;
|
||||
|
@ -852,13 +943,17 @@ static void evaluate_wakeup(sl_power_manager_em_t to)
|
|||
update_em1_requirement(true);
|
||||
requirement_on_em1_added = true;
|
||||
} else {
|
||||
uint16_t hf_accuracy_clk_flag = 0;
|
||||
if (sli_power_manager_is_high_freq_accuracy_clk_used()) {
|
||||
hf_accuracy_clk_flag = SLI_SLEEPTIMER_POWER_MANAGER_HF_ACCURACY_CLK_FLAG;
|
||||
}
|
||||
// Start internal sleeptimer to do the early wake-up.
|
||||
sl_sleeptimer_restart_timer(&clock_wakeup_timer_handle,
|
||||
(tick_remaining - (uint32_t)wakeup_delay),
|
||||
on_clock_wakeup_timeout,
|
||||
NULL,
|
||||
0,
|
||||
SLI_SLEEPTIMER_POWER_MANAGER_EARLY_WAKEUP_TIMER_FLAG);
|
||||
(SLI_SLEEPTIMER_POWER_MANAGER_EARLY_WAKEUP_TIMER_FLAG | hf_accuracy_clk_flag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -870,7 +965,7 @@ static void evaluate_wakeup(sl_power_manager_em_t to)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Updates internal EM1 requirement.
|
||||
* We add an internal EM1 requirement when we would usually go into EM2/EM3
|
||||
|
@ -917,7 +1012,7 @@ static void update_em1_requirement(bool add)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Do clock restore process and wait for it to be completed.
|
||||
******************************************************************************/
|
||||
|
@ -954,7 +1049,7 @@ static void clock_restore_and_wait(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Start clock restore process.
|
||||
*
|
||||
|
@ -987,7 +1082,7 @@ static void clock_restore(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Callback for clock enable timer.
|
||||
*
|
||||
|
@ -1031,11 +1126,11 @@ static void on_clock_wakeup_timeout(sl_sleeptimer_timer_handle_t *handle,
|
|||
******************************************************************************/
|
||||
void sli_hfxo_manager_notify_ready_for_power_manager(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// Complete HF restore and change current Energy mode
|
||||
// The notification will be done once back in the sleep loop
|
||||
if (current_em != SL_POWER_MANAGER_EM0
|
||||
&& is_sleeping_waiting_for_clock_restore == true) {
|
||||
&& (is_sleeping_waiting_for_clock_restore == true)) {
|
||||
sli_power_manager_restore_states();
|
||||
is_sleeping_waiting_for_clock_restore = false;
|
||||
is_states_saved = false;
|
||||
|
@ -1045,18 +1140,35 @@ void sli_hfxo_manager_notify_ready_for_power_manager(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(EMU_VSCALE_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* HFXO PRS ready notification callback for internal use with power manager
|
||||
*
|
||||
* @note Will only be used on series 2 devices when HFXO Manager and SYSRTC
|
||||
* is present.
|
||||
******************************************************************************/
|
||||
void sli_hfxo_notify_ready_for_power_manager_from_prs(void)
|
||||
{
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// Set clock restore to true to indicate that HFXO has been restored from a
|
||||
// PRS interrupt unless already in EM0 indicating HFXO didn't need to be restored.
|
||||
if (current_em != SL_POWER_MANAGER_EM0) {
|
||||
is_sleeping_waiting_for_clock_restore = true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable or disable fast wake-up in EM2 and EM3
|
||||
*
|
||||
* @note Will also update the wake up time from EM2 to EM0.
|
||||
*
|
||||
* @note This function will do nothing when SL_POWER_MANAGER_LOWEST_EM_ALLOWED
|
||||
* config is set to EM1.
|
||||
* @note This function will do nothing when a project contains the
|
||||
* power_manager_no_deepsleep component, which configures the
|
||||
* lowest energy mode as EM1.
|
||||
******************************************************************************/
|
||||
void sl_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if (defined(EMU_VSCALE_PRESENT) && !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT))
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
|
||||
CORE_ENTER_CRITICAL();
|
||||
|
@ -1068,4 +1180,3 @@ void sl_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable)
|
|||
(void)enable;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -38,7 +38,13 @@
|
|||
#include "sli_power_manager_private.h"
|
||||
#include "sl_sleeptimer.h"
|
||||
#include "sli_sleeptimer.h"
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) \
|
||||
&& !defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
#include "sli_hfxo_manager.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -51,11 +57,10 @@
|
|||
// Voltage scaling, HFXO startup and HFXO steady times are excluded from
|
||||
// this because they are handled separately. RTCCSYNC time is also
|
||||
// excluded and it is handled by RTCCSYNC code itself.
|
||||
//TODO need to validate this value. how?
|
||||
#if (_SILICON_LABS_32B_SERIES_2_CONFIG == 1)
|
||||
#define EM2_WAKEUP_PROCESS_TIME_OVERHEAD_US (100u) //(380u)
|
||||
#define EM2_WAKEUP_PROCESS_TIME_OVERHEAD_US (31u)
|
||||
#else // (_SILICON_LABS_32B_SERIES_2_CONFIG == 2),
|
||||
#define EM2_WAKEUP_PROCESS_TIME_OVERHEAD_US (100u) //(345u)
|
||||
#define EM2_WAKEUP_PROCESS_TIME_OVERHEAD_US (31u)
|
||||
#endif
|
||||
|
||||
// DPLL Locking delay related defines
|
||||
|
@ -66,7 +71,7 @@
|
|||
#define EM2_WAKEUP_VSCALE_OVERHEAD_US (64u)
|
||||
|
||||
// Default time value in microseconds required to wake-up the hfxo oscillator.
|
||||
#define HFXO_WAKE_UP_TIME_DEFAULT_VALUE_US (600u)
|
||||
#define HFXO_WAKE_UP_TIME_DEFAULT_VALUE_US (400u)
|
||||
|
||||
// high frequency oscillator wake-up time margin for possible variation
|
||||
// A shift by 3 will be like a division by 8, so a percentage of 12.5%.
|
||||
|
@ -75,11 +80,13 @@
|
|||
// Default time value in microseconds for the HFXO minimum off time.
|
||||
#define HFXO_MINIMUM_OFFTIME_DEFAULT_VALUE_US (400u)
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
// Table size of HFXO wake-up time measurement
|
||||
#define HFXO_WAKE_UP_TIME_TABLE_SIZE 10
|
||||
#endif
|
||||
|
||||
// Defines for hidden DBGSTATUS register and STARTUPDONE flag
|
||||
#define DBGSTATUS RESERVED6[0]
|
||||
// Defines for hidden HFXO0 DBGSTATUS register and STARTUPDONE flag
|
||||
#define HFXO0_DBGSTATUS (*(volatile uint32_t *)(HFXO0_BASE + 0x05C))
|
||||
#define HFXO_DBGSTATUS_STARTUPDONE (0x1UL << 1) /**< Startup Done Status */
|
||||
#define _HFXO_DBGSTATUS_STARTUPDONE_SHIFT 1 /**< Shift value for HFXO_STARTUPDONE */
|
||||
#define _HFXO_DBGSTATUS_STARTUPDONE_MASK 0x2UL /**< Bit mask for HFXO_STARTUPDONE */
|
||||
|
@ -104,8 +111,19 @@
|
|||
*************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
// Variables to save the relevant clock registers.
|
||||
uint32_t cmu_em01_grpA_clock_register;
|
||||
#if defined(_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK)
|
||||
uint32_t cmu_em01_grpB_clock_register;
|
||||
#endif
|
||||
#if defined(_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK)
|
||||
uint32_t cmu_em01_grpC_clock_register;
|
||||
#endif
|
||||
#if defined(_CMU_DPLLREFCLKCTRL_CLKSEL_MASK)
|
||||
uint32_t cmu_dpll_ref_clock_register;
|
||||
#endif
|
||||
|
||||
uint32_t cmu_sys_clock_register;
|
||||
|
||||
// Time in ticks required for the general wake-up process.
|
||||
|
@ -120,6 +138,17 @@ static bool is_dpll_used = false;
|
|||
static bool is_entering_deepsleep = false;
|
||||
|
||||
static bool is_hf_x_oscillator_already_started = false;
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
static uint32_t hf_x_oscillator_wakeup_time_tc_inital = 0;
|
||||
|
||||
static uint32_t hfxo_wakeup_time_table[HFXO_WAKE_UP_TIME_TABLE_SIZE];
|
||||
static uint8_t hfxo_wakeup_time_table_index = 0;
|
||||
static uint32_t hfxo_wakeup_time_sum_average = 0;
|
||||
|
||||
// Time in ticks required for HFXO start-up after wake-up from sleep.
|
||||
static uint32_t hfxo_wakeup_time_tick = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -131,13 +160,6 @@ static bool is_hf_x_oscillator_already_started = false;
|
|||
******************************************************************************/
|
||||
void sli_power_manager_init_hardware(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
uint32_t cmu_em01_grpA_clock_register;
|
||||
#if defined(CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO)
|
||||
uint32_t cmu_em01_grpB_clock_register;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initializes EMU (voltage scaling in EM2/3)
|
||||
#if defined(EMU_VSCALE_EM01_PRESENT)
|
||||
EMU_EM01Init_TypeDef em01_init = EMU_EM01INIT_DEFAULT;
|
||||
|
@ -145,7 +167,7 @@ void sli_power_manager_init_hardware(void)
|
|||
EMU_EM01Init(&em01_init);
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
#if defined(EMU_VSCALE_PRESENT)
|
||||
#if defined(SL_POWER_MANAGER_CONFIG_VOLTAGE_SCALING_FAST_WAKEUP)
|
||||
#if (SL_POWER_MANAGER_CONFIG_VOLTAGE_SCALING_FAST_WAKEUP == 0)
|
||||
|
@ -160,9 +182,8 @@ void sli_power_manager_init_hardware(void)
|
|||
|
||||
// Get the current HF oscillator for the SYSCLK
|
||||
cmu_sys_clock_register = CMU->SYSCLKCTRL & _CMU_SYSCLKCTRL_CLKSEL_MASK;
|
||||
cmu_em01_grpA_clock_register = CMU->EM01GRPACLKCTRL & _CMU_EM01GRPACLKCTRL_CLKSEL_MASK;
|
||||
#if defined(CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO)
|
||||
cmu_em01_grpB_clock_register = CMU->EM01GRPBCLKCTRL & _CMU_EM01GRPBCLKCTRL_CLKSEL_MASK;
|
||||
#if defined(_CMU_DPLLREFCLKCTRL_CLKSEL_MASK)
|
||||
cmu_dpll_ref_clock_register = CMU->DPLLREFCLKCTRL & _CMU_DPLLREFCLKCTRL_CLKSEL_MASK;
|
||||
#endif
|
||||
|
||||
#if defined(CMU_CLKEN0_DPLL0)
|
||||
|
@ -174,14 +195,27 @@ void sli_power_manager_init_hardware(void)
|
|||
is_dpll_used = ((DPLL0->STATUS & _DPLL_STATUS_ENS_MASK) != 0);
|
||||
|
||||
is_hf_x_oscillator_used = ((cmu_sys_clock_register == CMU_SYSCLKCTRL_CLKSEL_HFXO)
|
||||
|| (cmu_em01_grpA_clock_register == CMU_EM01GRPACLKCTRL_CLKSEL_HFXO));
|
||||
|| ((CMU->EM01GRPACLKCTRL & _CMU_EM01GRPACLKCTRL_CLKSEL_MASK) == CMU_EM01GRPACLKCTRL_CLKSEL_HFXO));
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
|
||||
is_hf_x_oscillator_used |= (CMU->RADIOCLKCTRL & _CMU_RADIOCLKCTRL_EN_MASK) != 0;
|
||||
#endif
|
||||
|
||||
#if defined(CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO)
|
||||
is_hf_x_oscillator_used |= (cmu_em01_grpB_clock_register == CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO);
|
||||
is_hf_x_oscillator_used |= ((CMU->EM01GRPBCLKCTRL & _CMU_EM01GRPBCLKCTRL_CLKSEL_MASK) == CMU_EM01GRPBCLKCTRL_CLKSEL_HFXO);
|
||||
#endif
|
||||
|
||||
#if defined(CMU_EM01GRPCCLKCTRL_CLKSEL_HFXO)
|
||||
is_hf_x_oscillator_used |= ((CMU->EM01GRPCCLKCTRL & _CMU_EM01GRPCCLKCTRL_CLKSEL_MASK) == CMU_EM01GRPCCLKCTRL_CLKSEL_HFXO);
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
// Set HFXO wakeup time to conservative default value
|
||||
hfxo_wakeup_time_tick = sli_power_manager_convert_delay_us_to_tick(HFXO_WAKE_UP_TIME_DEFAULT_VALUE_US);
|
||||
for (uint8_t i = 0; i < HFXO_WAKE_UP_TIME_TABLE_SIZE; i++) {
|
||||
hfxo_wakeup_time_table[i] = hfxo_wakeup_time_tick;
|
||||
hfxo_wakeup_time_sum_average += hfxo_wakeup_time_tick;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (is_dpll_used && !is_hf_x_oscillator_used) {
|
||||
|
@ -219,13 +253,13 @@ void sli_power_manager_init_hardware(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if defined(EMU_VSCALE_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Enable or disable fast wake-up in EM2 and EM3.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable)
|
||||
{
|
||||
#if (defined(EMU_VSCALE_PRESENT) && !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT))
|
||||
|
||||
if (enable == is_fast_wakeup_enabled) {
|
||||
return;
|
||||
}
|
||||
|
@ -251,21 +285,31 @@ void sli_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable)
|
|||
}
|
||||
|
||||
is_fast_wakeup_enabled = enable;
|
||||
#else
|
||||
(void)enable;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Save the CMU HF clock select state, oscillator enable, and voltage scaling.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_save_states(void)
|
||||
{
|
||||
// Save HF clock sources
|
||||
cmu_em01_grpA_clock_register = CMU->EM01GRPACLKCTRL & _CMU_EM01GRPACLKCTRL_CLKSEL_MASK;
|
||||
#if defined(_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK)
|
||||
cmu_em01_grpB_clock_register = CMU->EM01GRPBCLKCTRL & _CMU_EM01GRPBCLKCTRL_CLKSEL_MASK;
|
||||
#endif
|
||||
#if defined(_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK)
|
||||
cmu_em01_grpC_clock_register = CMU->EM01GRPCCLKCTRL & _CMU_EM01GRPCCLKCTRL_CLKSEL_MASK;
|
||||
#endif
|
||||
|
||||
EMU_Save();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Handle pre-sleep operations if any are necessary, like manually disabling
|
||||
* oscillators, change clock settings, etc.
|
||||
|
@ -277,13 +321,31 @@ void EMU_EM23PresleepHook(void)
|
|||
is_entering_deepsleep = false;
|
||||
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | _CMU_SYSCLKCTRL_CLKSEL_FSRCO;
|
||||
// Switch the HF Clocks oscillator's to FSRCO before deepsleep
|
||||
CMU->EM01GRPACLKCTRL = (CMU->EM01GRPACLKCTRL & ~_CMU_EM01GRPACLKCTRL_CLKSEL_MASK) | _CMU_EM01GRPACLKCTRL_CLKSEL_FSRCO;
|
||||
#if defined(_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK)
|
||||
CMU->EM01GRPBCLKCTRL = (CMU->EM01GRPBCLKCTRL & ~_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK) | _CMU_EM01GRPBCLKCTRL_CLKSEL_FSRCO;
|
||||
#endif
|
||||
#if defined(_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK)
|
||||
CMU->EM01GRPCCLKCTRL = (CMU->EM01GRPCCLKCTRL & ~_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK) | _CMU_EM01GRPCCLKCTRL_CLKSEL_FSRCO;
|
||||
#endif
|
||||
// Disable DPLL before deepsleep
|
||||
#if (_DPLL_IPVERSION_IPVERSION_DEFAULT >= 1)
|
||||
#if defined(_CMU_DPLLREFCLKCTRL_CLKSEL_MASK)
|
||||
if (is_dpll_used) {
|
||||
DPLL0->EN_CLR = DPLL_EN_EN;
|
||||
while ((DPLL0->EN & _DPLL_EN_DISABLING_MASK) != 0) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Handle post-sleep operations. The idea is to start HFXO ASAP when we know we
|
||||
* will need it.
|
||||
|
@ -304,25 +366,37 @@ void EMU_EM23PostsleepHook(void)
|
|||
&& sli_sleeptimer_is_power_manager_timer_next_to_expire()) {
|
||||
// Check if HFXO is already running and has finished its startup.
|
||||
// If yes, don't do the HFXO restore time measurement.
|
||||
if ((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0
|
||||
&& (HFXO0->DBGSTATUS & _HFXO_DBGSTATUS_STARTUPDONE_MASK) != 0) {
|
||||
if (((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0
|
||||
&& (HFXO0_DBGSTATUS & _HFXO_DBGSTATUS_STARTUPDONE_MASK) != 0)
|
||||
|| (HFXO0->STATUS & _HFXO_STATUS_RDY_MASK) != 0) {
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
// Force-enable HFXO in case the HFXO on-demand request would be removed
|
||||
// before we finish the restore process.
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
// Start measure HFXO restore time.
|
||||
is_hf_x_oscillator_already_started = true;
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
hf_x_oscillator_wakeup_time_tc_inital = sl_sleeptimer_get_tick_count();
|
||||
|
||||
// Switch SYSCLK to HFXO to measure restore time
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | cmuSelect_HFXO;
|
||||
SystemCoreClockUpdate();
|
||||
#else
|
||||
sli_hfxo_manager_begin_startup_measurement();
|
||||
|
||||
// Force enable HFXO to measure restore time
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Handle pre-deepsleep operations if any are necessary, like manually disabling
|
||||
* oscillators, change clock settings, etc.
|
||||
|
@ -333,7 +407,7 @@ void sli_power_manager_handle_pre_deepsleep_operations(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Handle post-sleep operations if any are necessary, like manually enabling
|
||||
* oscillators, change clock settings, etc.
|
||||
|
@ -349,26 +423,49 @@ void sli_power_manager_restore_high_freq_accuracy_clk(void)
|
|||
if (!is_hf_x_oscillator_already_started) {
|
||||
// Check if HFXO is already running and has finished its startup.
|
||||
// If yes, don't do the HFXO restore time measurement.
|
||||
if ((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0
|
||||
&& (HFXO0->DBGSTATUS & _HFXO_DBGSTATUS_STARTUPDONE_MASK) != 0) {
|
||||
if (((HFXO0->STATUS & _HFXO_STATUS_ENS_MASK) != 0
|
||||
&& (HFXO0_DBGSTATUS & _HFXO_DBGSTATUS_STARTUPDONE_MASK) != 0)
|
||||
|| (HFXO0->STATUS & _HFXO_STATUS_RDY_MASK) != 0) {
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
// Force-enable HFXO in case the HFXO on-demand request would be removed
|
||||
// before we finish the restore process.
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
hf_x_oscillator_wakeup_time_tc_inital = sl_sleeptimer_get_tick_count();
|
||||
|
||||
// Switch SYSCLK to HFXO to measure restore time
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | cmuSelect_HFXO;
|
||||
SystemCoreClockUpdate();
|
||||
#else
|
||||
// Start measure HFXO restore time
|
||||
sli_hfxo_manager_begin_startup_measurement();
|
||||
|
||||
// Force enable HFXO to measure restore time
|
||||
HFXO0->CTRL_SET = HFXO_CTRL_FORCEEN;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
uint32_t current_time = sl_sleeptimer_get_tick_count() - hf_x_oscillator_wakeup_time_tc_inital;
|
||||
// Calculate average for HFXO restore time
|
||||
hfxo_wakeup_time_sum_average -= (int32_t)hfxo_wakeup_time_table[hfxo_wakeup_time_table_index] - (int32_t)current_time;
|
||||
hfxo_wakeup_time_table[hfxo_wakeup_time_table_index] = current_time;
|
||||
hfxo_wakeup_time_tick = ((hfxo_wakeup_time_sum_average + (HFXO_WAKE_UP_TIME_TABLE_SIZE - 1) ) / HFXO_WAKE_UP_TIME_TABLE_SIZE);
|
||||
|
||||
// Update index of wakeup time table
|
||||
hfxo_wakeup_time_table_index++;
|
||||
hfxo_wakeup_time_table_index %= HFXO_WAKE_UP_TIME_TABLE_SIZE;
|
||||
#endif
|
||||
|
||||
is_hf_x_oscillator_already_started = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Checks if HF accuracy clocks is fully restored and, if needed, waits for it.
|
||||
*
|
||||
|
@ -384,21 +481,47 @@ bool sli_power_manager_is_high_freq_accuracy_clk_ready(bool wait)
|
|||
return true;
|
||||
}
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
(void)wait;
|
||||
return true;
|
||||
#else
|
||||
return sli_hfxo_manager_is_hfxo_ready(wait);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Restore CMU HF clock select state, oscillator enable, and voltage scaling.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_restore_states(void)
|
||||
{
|
||||
// Restore specific EMU saved contexts
|
||||
EMU_Restore();
|
||||
|
||||
// Restore DPLL after deepsleep
|
||||
#if (_DPLL_IPVERSION_IPVERSION_DEFAULT >= 1)
|
||||
#if defined(_CMU_DPLLREFCLKCTRL_CLKSEL_MASK)
|
||||
if (is_dpll_used) {
|
||||
DPLL0->EN_SET = DPLL_EN_EN;
|
||||
while ((DPLL0->STATUS & _DPLL_STATUS_RDY_MASK) == 0U) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Restore SYSCLK to what it was before the deepsleep
|
||||
CMU->SYSCLKCTRL = (CMU->SYSCLKCTRL & ~_CMU_SYSCLKCTRL_CLKSEL_MASK) | cmu_sys_clock_register;
|
||||
|
||||
// Restore the HF Clocks to what they were before deepsleep
|
||||
CMU->EM01GRPACLKCTRL = (CMU->EM01GRPACLKCTRL & ~_CMU_EM01GRPACLKCTRL_CLKSEL_MASK) | cmu_em01_grpA_clock_register;
|
||||
#if defined(_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK)
|
||||
CMU->EM01GRPBCLKCTRL = (CMU->EM01GRPBCLKCTRL & ~_CMU_EM01GRPBCLKCTRL_CLKSEL_MASK) | cmu_em01_grpB_clock_register;
|
||||
#endif
|
||||
#if defined(_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK)
|
||||
CMU->EM01GRPCCLKCTRL = (CMU->EM01GRPCCLKCTRL & ~_CMU_EM01GRPCCLKCTRL_CLKSEL_MASK) | cmu_em01_grpC_clock_register;
|
||||
#endif
|
||||
|
||||
// Remove FORCEEN on HFXO
|
||||
if (is_hf_x_oscillator_used) {
|
||||
HFXO0->CTRL_CLR = HFXO_CTRL_FORCEEN;
|
||||
|
@ -406,8 +529,8 @@ void sli_power_manager_restore_states(void)
|
|||
|
||||
SystemCoreClockUpdate();
|
||||
|
||||
#if 0 // TODO PLATFORM_MTL-8499
|
||||
// Wait for DPLL to lock
|
||||
#if 0 // TODO This seems to cause issues in some cases. That has to be fixed.
|
||||
if (is_dpll_used) {
|
||||
while (!(DPLL0->STATUS && _DPLL_STATUS_RDY_MASK)) {
|
||||
}
|
||||
|
@ -461,7 +584,7 @@ void sli_power_manager_apply_em(sl_power_manager_em_t em)
|
|||
}
|
||||
}
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Returns the default minimum offtime for HFXO.
|
||||
******************************************************************************/
|
||||
|
@ -478,12 +601,16 @@ uint32_t sli_power_manager_get_default_high_frequency_minimum_offtime(void)
|
|||
******************************************************************************/
|
||||
uint32_t sli_power_manager_get_wakeup_process_time_overhead(void)
|
||||
{
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
uint32_t delay = 0;
|
||||
|
||||
// Add HFXO start-up delay if applicable
|
||||
if (is_hf_x_oscillator_used) {
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_DEEPSLEEP_BLOCKING_HFXO_RESTORE_PRESENT)
|
||||
delay = hfxo_wakeup_time_tick;
|
||||
#else
|
||||
delay = sli_hfxo_manager_get_startup_time();
|
||||
#endif
|
||||
delay += delay >> HFXO_START_UP_TIME_OVERHEAD_LOG2;
|
||||
}
|
||||
|
||||
|
@ -496,7 +623,7 @@ uint32_t sli_power_manager_get_wakeup_process_time_overhead(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/***************************************************************************//**
|
||||
* Informs the power manager module that the high accuracy/high frequency clock
|
||||
* is used.
|
||||
|
@ -507,7 +634,7 @@ void sli_power_manager_set_high_accuracy_hf_clock_as_used(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Restores the Low Frequency clocks according to what LF oscillators are used.
|
||||
*
|
||||
|
@ -517,5 +644,16 @@ void sli_power_manager_set_high_accuracy_hf_clock_as_used(void)
|
|||
void sli_power_manager_low_frequency_restore(void)
|
||||
{
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Informs the power manager if the high accuracy/high frequency clock
|
||||
* is used, prior to scheduling an early clock restore.
|
||||
*
|
||||
* @return true if HFXO is used, else false.
|
||||
******************************************************************************/
|
||||
bool sli_power_manager_is_high_freq_accuracy_clk_used(void)
|
||||
{
|
||||
return is_hf_x_oscillator_used;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
#include "sl_cycle_counter.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
@ -73,7 +77,7 @@ void sli_power_manager_apply_em(sl_power_manager_em_t em);
|
|||
|
||||
void sli_power_manager_debug_init(void);
|
||||
|
||||
#if (SL_POWER_MANAGER_LOWEST_EM_ALLOWED != 1)
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
void sli_power_manager_save_states(void);
|
||||
|
||||
void sli_power_manager_handle_pre_deepsleep_operations(void);
|
||||
|
@ -94,20 +98,26 @@ uint32_t sli_power_manager_convert_delay_us_to_tick(uint32_t time_us);
|
|||
******************************************************************************/
|
||||
uint32_t sli_power_manager_get_default_high_frequency_minimum_offtime(void);
|
||||
|
||||
#if defined(EMU_VSCALE_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Restores the Low Frequency clocks according to which LF oscillators are used.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_low_frequency_restore(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Informs the power manager if the high accuracy/high frequency clock
|
||||
* is used, prior to scheduling an early clock restore.
|
||||
*
|
||||
* @return true if HFXO is used, else false.
|
||||
******************************************************************************/
|
||||
bool sli_power_manager_is_high_freq_accuracy_clk_used(void);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* Enable or disable fast wake-up in EM2 and EM3
|
||||
*
|
||||
* @note Will also update the wake up time from EM2 to EM0.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_em23_voltage_scaling_enable_fast_wakeup(bool enable);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Restores the Low Frequency clocks according to which LF oscillators are used.
|
||||
******************************************************************************/
|
||||
void sli_power_manager_low_frequency_restore(void);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Gets the delay associated the wake-up process from EM23.
|
||||
|
@ -115,3 +125,18 @@ void sli_power_manager_low_frequency_restore(void);
|
|||
* @return Delay for the complete wake-up process with full restore.
|
||||
******************************************************************************/
|
||||
uint32_t sli_power_manager_get_wakeup_process_time_overhead(void);
|
||||
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT)
|
||||
/*******************************************************************************
|
||||
* Gets the status of power manager variable is_sleeping_waiting_for_clock_restore.
|
||||
*
|
||||
* @return true if Power Manager is sleeping waiting for clock restore, else false.
|
||||
*
|
||||
* @note FOR INTERNAL USE ONLY.
|
||||
******************************************************************************/
|
||||
bool sli_power_manager_get_clock_restore_status(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#define SL_SLEEPTIMER_PERIPHERAL_RTC 3
|
||||
#define SL_SLEEPTIMER_PERIPHERAL_SYSRTC 4
|
||||
#define SL_SLEEPTIMER_PERIPHERAL_BURTC 5
|
||||
#define SL_SLEEPTIMER_PERIPHERAL_WTIMER 6
|
||||
#define SL_SLEEPTIMER_PERIPHERAL_TIMER 7
|
||||
|
||||
// <o SL_SLEEPTIMER_PERIPHERAL> Timer Peripheral Used by Sleeptimer
|
||||
// <SL_SLEEPTIMER_PERIPHERAL_DEFAULT=> Default (auto select)
|
||||
|
@ -47,15 +49,23 @@
|
|||
// <SL_SLEEPTIMER_PERIPHERAL_RTC=> RTC
|
||||
// <SL_SLEEPTIMER_PERIPHERAL_SYSRTC=> SYSRTC
|
||||
// <SL_SLEEPTIMER_PERIPHERAL_BURTC=> Back-Up RTC (BURTC)
|
||||
// <SL_SLEEPTIMER_PERIPHERAL_WTIMER=> WTIMER
|
||||
// <SL_SLEEPTIMER_PERIPHERAL_TIMER=> TIMER
|
||||
// <i> Selection of the Timer Peripheral Used by the Sleeptimer
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_DEFAULT
|
||||
|
||||
// <o SL_SLEEPTIMER_TIMER_INSTANCE> TIMER/WTIMER Instance Used by Sleeptimer (not applicable for other peripherals)
|
||||
// <i> Make sure TIMER instance size is 32bits. Check datasheet for 32bits TIMERs.
|
||||
// <i> Default: 0
|
||||
#define SL_SLEEPTIMER_TIMER_INSTANCE 0
|
||||
|
||||
// <q SL_SLEEPTIMER_WALLCLOCK_CONFIG> Enable wallclock functionality
|
||||
// <i> Enable or disable wallclock functionalities (get_time, get_date, etc).
|
||||
// <i> Default: 0
|
||||
#define SL_SLEEPTIMER_WALLCLOCK_CONFIG 0
|
||||
|
||||
// <o SL_SLEEPTIMER_FREQ_DIVIDER> Timer frequency divider
|
||||
// <o SL_SLEEPTIMER_FREQ_DIVIDER> Timer frequency divider (not applicable for WTIMER/TIMER)
|
||||
// <i> WTIMER/TIMER peripherals are always prescaled to 1024.
|
||||
// <i> Default: 1
|
||||
#define SL_SLEEPTIMER_FREQ_DIVIDER 1
|
||||
|
||||
|
|
|
@ -35,16 +35,50 @@
|
|||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "em_device.h"
|
||||
#include "sl_sleeptimer_config.h"
|
||||
|
||||
#define SLEEPTIMER_EVENT_OF (0x01)
|
||||
#define SLEEPTIMER_EVENT_COMP (0x02)
|
||||
|
||||
#define SLI_SLEEPTIMER_POWER_MANAGER_EARLY_WAKEUP_TIMER_FLAG 0x02
|
||||
#define SLI_SLEEPTIMER_POWER_MANAGER_HF_ACCURACY_CLK_FLAG 0x04
|
||||
|
||||
#if SL_SLEEPTIMER_PERIPHERAL == SL_SLEEPTIMER_PERIPHERAL_DEFAULT
|
||||
#if defined(RTCC_PRESENT) && RTCC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_RTCC
|
||||
#elif defined(RTC_PRESENT) && RTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_RTC
|
||||
#elif defined(SYSRTC_PRESENT) && SYSRTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_SYSRTC
|
||||
#elif defined(BURTC_PRESENT) && BURTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_BURTC
|
||||
#elif defined(WTIMER_PRESENT) && WTIMER_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_WTIMER
|
||||
#elif defined(TIMER_PRESENT) && TIMER_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_TIMER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to perform initialization related to Power Manager.
|
||||
******************************************************************************/
|
||||
__WEAK void sli_sleeptimer_hal_power_manager_integration_init(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to perform initialization related to HFXO Manager.
|
||||
******************************************************************************/
|
||||
__WEAK void sli_sleeptimer_hal_hfxo_manager_integration_init(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get interrupt status.
|
||||
*
|
||||
|
@ -63,6 +97,38 @@ bool sli_sleeptimer_hal_is_int_status_set(uint8_t local_flag);
|
|||
*****************************************************************************/
|
||||
bool sli_sleeptimer_is_power_manager_timer_next_to_expire(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set lowest energy mode based on a project's configurations and clock source
|
||||
*
|
||||
* @note If power_manager_no_deepsleep component is included in a project, the
|
||||
* lowest possible energy mode is EM1, else lowest energy mode is
|
||||
* determined by clock source.
|
||||
******************************************************************************/
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
void sli_sleeptimer_set_pm_em_requirement(void);
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Update sleep_on_isr_exit flag.
|
||||
*
|
||||
* @param flag Boolean value update_sleep_on_isr_exit will be set to.
|
||||
******************************************************************************/
|
||||
void sli_sleeptimer_update_sleep_on_isr_exit(bool flag);
|
||||
|
||||
/*******************************************************************************
|
||||
* Gets the associated peripheral capture channel current value.
|
||||
*
|
||||
* @return Capture value
|
||||
* 0 if capture channel is not valid
|
||||
******************************************************************************/
|
||||
uint32_t sli_sleeptimer_get_capture(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Resets the PRS signal triggered by the associated peripheral.
|
||||
******************************************************************************/
|
||||
void sli_sleeptimer_reset_prs_signal(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1900,3 +1900,43 @@ static bool is_valid_date_64(sl_sleeptimer_date_t *date)
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Gets the precision (in PPM) of the sleeptimer's clock.
|
||||
*
|
||||
* @return
|
||||
* Clock accuracy, in PPM.
|
||||
*
|
||||
******************************************************************************/
|
||||
uint16_t sl_sleeptimer_get_clock_accuracy(void)
|
||||
{
|
||||
return sleeptimer_hal_get_clock_accuracy();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Update sleep_on_isr_exit flag.
|
||||
*
|
||||
* @param flag Value update_sleep_on_isr_exit will be set to.
|
||||
******************************************************************************/
|
||||
void sli_sleeptimer_update_sleep_on_isr_exit(bool flag)
|
||||
{
|
||||
sleep_on_isr_exit = flag;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Gets the associated peripheral capture channel current value.
|
||||
******************************************************************************/
|
||||
uint32_t sli_sleeptimer_get_capture(void)
|
||||
{
|
||||
return sleeptimer_hal_get_capture();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Resets the PRS signal triggered by the associated peripheral.
|
||||
******************************************************************************/
|
||||
void sli_sleeptimer_reset_prs_signal(void)
|
||||
{
|
||||
sleeptimer_hal_reset_prs_signal();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
#include "em_core.h"
|
||||
#include "em_cmu.h"
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
#include "sl_power_manager.h"
|
||||
#endif
|
||||
|
||||
#if SL_SLEEPTIMER_PERIPHERAL == SL_SLEEPTIMER_PERIPHERAL_RTCC
|
||||
|
||||
// Minimum difference between current count value and what the comparator of the timer can be set to.
|
||||
|
@ -256,4 +260,82 @@ __STATIC_INLINE uint32_t get_time_diff(uint32_t a,
|
|||
return (a - b);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* @brief
|
||||
* Gets the precision (in PPM) of the sleeptimer's clock.
|
||||
*
|
||||
* @return
|
||||
* Clock accuracy, in PPM.
|
||||
*
|
||||
******************************************************************************/
|
||||
uint16_t sleeptimer_hal_get_clock_accuracy(void)
|
||||
{
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
return CMU_LF_ClockPrecisionGet(cmuClock_RTCC);
|
||||
|
||||
#else
|
||||
return CMU_LF_ClockPrecisionGet(cmuClock_LFE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get the capture channel value.
|
||||
******************************************************************************/
|
||||
uint32_t sleeptimer_hal_get_capture(void)
|
||||
{
|
||||
// Invalid for RTCC peripheral
|
||||
EFM_ASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to reset PRS signal triggered by the associated
|
||||
* peripheral.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_reset_prs_signal(void)
|
||||
{
|
||||
// Invalid for RTCC peripheral
|
||||
EFM_ASSERT(0);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set lowest energy mode based on a project's configurations and clock source
|
||||
*
|
||||
* @note If power_manager_no_deepsleep component is included in a project, the
|
||||
* lowest possible energy mode is EM1, else lowest energy mode is
|
||||
* determined by clock source.
|
||||
******************************************************************************/
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
void sli_sleeptimer_set_pm_em_requirement(void)
|
||||
{
|
||||
#if defined(_CMU_RTCCCLKCTRL_CLKSEL_MASK)
|
||||
switch (CMU->RTCCCLKCTRL & _CMU_RTCCCLKCTRL_CLKSEL_MASK) {
|
||||
case CMU_RTCCCLKCTRL_CLKSEL_LFRCO:
|
||||
case CMU_RTCCCLKCTRL_CLKSEL_LFXO:
|
||||
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#elif defined(_CMU_LFECLKEN0_RTCC_MASK)
|
||||
switch ((CMU->LFECLKSEL & _CMU_LFECLKSEL_LFE_MASK) >> _CMU_LFECLKSEL_LFE_SHIFT) {
|
||||
case CMU_LFECLKSEL_LFE_LFRCO:
|
||||
case CMU_LFECLKSEL_LFE_LFXO:
|
||||
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#elif defined(_CMU_LFACLKEN0_RTCC_MASK)
|
||||
switch ((CMU->LFACLKSEL & _CMU_LFACLKSEL_LFA_MASK) >> _CMU_LFACLKSEL_LFA_SHIFT) {
|
||||
case CMU_LFACLKSEL_LFA_LFRCO:
|
||||
case CMU_LFACLKSEL_LFA_LFXO:
|
||||
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -28,20 +28,27 @@
|
|||
*
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
#include "peripheral_sysrtc.h"
|
||||
#include "sl_sleeptimer.h"
|
||||
#include "sli_sleeptimer_hal.h"
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) && defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
#include "sli_hfxo_manager.h"
|
||||
#endif
|
||||
#include "em_core.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_prs.h"
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
#include "sl_power_manager.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) || defined(SL_CATALOG_HFXO_MANAGER_PRESENT)
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
#include "em_prs.h"
|
||||
#else
|
||||
#include "sl_peripheral_prs.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SL_SLEEPTIMER_PERIPHERAL == SL_SLEEPTIMER_PERIPHERAL_SYSRTC
|
||||
|
||||
// Minimum difference between current count value and what the comparator of the timer can be set to.
|
||||
|
@ -63,9 +70,8 @@ __STATIC_INLINE uint32_t get_time_diff(uint32_t a,
|
|||
*****************************************************************************/
|
||||
void sleeptimer_hal_init_timer(void)
|
||||
{
|
||||
sl_sysrtc_config_t sysrtc_config = SYSRTC_CONFIG_DEFAULT;
|
||||
sl_sysrtc_group_config_t group_config = SYSRTC_GROUP_CONFIG_DEFAULT;
|
||||
const sl_sysrtc_group_channel_compare_config_t group_compare_channel_config = SYSRTC_GROUP_CHANNEL_COMPARE_CONFIG_EARLY_WAKEUP;
|
||||
sl_hal_sysrtc_config_t sysrtc_config = SYSRTC_CONFIG_DEFAULT;
|
||||
sl_hal_sysrtc_group_config_t group_config = SYSRTC_GROUP_CONFIG_DEFAULT;
|
||||
|
||||
CMU_ClockEnable(cmuClock_SYSRTC, true);
|
||||
|
||||
|
@ -73,33 +79,71 @@ void sleeptimer_hal_init_timer(void)
|
|||
sysrtc_config.enable_debug_run = true;
|
||||
#endif
|
||||
|
||||
sl_sysrtc_init(&sysrtc_config);
|
||||
sl_hal_sysrtc_init(&sysrtc_config);
|
||||
|
||||
group_config.compare_channel0_enable = false;
|
||||
group_config.compare_channel1_enable = false;
|
||||
group_config.p_compare_channel1_config = &group_compare_channel_config;
|
||||
sl_sysrtc_init_group(0u, &group_config);
|
||||
|
||||
sl_sysrtc_disable_group_interrupts(0u, _SYSRTC_GRP0_IEN_MASK);
|
||||
sl_sysrtc_clear_group_interrupts(0u, _SYSRTC_GRP0_IF_MASK);
|
||||
sl_sysrtc_enable();
|
||||
sl_sysrtc_set_counter(0u);
|
||||
sl_hal_sysrtc_init_group(0u, &group_config);
|
||||
|
||||
sl_hal_sysrtc_disable_group_interrupts(0u, _SYSRTC_GRP0_IEN_MASK);
|
||||
sl_hal_sysrtc_clear_group_interrupts(0u, _SYSRTC_GRP0_IF_MASK);
|
||||
sl_hal_sysrtc_enable();
|
||||
sl_hal_sysrtc_set_counter(0u);
|
||||
|
||||
NVIC_ClearPendingIRQ(SYSRTC_APP_IRQn);
|
||||
NVIC_EnableIRQ(SYSRTC_APP_IRQn);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to perform initialization related to Power Manager.
|
||||
******************************************************************************/
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
void sli_sleeptimer_hal_power_manager_integration_init(void)
|
||||
{
|
||||
// Initialize PRS to start HFXO for early wakeup
|
||||
CMU_ClockEnable(cmuClock_PRS, true);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
PRS_ConnectSignal(1UL, prsTypeAsync, prsSignalSYSRTC0_GRP0OUT1);
|
||||
PRS_ConnectConsumer(1UL, prsTypeAsync, prsConsumerHFXO0_OSCREQ);
|
||||
#else
|
||||
sl_hal_prs_async_connect_channel_producer(1UL, SL_HAL_PRS_ASYNC_SYSRTC0_GRP0OUT1);
|
||||
sl_hal_prs_connect_channel_consumer(1UL, SL_HAL_PRS_TYPE_ASYNC, SL_HAL_PRS_CONSUMER_HFXO0_OSCREQ);
|
||||
#endif
|
||||
|
||||
// Set SYSRTC Compare Channel 1
|
||||
SYSRTC0->GRP0_CTRL |= (_SYSRTC_GRP0_CTRL_CMP1CMOA_CMPIF << _SYSRTC_GRP0_CTRL_CMP1CMOA_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to perform initialization related to HFXO Manager.
|
||||
******************************************************************************/
|
||||
#if defined(SL_CATALOG_HFXO_MANAGER_PRESENT)
|
||||
void sli_sleeptimer_hal_hfxo_manager_integration_init(void)
|
||||
{
|
||||
// Set PRS signal from HFXO to SYSRTC capture channel
|
||||
CMU_ClockEnable(cmuClock_PRS, true);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
PRS_ConnectSignal(2UL, prsTypeAsync, prsSignalHFXO0L_STATUS1);
|
||||
PRS_ConnectConsumer(2UL, prsTypeAsync, prsConsumerSYSRTC0_SRC0);
|
||||
#else
|
||||
sl_hal_prs_async_connect_channel_producer(2UL, SL_HAL_PRS_ASYNC_SYXO0L_STATUS1);
|
||||
sl_hal_prs_connect_channel_consumer(2UL, SL_HAL_PRS_TYPE_ASYNC, SL_HAL_PRS_CONSUMER_SYSRTC0_IN0);
|
||||
#endif
|
||||
|
||||
// Set SYSRTC Capture Channel
|
||||
SYSRTC0->GRP0_CTRL |= (_SYSRTC_GRP0_CTRL_CAP0EDGE_RISING << _SYSRTC_GRP0_CTRL_CAP0EDGE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************
|
||||
* Gets SYSRTC counter value.
|
||||
*****************************************************************************/
|
||||
uint32_t sleeptimer_hal_get_counter(void)
|
||||
{
|
||||
return sl_sysrtc_get_counter();
|
||||
return sl_hal_sysrtc_get_counter();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -107,14 +151,14 @@ uint32_t sleeptimer_hal_get_counter(void)
|
|||
*****************************************************************************/
|
||||
uint32_t sleeptimer_hal_get_compare(void)
|
||||
{
|
||||
return sl_sysrtc_get_group_compare_channel_value(0u, 0u);
|
||||
return sl_hal_sysrtc_get_group_compare_channel_value(0u, 0u);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Sets SYSRTC channel zero's compare value.
|
||||
*
|
||||
* @note Compare match value is set to the requested value - 1. This is done
|
||||
* to compensate for the fact that the BURTC compare match interrupt always
|
||||
* to compensate for the fact that the SYSRTC compare match interrupt always
|
||||
* triggers at the end of the requested ticks and that the IRQ handler is
|
||||
* executed when current tick count == compare_value + 1.
|
||||
*****************************************************************************/
|
||||
|
@ -129,7 +173,7 @@ void sleeptimer_hal_set_compare(uint32_t value)
|
|||
counter = sleeptimer_hal_get_counter();
|
||||
compare = sleeptimer_hal_get_compare();
|
||||
|
||||
if (((sl_sysrtc_get_group_interrupts(0u) & SYSRTC_GRP0_IEN_CMP0) != 0)
|
||||
if (((sl_hal_sysrtc_get_group_interrupts(0u) & SYSRTC_GRP0_IEN_CMP0) != 0)
|
||||
|| get_time_diff(compare, counter) > SLEEPTIMER_COMPARE_MIN_DIFF
|
||||
|| compare == counter) {
|
||||
// Add margin if necessary
|
||||
|
@ -138,7 +182,7 @@ void sleeptimer_hal_set_compare(uint32_t value)
|
|||
}
|
||||
compare_value %= SLEEPTIMER_TMR_WIDTH;
|
||||
|
||||
sl_sysrtc_set_group_compare_channel_value(0u, 0u, compare_value - 1);
|
||||
sl_hal_sysrtc_set_group_compare_channel_value(0u, 0u, compare_value - 1);
|
||||
sleeptimer_hal_enable_int(SLEEPTIMER_EVENT_COMP);
|
||||
}
|
||||
CORE_EXIT_CRITICAL();
|
||||
|
@ -153,7 +197,7 @@ void sleeptimer_hal_set_compare(uint32_t value)
|
|||
* Sets SYSRTC channel one's compare value.
|
||||
*
|
||||
* @note Compare match value is set to the requested value - 1. This is done
|
||||
* to compensate for the fact that the BURTC compare match interrupt always
|
||||
* to compensate for the fact that the SYSRTC compare match interrupt always
|
||||
* triggers at the end of the requested ticks and that the IRQ handler is
|
||||
* executed when current tick count == compare_value + 1.
|
||||
******************************************************************************/
|
||||
|
@ -174,18 +218,15 @@ void sleeptimer_hal_set_compare_prs_hfxo_startup(int32_t value)
|
|||
compare_value = counter + SLEEPTIMER_COMPARE_MIN_DIFF;
|
||||
}
|
||||
|
||||
#if !defined(SL_CATALOG_POWER_MANAGER_NO_DEEPSLEEP_PRESENT) && defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
sli_hfxo_prs_manager_begin_startup_measurement(compare_value);
|
||||
#endif
|
||||
|
||||
compare_value %= SLEEPTIMER_TMR_WIDTH;
|
||||
|
||||
sl_sysrtc_set_group_compare_channel_value(0u, 1u, compare_value - 1);
|
||||
sl_hal_sysrtc_set_group_compare_channel_value(0u, 1u, compare_value - 1);
|
||||
|
||||
CORE_EXIT_CRITICAL();
|
||||
|
||||
if (cc1_disabled) {
|
||||
SYSRTC0->GRP0_CTRL |= SYSRTC_GRP0_CTRL_CMP1EN;
|
||||
SYSRTC0->GRP0_CTRL |= SYSRTC_GRP0_CTRL_CAP0EN;
|
||||
cc1_disabled = false;
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +246,7 @@ void sleeptimer_hal_enable_int(uint8_t local_flag)
|
|||
sysrtc_ien |= SYSRTC_GRP0_IEN_CMP0;
|
||||
}
|
||||
|
||||
sl_sysrtc_enable_group_interrupts(0u, sysrtc_ien);
|
||||
sl_hal_sysrtc_enable_group_interrupts(0u, sysrtc_ien);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -226,7 +267,7 @@ void sleeptimer_hal_disable_int(uint8_t local_flag)
|
|||
SYSRTC0->GRP0_CTRL &= ~_SYSRTC_GRP0_CTRL_CMP0EN_MASK;
|
||||
}
|
||||
|
||||
sl_sysrtc_disable_group_interrupts(0u, sysrtc_int_dis);
|
||||
sl_hal_sysrtc_disable_group_interrupts(0u, sysrtc_int_dis);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -247,7 +288,7 @@ void sleeptimer_hal_set_int(uint8_t local_flag)
|
|||
bool sli_sleeptimer_hal_is_int_status_set(uint8_t local_flag)
|
||||
{
|
||||
bool int_is_set = false;
|
||||
uint32_t irq_flag = sl_sysrtc_get_group_interrupts(0u);
|
||||
uint32_t irq_flag = sl_hal_sysrtc_get_group_interrupts(0u);
|
||||
|
||||
switch (local_flag) {
|
||||
case SLEEPTIMER_EVENT_COMP:
|
||||
|
@ -275,7 +316,7 @@ void SYSRTC_APP_IRQHandler(void)
|
|||
uint32_t irq_flag;
|
||||
|
||||
CORE_ENTER_ATOMIC();
|
||||
irq_flag = sl_sysrtc_get_group_interrupts(0u);
|
||||
irq_flag = sl_hal_sysrtc_get_group_interrupts(0u);
|
||||
|
||||
if (irq_flag & SYSRTC_GRP0_IF_OVF) {
|
||||
local_flag |= SLEEPTIMER_EVENT_OF;
|
||||
|
@ -284,7 +325,7 @@ void SYSRTC_APP_IRQHandler(void)
|
|||
if (irq_flag & SYSRTC_GRP0_IF_CMP0) {
|
||||
local_flag |= SLEEPTIMER_EVENT_COMP;
|
||||
}
|
||||
sl_sysrtc_clear_group_interrupts(0u, irq_flag & (SYSRTC_GRP0_IF_OVF | SYSRTC_GRP0_IF_CMP0));
|
||||
sl_hal_sysrtc_clear_group_interrupts(0u, irq_flag & (SYSRTC_GRP0_IF_OVF | SYSRTC_GRP0_IF_CMP0));
|
||||
|
||||
process_timer_irq(local_flag);
|
||||
|
||||
|
@ -326,6 +367,40 @@ uint16_t sleeptimer_hal_get_clock_accuracy(void)
|
|||
return CMU_LF_ClockPrecisionGet(cmuClock_SYSRTC);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get the capture channel value.
|
||||
******************************************************************************/
|
||||
uint32_t sleeptimer_hal_get_capture(void)
|
||||
{
|
||||
if ((sl_hal_sysrtc_get_group_interrupts(0) & _SYSRTC_GRP0_IF_CAP0_MASK) != 0) {
|
||||
sl_hal_sysrtc_clear_group_interrupts(0, _SYSRTC_GRP0_IF_CAP0_MASK);
|
||||
return sl_hal_sysrtc_get_group_capture_channel_value(0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to reset PRS signal triggered by the associated
|
||||
* peripheral.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_reset_prs_signal(void)
|
||||
{
|
||||
sl_hal_sysrtc_clear_group_interrupts(0, SYSRTC_GRP0_IF_CMP1);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to disable PRS compare and capture channel.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_disable_prs_compare_and_capture_channel(void)
|
||||
{
|
||||
if (!cc1_disabled) {
|
||||
SYSRTC0->GRP0_CTRL &= ~SYSRTC_GRP0_CTRL_CMP1EN;
|
||||
SYSRTC0->GRP0_CTRL &= ~SYSRTC_GRP0_CTRL_CAP0EN;
|
||||
cc1_disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Set lowest energy mode based on a project's configurations and clock source
|
||||
*
|
||||
|
|
|
@ -36,23 +36,6 @@
|
|||
#include <stdbool.h>
|
||||
#include "em_device.h"
|
||||
#include "sli_sleeptimer.h"
|
||||
#include "sl_sleeptimer_config.h"
|
||||
|
||||
#if SL_SLEEPTIMER_PERIPHERAL == SL_SLEEPTIMER_PERIPHERAL_DEFAULT
|
||||
#if defined(RTCC_PRESENT) && RTCC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_RTCC
|
||||
#elif defined(RTC_PRESENT) && RTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_RTC
|
||||
#elif defined(SYSRTC_PRESENT) && SYSRTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_SYSRTC
|
||||
#elif defined(BURTC_PRESENT) && BURTC_COUNT >= 1
|
||||
#undef SL_SLEEPTIMER_PERIPHERAL
|
||||
#define SL_SLEEPTIMER_PERIPHERAL SL_SLEEPTIMER_PERIPHERAL_BURTC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -84,6 +67,14 @@ uint32_t sleeptimer_hal_get_compare(void);
|
|||
******************************************************************************/
|
||||
void sleeptimer_hal_set_compare(uint32_t value);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to set a comparator value to trigger a
|
||||
* peripheral request signal to initialize.
|
||||
*
|
||||
* @param value Number of ticks to set.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_set_compare_prs_hfxo_startup(int32_t value);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get the timer frequency.
|
||||
******************************************************************************/
|
||||
|
@ -110,6 +101,37 @@ void sleeptimer_hal_disable_int(uint8_t local_flag);
|
|||
******************************************************************************/
|
||||
void sleeptimer_hal_set_int(uint8_t local_flag);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get the sleeptimer's clock accuracy.
|
||||
*
|
||||
* @return Clock accuracy in PPM.
|
||||
******************************************************************************/
|
||||
uint16_t sleeptimer_hal_get_clock_accuracy(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to get the capture channel value.
|
||||
*
|
||||
* @note Not supported by all peripherals Sleeptimer can use.
|
||||
*
|
||||
* @return Capture value.
|
||||
******************************************************************************/
|
||||
uint32_t sleeptimer_hal_get_capture(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to reset PRS signal triggered by the associated
|
||||
* peripheral.
|
||||
*
|
||||
* @note Not supported by all peripherals Sleeptimer can use.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_reset_prs_signal(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer to disable PRS compare and capture channel.
|
||||
*
|
||||
* @note Not supported by all peripherals Sleeptimer can use.
|
||||
******************************************************************************/
|
||||
void sleeptimer_hal_disable_prs_compare_and_capture_channel(void);
|
||||
|
||||
/*******************************************************************************
|
||||
* Process the timer interrupt.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue