mirror of
https://github.com/thelsing/knx.git
synced 2025-11-07 01:20:20 +01:00
git-subtree-dir: examples/knx-cc1310/coresdk_cc13xx_cc26xx git-subtree-split: 0d78d3280357416a5c0388148cda13717c9ffaa5
195 lines
6.8 KiB
C
195 lines
6.8 KiB
C
/*
|
|
* Copyright (c) 2017-2018, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/*
|
|
* ======== PowerCC26X2_nortos.c ========
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <ti/drivers/Power.h>
|
|
#include <ti/drivers/power/PowerCC26X2.h>
|
|
|
|
#include <ti/drivers/dpl/ClockP.h>
|
|
#include <ti/drivers/dpl/HwiP.h>
|
|
#include <ti/drivers/dpl/SwiP.h>
|
|
|
|
#include <ti/devices/DeviceFamily.h>
|
|
#include DeviceFamily_constructPath(inc/hw_types.h)
|
|
#include DeviceFamily_constructPath(driverlib/prcm.h)
|
|
#include DeviceFamily_constructPath(driverlib/osc.h)
|
|
#include DeviceFamily_constructPath(driverlib/cpu.h)
|
|
#include DeviceFamily_constructPath(driverlib/sys_ctrl.h)
|
|
#include DeviceFamily_constructPath(driverlib/vims.h)
|
|
|
|
extern PowerCC26X2_ModuleState PowerCC26X2_module;
|
|
|
|
static uintptr_t PowerCC26X2_swiKey;
|
|
|
|
/*
|
|
* ======== PowerCC26XX_standbyPolicy ========
|
|
*/
|
|
void PowerCC26XX_standbyPolicy()
|
|
{
|
|
bool justIdle = true;
|
|
uint32_t constraints;
|
|
uint32_t ticks, time;
|
|
uintptr_t key;
|
|
|
|
/* disable interrupts */
|
|
key = HwiP_disable();
|
|
|
|
/*
|
|
* Check if the Power policy has been disabled since we last checked.
|
|
* Since we're in this policy function already, the policy must have
|
|
* been enabled (with a valid policyFxn) when we were called, but
|
|
* could have been disbled to short-circuit this function.
|
|
* SemaphoreP_post() does this purposely (see comments in there).
|
|
*/
|
|
if (!PowerCC26X2_module.enablePolicy) {
|
|
HwiP_restore(key);
|
|
|
|
return;
|
|
}
|
|
|
|
/* check operating conditions, optimally choose DCDC versus GLDO */
|
|
SysCtrl_DCDC_VoltageConditionalControl();
|
|
|
|
/* query the declared constraints */
|
|
constraints = Power_getConstraintMask();
|
|
|
|
/* do quick check to see if only WFI allowed; if yes, do it now */
|
|
if ((constraints &
|
|
((1 << PowerCC26XX_DISALLOW_STANDBY) |
|
|
(1 << PowerCC26XX_DISALLOW_IDLE))) ==
|
|
((1 << PowerCC26XX_DISALLOW_STANDBY) |
|
|
(1 << PowerCC26XX_DISALLOW_IDLE))) {
|
|
PRCMSleep();
|
|
}
|
|
/*
|
|
* check if any sleep modes are allowed for automatic activation
|
|
*/
|
|
else {
|
|
/* check if we are allowed to go to standby */
|
|
if ((constraints & (1 << PowerCC26XX_DISALLOW_STANDBY)) == 0) {
|
|
/*
|
|
* Check how many ticks until the next scheduled wakeup. A value of
|
|
* zero indicates a wakeup will occur as the current Clock tick
|
|
* period expires; a very large value indicates a very large number
|
|
* of Clock tick periods will occur before the next scheduled
|
|
* wakeup.
|
|
*/
|
|
ticks = ClockP_getTicksUntilInterrupt();
|
|
|
|
/* convert ticks to usec */
|
|
time = ticks * ClockP_tickPeriod;
|
|
|
|
/* check if can go to STANDBY */
|
|
if (time > Power_getTransitionLatency(PowerCC26XX_STANDBY,
|
|
Power_TOTAL)) {
|
|
|
|
/* schedule the wakeup event */
|
|
ticks -= PowerCC26X2_WAKEDELAYSTANDBY / ClockP_tickPeriod;
|
|
ClockP_setTimeout(ClockP_handle((ClockP_Struct *)
|
|
&PowerCC26X2_module.clockObj), ticks);
|
|
ClockP_start(ClockP_handle((ClockP_Struct *)
|
|
&PowerCC26X2_module.clockObj));
|
|
|
|
/* go to standby mode */
|
|
Power_sleep(PowerCC26XX_STANDBY);
|
|
ClockP_stop(ClockP_handle((ClockP_Struct *)
|
|
&PowerCC26X2_module.clockObj));
|
|
justIdle = false;
|
|
}
|
|
}
|
|
|
|
/* idle if allowed */
|
|
if (justIdle) {
|
|
|
|
/*
|
|
* Power off the CPU domain; VIMS will power down if SYSBUS is
|
|
* powered down, and SYSBUS will power down if there are no
|
|
* dependencies
|
|
* NOTE: if radio driver is active it must force SYSBUS enable to
|
|
* allow access to the bus and SRAM
|
|
*/
|
|
if ((constraints & (1 << PowerCC26XX_DISALLOW_IDLE)) == 0) {
|
|
uint32_t modeVIMS;
|
|
/* 1. Get the current VIMS mode */
|
|
do {
|
|
modeVIMS = VIMSModeGet(VIMS_BASE);
|
|
} while (modeVIMS == VIMS_MODE_CHANGING);
|
|
|
|
/* 2. Configure flash to remain on in IDLE or not and keep
|
|
* VIMS powered on if it is configured as GPRAM
|
|
* 3. Always keep cache retention ON in IDLE
|
|
* 4. Turn off the CPU power domain
|
|
* 5. Ensure any possible outstanding AON writes complete
|
|
* 6. Enter IDLE
|
|
*/
|
|
if ((constraints & (1 << PowerCC26XX_NEED_FLASH_IN_IDLE)) ||
|
|
(modeVIMS == VIMS_MODE_DISABLED)) {
|
|
SysCtrlIdle(VIMS_ON_BUS_ON_MODE);
|
|
}
|
|
else {
|
|
SysCtrlIdle(VIMS_ON_CPU_ON_MODE);
|
|
}
|
|
|
|
/* 7. Make sure MCU and AON are in sync after wakeup */
|
|
SysCtrlAonUpdate();
|
|
}
|
|
else {
|
|
PRCMSleep();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* re-enable interrupts */
|
|
HwiP_restore(key);
|
|
}
|
|
|
|
/*
|
|
* ======== PowerCC26XX_schedulerDisable ========
|
|
*/
|
|
void PowerCC26XX_schedulerDisable()
|
|
{
|
|
PowerCC26X2_swiKey = SwiP_disable();
|
|
}
|
|
|
|
/*
|
|
* ======== PowerCC26XX_schedulerRestore ========
|
|
*/
|
|
void PowerCC26XX_schedulerRestore()
|
|
{
|
|
SwiP_restore(PowerCC26X2_swiKey);
|
|
}
|