summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2019-10-28 11:53:19 +0100
committerDaniel Friesel <daniel.friesel@uos.de>2019-10-28 11:53:19 +0100
commit6693c0149a787063a4726815344e4f9276b78845 (patch)
tree56ea2f2c951a847702ec04f60f261787d9a42957 /src/arch
parent46c68f5d29c2cc8871486ee2a2e46d204c6f8047 (diff)
MSP430FR5994: Add .arch.sleep_ms (energy-efficient delay_ms variant)
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/msp430fr5994lp/arch.cc42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/arch/msp430fr5994lp/arch.cc b/src/arch/msp430fr5994lp/arch.cc
index 3f0eb3c..c6739dd 100644
--- a/src/arch/msp430fr5994lp/arch.cc
+++ b/src/arch/msp430fr5994lp/arch.cc
@@ -125,6 +125,39 @@ void Arch::delay_ms(unsigned int const ms)
}
}
+volatile bool sleep_done = false;
+
+// max delay: 2621 ms
+void Arch::sleep_ms(unsigned int const ms)
+{
+ sleep_done = false;
+#if F_CPU == 16000000UL
+ TA3CTL = TASSEL__SMCLK | ID__8; // /8
+ TA3EX0 = 7; // /8 -> /64 (250 kHz)
+#elif F_CPU == 8000000UL
+ TA3CTL = TASSEL__SMCLK | ID__8; // /8
+ TA3EX0 = 3; // /4 -> /32 (250 kHz)
+#elif F_CPU == 4000000UL
+ TA3CTL = TASSEL__SMCLK | ID__4; // /4
+ TA3EX0 = 3; // /4 -> /16 (250 kHz)
+#elif F_CPU == 1000000UL
+ TA3CTL = TASSEL__SMCLK | ID__1; // /1
+ TA3EX0 = 3; // /4 -> /4 (250 kHz)
+#else
+#error Unsupported F_CPU
+#endif /* F_CPU */
+ TA3CCR0 = ms * 250;
+ TA3CCTL0 = CCIE;
+ TA3CTL |= MC__UP | TACLR;
+ while (!sleep_done) {
+ asm volatile("nop");
+ __bis_SR_register(GIE | LPM2_bits);
+ asm volatile("nop");
+ __dint();
+ }
+ TA3CTL = TASSEL__SMCLK;
+}
+
void Arch::idle_loop(void)
{
while (1) {
@@ -162,6 +195,7 @@ Arch arch;
#include "driver/uptime.h"
#ifndef __acweaving
+// overflow interrupts end up in A1 (joint interrupt for CCR1 ... CCR6 and overflow)
__attribute__((interrupt(TIMER1_A1_VECTOR))) __attribute__((wakeup)) void handle_timer1_overflow()
{
if (TA1IV == 0x0e) {
@@ -176,3 +210,11 @@ __attribute__((interrupt(TIMER1_A1_VECTOR))) __attribute__((wakeup)) void handle
#endif
#endif /* defined(WITH_LOOP) || defined(TIMER_S) */
+
+#ifndef __acweaving
+// CCR0 interrupts are exclusive to A0
+__attribute__((interrupt(TIMER3_A0_VECTOR))) __attribute__((wakeup)) void handle_timer3_ccr0()
+{
+ sleep_done = true;
+}
+#endif /* __acweaving */