/*
* -------------------------------------------
- * MSP432 DriverLib - v01_04_00_18
+ * MSP432 DriverLib - v3_10_00_09
* -------------------------------------------
*
* --COPYRIGHT--,BSD,BSD
- * Copyright (c) 2015, Texas Instruments Incorporated
+ * Copyright (c) 2014, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <pcm.h>
#include <debug.h>
#include <interrupt.h>
+#include <wdt_a.h>
+#include <rtc_c.h>
#include <cpu.h>
-bool PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel)
-{
- return PCM_setCoreVoltageLevelWithTimeout(voltageLevel, 0);
-}
-
-bool PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel,
- uint32_t timeOut)
+static bool __PCM_setCoreVoltageLevelAdvanced(uint_fast8_t voltageLevel,
+ uint32_t timeOut, bool blocking)
{
uint8_t powerMode, bCurrentVoltageLevel;
uint32_t regValue;
while (bCurrentVoltageLevel != voltageLevel)
{
- regValue = PCM->rCTL0.r;
+ regValue = PCM->CTL0;
switch (PCM_getPowerState())
{
case PCM_AM_LF_VCORE1:
case PCM_AM_DCDC_VCORE1:
case PCM_AM_LDO_VCORE0:
- PCM->rCTL0.r = (PCM_KEY | (PCM_AM_LDO_VCORE1)
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE1)
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LF_VCORE0:
case PCM_AM_DCDC_VCORE0:
case PCM_AM_LDO_VCORE1:
- PCM->rCTL0.r = (PCM_KEY | (PCM_AM_LDO_VCORE0)
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE0)
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
default:
ASSERT(false);
}
- while (BITBAND_PERI(PCM->rCTL1.r, PMR_BUSY_OFS))
+ if(blocking)
{
- if (boolTimeout && !(--timeOut))
- return false;
+ while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
+ {
+ if (boolTimeout && !(--timeOut))
+ return false;
+ }
+ }
+ else
+ {
+ return true;
}
bCurrentVoltageLevel = PCM_getCoreVoltageLevel();
}
-bool PCM_setPowerMode(uint_fast8_t powerMode)
+
+bool PCM_setCoreVoltageLevel(uint_fast8_t voltageLevel)
+{
+ return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, true);
+}
+
+bool PCM_setCoreVoltageLevelWithTimeout(uint_fast8_t voltageLevel,
+ uint32_t timeOut)
{
- return PCM_setPowerModeWithTimeout(powerMode, 0);
+ return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, timeOut, true);
+}
+
+bool PCM_setCoreVoltageLevelNonBlocking(uint_fast8_t voltageLevel)
+{
+ return __PCM_setCoreVoltageLevelAdvanced(voltageLevel, 0, false);
}
uint8_t PCM_getPowerMode(void)
}
}
-bool PCM_setPowerModeWithTimeout(uint_fast8_t powerMode, uint32_t timeOut)
+static bool __PCM_setPowerModeAdvanced(uint_fast8_t powerMode, uint32_t timeOut,
+bool blocking)
{
uint8_t bCurrentPowerMode, bCurrentPowerState;
uint32_t regValue;
/* Go through the while loop while we haven't achieved the power mode */
while (bCurrentPowerMode != powerMode)
{
- regValue = PCM->rCTL0.r;
+ regValue = PCM->CTL0;
switch (bCurrentPowerState)
{
case PCM_AM_DCDC_VCORE0:
case PCM_AM_LF_VCORE0:
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_LDO_VCORE0
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE0
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LF_VCORE1:
case PCM_AM_DCDC_VCORE1:
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_LDO_VCORE1
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE1
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
break;
case PCM_AM_LDO_VCORE1:
{
if (powerMode == PCM_DCDC_MODE)
{
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_DCDC_VCORE1
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE1
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
} else if (powerMode == PCM_LF_MODE)
{
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_LF_VCORE1
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE1
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
} else
ASSERT(false);
{
if (powerMode == PCM_DCDC_MODE)
{
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_DCDC_VCORE0
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE0
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
} else if (powerMode == PCM_LF_MODE)
{
- PCM->rCTL0.r = (PCM_KEY | PCM_AM_LF_VCORE0
- | (regValue & ~(PCMKEY_M | AMR_M)));
+ PCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE0
+ | (regValue & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));
} else
ASSERT(false);
ASSERT(false);
}
- while (BITBAND_PERI(PCM->rCTL1.r, PMR_BUSY_OFS))
+ if (blocking)
{
- if (boolTimeout && !(--timeOut))
- return false;
+ while (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
+ {
+ if (boolTimeout && !(--timeOut))
+ return false;
- }
+ }
+ } else
+ return true;
bCurrentPowerMode = PCM_getPowerMode();
bCurrentPowerState = PCM_getPowerState();
}
-bool PCM_setPowerState(uint_fast8_t powerState)
+bool PCM_setPowerMode(uint_fast8_t powerMode)
{
- return PCM_setPowerStateWithTimeout(powerState, 0);
+ return __PCM_setPowerModeAdvanced(powerMode, 0, true);
}
-bool PCM_setPowerStateWithTimeout(uint_fast8_t powerState, uint32_t timeout)
+bool PCM_setPowerModeNonBlocking(uint_fast8_t powerMode)
+{
+ return __PCM_setPowerModeAdvanced(powerMode, 0, false);
+}
+
+bool PCM_setPowerModeWithTimeout(uint_fast8_t powerMode, uint32_t timeOut)
+{
+ return __PCM_setPowerModeAdvanced(powerMode, timeOut, true);
+}
+
+static bool __PCM_setPowerStateAdvanced(uint_fast8_t powerState,
+ uint32_t timeout,
+ bool blocking)
{
uint8_t bCurrentPowerState;
bCurrentPowerState = PCM_getPowerState();
|| powerState == PCM_LPM0_LDO_VCORE0 || powerState == PCM_LPM0_LDO_VCORE1
|| powerState == PCM_LPM0_DCDC_VCORE0 || powerState == PCM_LPM0_DCDC_VCORE1
|| powerState == PCM_LPM3 || powerState == PCM_LPM35_VCORE0
- || powerState == PCM_LPM45);
+ || powerState == PCM_LPM45 || powerState == PCM_LPM4);
if (bCurrentPowerState == powerState)
return true;
switch (powerState)
{
case PCM_AM_LDO_VCORE0:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- && PCM_setPowerModeWithTimeout(PCM_LDO_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking));
case PCM_AM_LDO_VCORE1:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- && PCM_setPowerModeWithTimeout(PCM_LDO_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking));
case PCM_AM_DCDC_VCORE0:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- && PCM_setPowerModeWithTimeout(PCM_DCDC_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking));
case PCM_AM_DCDC_VCORE1:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- && PCM_setPowerModeWithTimeout(PCM_DCDC_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout, blocking));
case PCM_AM_LF_VCORE0:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- && PCM_setPowerModeWithTimeout(PCM_LF_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking));
case PCM_AM_LF_VCORE1:
- return (PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- && PCM_setPowerModeWithTimeout(PCM_LF_MODE, timeout));
+ return (__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ && __PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking));
case PCM_LPM0_LDO_VCORE0:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_LDO_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM0_LDO_VCORE1:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_LDO_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_LDO_MODE, timeout, blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM0_DCDC_VCORE0:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_DCDC_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout,
+ blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM0_DCDC_VCORE1:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_DCDC_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_DCDC_MODE, timeout,
+ blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM0_LF_VCORE0:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE0, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_LF_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE0, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM0_LF_VCORE1:
- if (!PCM_setCoreVoltageLevelWithTimeout(PCM_VCORE1, timeout)
- || !PCM_setPowerModeWithTimeout(PCM_LF_MODE, timeout))
+ if (!__PCM_setCoreVoltageLevelAdvanced(PCM_VCORE1, timeout, blocking)
+ || !__PCM_setPowerModeAdvanced(PCM_LF_MODE, timeout, blocking))
break;
return PCM_gotoLPM0();
case PCM_LPM3:
return PCM_gotoLPM3();
+ case PCM_LPM4:
+ return PCM_gotoLPM4();
case PCM_LPM45:
return PCM_shutdownDevice(PCM_LPM45);
case PCM_LPM35_VCORE0:
}
+bool PCM_setPowerState(uint_fast8_t powerState)
+{
+ return __PCM_setPowerStateAdvanced(powerState, 0, true);
+}
+
+bool PCM_setPowerStateWithTimeout(uint_fast8_t powerState, uint32_t timeout)
+{
+ return __PCM_setPowerStateAdvanced(powerState, timeout, true);
+}
+
+bool PCM_setPowerStateNonBlocking(uint_fast8_t powerState)
+{
+ return __PCM_setPowerStateAdvanced(powerState, 0, false);
+}
+
bool PCM_shutdownDevice(uint32_t shutdownMode)
{
- uint32_t shutdownModeBits = (shutdownMode == PCM_LPM45) ? LPMR_12 : LPMR_10;
+ uint32_t shutdownModeBits = (shutdownMode == PCM_LPM45) ?
+ PCM_CTL0_LPMR_12 : PCM_CTL0_LPMR_10;
ASSERT(
shutdownMode == PCM_SHUTDOWN_PARTIAL
|| shutdownMode == PCM_SHUTDOWN_COMPLETE);
/* If a power transition is occuring, return false */
- if (BITBAND_PERI(PCM->rCTL1.r, PMR_BUSY_OFS))
+ if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
/* Initiating the shutdown */
- HWREG32(SCS_BASE + OFS_SCB_SCR) |= (SCB_SCR_SLEEPDEEP);
- PCM->rCTL0.r = (PCM_KEY | shutdownModeBits
- | (PCM->rCTL0.r & ~(PCMKEY_M | LPMR_M)));
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+
+ PCM->CTL0 = (PCM_KEY | shutdownModeBits
+ | (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)));
CPU_wfi();
return true;
}
-bool PCM_gotoLPM0(void)
+bool PCM_gotoLPM4(void)
+{
+ /* Disabling RTC_C and WDT_A */
+ WDT_A_holdTimer();
+ RTC_C_holdClock();
+
+ /* LPM4 is just LPM3 with WDT_A/RTC_C disabled... */
+ return PCM_gotoLPM3();
+}
+
+bool PCM_gotoLPM4InterruptSafe(void)
{
+ bool slHappenedCorrect;
+ /* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
+ master interrupts are disabled and a WFI happens the WFI will
+ immediately exit. */
+ Interrupt_disableMaster();
+
+ slHappenedCorrect = PCM_gotoLPM4();
+
+ /* Enabling and Disabling Interrupts very quickly so that the
+ processor catches any pending interrupts */
+ Interrupt_enableMaster();
+ Interrupt_disableMaster();
+
+ return slHappenedCorrect;
+}
+
+bool PCM_gotoLPM0(void)
+{
/* If we are in the middle of a state transition, return false */
- if (BITBAND_PERI(PCM->rCTL1.r, PMR_BUSY_OFS))
+ if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
- HWREG32(SCS_BASE + OFS_SCB_SCR) &= ~(SCB_SCR_SLEEPDEEP);
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
CPU_wfi();
bool PCM_gotoLPM0InterruptSafe(void)
{
-
bool slHappenedCorrect;
/* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
uint_fast8_t currentPowerMode;
/* If we are in the middle of a state transition, return false */
- if (BITBAND_PERI(PCM->rCTL1.r, PMR_BUSY_OFS))
+ if (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))
return false;
/* If we are in the middle of a shutdown, return false */
- if ((PCM->rCTL0.r & LPMR_M) == LPMR_10 || (PCM->rCTL0.r & LPMR_M) == LPMR_12)
+ if ((PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_10
+ || (PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_12)
return false;
currentPowerMode = PCM_getPowerMode();
PCM_setPowerMode(PCM_LDO_MODE);
/* Clearing the SDR */
- PCM->rCTL0.r = (PCM->rCTL0.r & ~(PCMKEY_M | LPMR_M)) | PCM_KEY;
+ PCM->CTL0 = (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)) | PCM_KEY;
/* Setting the sleep deep bit */
- HWREG32(SCS_BASE + OFS_SCB_SCR) |= (SCB_SCR_SLEEPDEEP);
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
CPU_wfi();
- HWREG32(SCS_BASE + OFS_SCB_SCR) &= ~(SCB_SCR_SLEEPDEEP);
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
return PCM_setPowerState(bCurrentPowerState);
}
bool PCM_gotoLPM3InterruptSafe(void)
{
- bool dslHappenedCorrect;
+ bool lpmHappenedCorrect;
/* Disabling master interrupts. In Cortex M, if an interrupt is enabled but
master interrupts are disabled and a WFI happens the WFI will
immediately exit. */
Interrupt_disableMaster();
- dslHappenedCorrect = PCM_gotoLPM3();
+ lpmHappenedCorrect = PCM_gotoLPM3();
/* Enabling and Disabling Interrupts very quickly so that the
processor catches any pending interrupts */
Interrupt_enableMaster();
Interrupt_disableMaster();
- return dslHappenedCorrect;
+ return lpmHappenedCorrect;
}
uint8_t PCM_getPowerState(void)
{
- return PCM->rCTL0.b.bCPM;
+ return (PCM->CTL0 | PCM_CTL0_CPM_MASK);
}
void PCM_enableRudeMode(void)
{
- PCM->rCTL1.r = (PCM->rCTL1.r & ~(PCMKEY_M)) | PCM_KEY | FORCE_LPM_ENTRY;
+ PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK)) | PCM_KEY
+ | PCM_CTL1_FORCE_LPM_ENTRY;
}
void PCM_disableRudeMode(void)
{
- PCM->rCTL1.r = (PCM->rCTL1.r & ~(PCMKEY_M | FORCE_LPM_ENTRY)) | PCM_KEY;
+ PCM->CTL1 = (PCM->CTL1 & ~(PCM_CTL0_KEY_MASK | PCM_CTL1_FORCE_LPM_ENTRY))
+ | PCM_KEY;
}
void PCM_enableInterrupt(uint32_t flags)
{
- PCM->rIE.r |= flags;
+ PCM->IE |= flags;
}
void PCM_disableInterrupt(uint32_t flags)
{
- PCM->rIE.r &= ~flags;
+ PCM->IE &= ~flags;
}
uint32_t PCM_getInterruptStatus(void)
{
- return PCM->rIFG.r;
+ return PCM->IFG;
}
uint32_t PCM_getEnabledInterruptStatus(void)
{
- return PCM_getInterruptStatus() & PCM->rIE.r;
+ return PCM_getInterruptStatus() & PCM->IE;
}
void PCM_clearInterruptFlag(uint32_t flags)
{
- PCM->rCLRIFG.r |= flags;
+ PCM->CLRIFG |= flags;
}
void PCM_registerInterrupt(void (*intHandler)(void))