summaryrefslogtreecommitdiff
path: root/fw/fe310/eos/soc/pwr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fw/fe310/eos/soc/pwr.c')
-rw-r--r--fw/fe310/eos/soc/pwr.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/fw/fe310/eos/soc/pwr.c b/fw/fe310/eos/soc/pwr.c
new file mode 100644
index 0000000..a2adfd4
--- /dev/null
+++ b/fw/fe310/eos/soc/pwr.c
@@ -0,0 +1,70 @@
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "encoding.h"
+#include "platform.h"
+
+#include "eos.h"
+#include "timer.h"
+#include "dev/net.h"
+
+#include "pwr.h"
+
+#define PWR_RTC_SCALE 15
+#define PWR_RTC_SFREQ (EOS_TIMER_RTC_FREQ >> PWR_RTC_SCALE)
+
+int eos_pwr_init(uint8_t wakeup_cause) {
+ AON_REG(AON_PMUKEY) = 0x51F15E;
+ AON_REG(AON_PMUIE) = 0x5;
+
+ AON_REG(AON_RTCCMP) = 0xFFFFFFFF;
+ AON_REG(AON_RTCCFG) = PWR_RTC_SCALE;
+ AON_REG(AON_RTCHI) = 0;
+ AON_REG(AON_RTCLO) = 0;
+
+ return EOS_OK;
+}
+
+uint8_t eos_pwr_wakeup_cause(void) {
+ return AON_REG(AON_PMUCAUSE) & 0xff;
+}
+
+uint8_t eos_pwr_reset_cause(void) {
+ return (AON_REG(AON_PMUCAUSE) >> 8) & 0xff;
+}
+
+int eos_pwr_sleep(void) {
+ int rv;
+
+ rv = eos_net_sleep(1000);
+ if (rv) return rv;
+
+ AON_REG(AON_PMUKEY) = 0x51F15E;
+ AON_REG(AON_PMUSLEEP) = 1;
+
+ return EOS_OK;
+}
+
+void eos_pwr_wake_at(uint32_t msec) {
+ uint32_t pmuie;
+
+ AON_REG(AON_RTCCFG) |= AON_RTCCFG_ENALWAYS;
+ AON_REG(AON_RTCCMP) = msec * PWR_RTC_SFREQ / 1000;
+
+ pmuie = AON_REG(AON_PMUIE) | 0x2;
+ AON_REG(AON_PMUKEY) = 0x51F15E;
+ AON_REG(AON_PMUIE) = pmuie;
+}
+
+void eos_pwr_wake_disable(void) {
+ uint32_t pmuie;
+
+ AON_REG(AON_RTCCMP) = 0xFFFFFFFF;
+ AON_REG(AON_RTCCFG) &= ~AON_RTCCFG_ENALWAYS;
+ AON_REG(AON_RTCHI) = 0;
+ AON_REG(AON_RTCLO) = 0;
+
+ pmuie = AON_REG(AON_PMUIE) & ~0x2;
+ AON_REG(AON_PMUKEY) = 0x51F15E;
+ AON_REG(AON_PMUIE) = pmuie;
+}