From ebee1f67d77cb217087f807033245ef3ed2c5d55 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 11 May 2009 12:01:15 -0400 Subject: [PATCH 1/7] add radio_on and radio_off. --- include/maca.h | 2 ++ src/maca.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/maca.h b/include/maca.h index e9079ea9d..3091685ce 100644 --- a/include/maca.h +++ b/include/maca.h @@ -412,6 +412,8 @@ void init_phy(void); void vreg_init(void); void ResumeMACASync(void); void radio_init(void); +void radio_off(void); +void radio_on(void); uint32_t init_from_flash(uint32_t addr); void set_power(uint8_t power); void set_channel(uint8_t chan); diff --git a/src/maca.c b/src/maca.c index 6f0608aba..9416e4dd4 100644 --- a/src/maca.c +++ b/src/maca.c @@ -146,6 +146,19 @@ void vreg_init(void) { *(volatile uint32_t *)(0x80003048) = 0x00000ff8; /* start the regulators */ } +void radio_off(void) { + /* turn off the radio regulators */ + reg(0x80003048) = 0x00000f00; + /* hold the maca in reset */ + maca_reset = maca_reset_rst; +} + +void radio_on(void) { + /* turn the radio regulators back on */ + reg(0x80003048) = 0x00000f78; + /* reinitialize the phy */ + init_phy(); +} /* radio_init has been tested to be good */ void radio_init(void) { From bc59b04bbf11b7bc655c77738f59fd646983919b Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 11 May 2009 15:52:30 -0400 Subject: [PATCH 2/7] sleep tests. --- Makefile | 1 + tests/sleep.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/sleep.c diff --git a/Makefile b/Makefile index 7c3873052..f664bf956 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ tests/nvm-write.obj: src/maca.o src/nvm.o tests/rftest-rx.obj: src/maca.o src/nvm.o tests/rftest-tx.obj: src/maca.o src/nvm.o tests/tmr-ints.obj: src/isr.o +tests/sleep.obj: src/isr.o NOTHUMB_CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ diff --git a/tests/sleep.c b/tests/sleep.c new file mode 100644 index 000000000..cd0311310 --- /dev/null +++ b/tests/sleep.c @@ -0,0 +1,62 @@ +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 +#define CRM_WU_CNTL 0x80003004 +#define CRM_SLEEP_CNTL 0x80003008 +#define CRM_STATUS 0x80003018 +#define GPIO_PAD_PU_EN0 0x80000010 +#define GPIO_PAD_PU_EN1 0x80000014 +#define ADC_CONTROL 0x80000018 +#define CRM_XTAL_CNTL 0x80000040 + +#define DELAY 400000 + +#include "embedded_types.h" +#include "isr.h" +#include "utils.h" + +__attribute__ ((section ("startup"))) void main(void) { + reg32(GPIO_PAD_DIR0) = 0x00000100; + + reg32(GPIO_DATA0) = 0x00000100; + + /* disable all pullups */ + /* seems to make a slight difference (2.0uA vs 1.95uA)*/ + reg32(GPIO_PAD_PU_EN0) = 0; + reg32(GPIO_PAD_PU_EN1) = 0; + reg16(ADC_CONTROL) = 0; /* internal Vref2 */ + +// reg16(CRM_XTAL_CNTL) = 0x052; /* default is 0xf52 */ /* doesn't anything w.r.t. power */ + + /* go to sleep */ +// reg32(CRM_WU_CNTL) = 0x1; /* enable wakeup from wakeup timer */ + reg32(CRM_WU_CNTL) = 0; /* don't wake up */ + +// reg32(CRM_SLEEP_CNTL) = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2.0uA */ +// reg32(CRM_SLEEP_CNTL) = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 10.0uA */ +// reg32(CRM_SLEEP_CNTL) = 0x51; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 11.7uA */ +// reg32(CRM_SLEEP_CNTL) = 0x61; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 13.9uA */ +// reg32(CRM_SLEEP_CNTL) = 0x71; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ +// reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, RAM page 0&1 only, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ + +// reg32(CRM_SLEEP_CNTL) = 2; /* doze , RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 69.2 uA */ +// reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ +// reg32(CRM_SLEEP_CNTL) = 0x52; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 78.9uA */ +// reg32(CRM_SLEEP_CNTL) = 0x62; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 81.2uA */ +// reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ + reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , RAM page 0&1 only, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ + reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this totally powers down */ + + + volatile uint32_t i; + while(1) { + + reg32(GPIO_DATA0) = 0x00000100; + + for(i=0; i Date: Mon, 11 May 2009 17:01:31 -0400 Subject: [PATCH 3/7] this test demonstrates sleeping in both hibernate and doze. wake up is controlled with the wake up timer. read the comments for current measurments. --- tests/sleep.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/sleep.c b/tests/sleep.c index cd0311310..fc621eb51 100644 --- a/tests/sleep.c +++ b/tests/sleep.c @@ -1,11 +1,14 @@ #define GPIO_PAD_DIR0 0x80000000 #define GPIO_DATA0 0x80000008 -#define CRM_WU_CNTL 0x80003004 -#define CRM_SLEEP_CNTL 0x80003008 -#define CRM_STATUS 0x80003018 + #define GPIO_PAD_PU_EN0 0x80000010 #define GPIO_PAD_PU_EN1 0x80000014 #define ADC_CONTROL 0x80000018 + +#define CRM_WU_CNTL 0x80003004 +#define CRM_WU_TIMEOUT 0x80003024 +#define CRM_SLEEP_CNTL 0x80003008 +#define CRM_STATUS 0x80003018 #define CRM_XTAL_CNTL 0x80000040 #define DELAY 400000 @@ -21,15 +24,17 @@ __attribute__ ((section ("startup"))) void main(void) { /* disable all pullups */ /* seems to make a slight difference (2.0uA vs 1.95uA)*/ - reg32(GPIO_PAD_PU_EN0) = 0; - reg32(GPIO_PAD_PU_EN1) = 0; - reg16(ADC_CONTROL) = 0; /* internal Vref2 */ +// reg32(GPIO_PAD_PU_EN0) = 0; +// reg32(GPIO_PAD_PU_EN1) = 0; +// reg16(ADC_CONTROL) = 0; /* internal Vref2 */ // reg16(CRM_XTAL_CNTL) = 0x052; /* default is 0xf52 */ /* doesn't anything w.r.t. power */ /* go to sleep */ -// reg32(CRM_WU_CNTL) = 0x1; /* enable wakeup from wakeup timer */ - reg32(CRM_WU_CNTL) = 0; /* don't wake up */ +// reg32(CRM_WU_CNTL) = 0; /* don't wake up */ + reg32(CRM_WU_CNTL) = 0x1; /* enable wakeup from wakeup timer */ + reg32(CRM_WU_TIMEOUT) = 1875000; /* wake 10 sec later if doze */ +// reg32(CRM_WU_TIMEOUT) = 20000; /* wake 10 sec later if hibernate w/2kHz*/ // reg32(CRM_SLEEP_CNTL) = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2.0uA */ // reg32(CRM_SLEEP_CNTL) = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 10.0uA */ @@ -39,13 +44,22 @@ __attribute__ ((section ("startup"))) void main(void) { // reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, RAM page 0&1 only, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ // reg32(CRM_SLEEP_CNTL) = 2; /* doze , RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 69.2 uA */ -// reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ + reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ // reg32(CRM_SLEEP_CNTL) = 0x52; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 78.9uA */ // reg32(CRM_SLEEP_CNTL) = 0x62; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 81.2uA */ // reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ - reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , RAM page 0&1 only, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ - reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this totally powers down */ +// reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , RAM page 0&1 only, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ + + while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } + + reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */ + /* asleep */ + + while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } + + reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */ + volatile uint32_t i; while(1) { From 5dbd9aa02f303fdcb1ddc1fc28406b3128ab75d7 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 11 May 2009 17:03:20 -0400 Subject: [PATCH 4/7] added a few comments --- tests/sleep.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/sleep.c b/tests/sleep.c index fc621eb51..0368394e1 100644 --- a/tests/sleep.c +++ b/tests/sleep.c @@ -50,16 +50,17 @@ __attribute__ ((section ("startup"))) void main(void) { // reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ // reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , RAM page 0&1 only, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ + /* wait for the sleep cycle to complete */ while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } - - reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */ + /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */ + reg32(CRM_STATUS) = 1; /* asleep */ + /* wait for the awake cycle to complete */ while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } - - reg32(CRM_STATUS) = 1; /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */ - + /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */ + reg32(CRM_STATUS) = 1; volatile uint32_t i; while(1) { From 13656da889321acd63819a5e78639d66bce6847c Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 11 May 2009 17:26:10 -0400 Subject: [PATCH 5/7] corrected comments about ram retention --- tests/sleep.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/sleep.c b/tests/sleep.c index 0368394e1..d223ad50b 100644 --- a/tests/sleep.c +++ b/tests/sleep.c @@ -39,16 +39,16 @@ __attribute__ ((section ("startup"))) void main(void) { // reg32(CRM_SLEEP_CNTL) = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2.0uA */ // reg32(CRM_SLEEP_CNTL) = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 10.0uA */ // reg32(CRM_SLEEP_CNTL) = 0x51; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 11.7uA */ -// reg32(CRM_SLEEP_CNTL) = 0x61; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 13.9uA */ -// reg32(CRM_SLEEP_CNTL) = 0x71; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ -// reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, RAM page 0&1 only, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ +// reg32(CRM_SLEEP_CNTL) = 0x61; /* hibernate, RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 13.9uA */ +// reg32(CRM_SLEEP_CNTL) = 0x71; /* hibernate, all RAM pages, retain state, don't power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ +// reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, all RAM pages, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ // reg32(CRM_SLEEP_CNTL) = 2; /* doze , RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 69.2 uA */ reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ // reg32(CRM_SLEEP_CNTL) = 0x52; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 78.9uA */ -// reg32(CRM_SLEEP_CNTL) = 0x62; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 81.2uA */ -// reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ -// reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , RAM page 0&1 only, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ +// reg32(CRM_SLEEP_CNTL) = 0x62; /* doze , RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 81.2uA */ +// reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , all RAM pages, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ +// reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , all RAM pages, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ /* wait for the sleep cycle to complete */ while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } From fa91eed2a152a88f199cdced6cdbf29a5acfccc7 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Mon, 11 May 2009 17:58:21 -0400 Subject: [PATCH 6/7] added crm.h from contiki --- include/crm.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 include/crm.h diff --git a/include/crm.h b/include/crm.h new file mode 100644 index 000000000..e7b80710f --- /dev/null +++ b/include/crm.h @@ -0,0 +1,36 @@ +#ifndef CRM_H +#define CRM_H + +#define CRM_BASE (0x80003000) +#define CRM_SYS_CNTL (CRM_BASE+0x00) +#define CRM_WU_CNTL (CRM_BASE+0x04) +#define CRM_SLEEP_CNTL (CRM_BASE+0x08) +#define CRM_BS_CNTL (CRM_BASE+0x0c) +#define CRM_COP_CNTL (CRM_BASE+0x10) +#define CRM_COP_SERVICE (CRM_BASE+0x14) +#define CRM_STATUS (CRM_BASE+0x18) +#define CRM_MOD_STATUS (CRM_BASE+0x1c) +#define CRM_WU_COUNT (CRM_BASE+0x20) +#define CRM_WU_TIMEOUT (CRM_BASE+0x24) +#define CRM_RTC_COUNT (CRM_BASE+0x28) +#define CRM_RTC_TIMEOUT (CRM_BASE+0x2c) +#define CRM_CAL_CNTL (CRM_BASE+0x34) +#define CRM_CAL_COUNT (CRM_BASE+0x38) +#define CRM_RINGOSC_CTNL (CRM_BASE+0x3c) +#define CRM_XTAL_CNTL (CRM_BASE+0x40) +#define CRM_XTAL32_CNTL (CRM_BASE+0x44) +#define CRM_VREG_CNTL (CRM_BASE+0x48) +#define CRM_SW_RST (CRM_BASE+0x50) + +/* wu_cntl bit locations */ +#define EXT_WU_IEN 20 /* 4 bits */ +#define EXT_WU_EN 4 /* 4 bits */ +#define EXT_WU_EDGE 8 /* 4 bits */ +#define EXT_WU_POL 12 /* 4 bits */ + +/* status bit locations */ +#define EXT_WU_EVT 4 /* 4 bits */ + +#define enable_wu_en(k) (set_bit(reg32(CRM_WU_CNTL),(EXT_WU_EN+k-4))) + +#endif From d8a8d529bc9f1366a40130b1668e287a3510a606 Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Tue, 12 May 2009 17:19:57 -0400 Subject: [PATCH 7/7] Sleep works now. Make sure to turn the radio off first. --- Makefile | 2 +- include/isr.h | 2 + tests/sleep.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 147 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f664bf956..93ad8d3f5 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ tests/nvm-write.obj: src/maca.o src/nvm.o tests/rftest-rx.obj: src/maca.o src/nvm.o tests/rftest-tx.obj: src/maca.o src/nvm.o tests/tmr-ints.obj: src/isr.o -tests/sleep.obj: src/isr.o +tests/sleep.obj: src/isr.o src/maca.o src/nvm.o NOTHUMB_CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ diff --git a/include/isr.h b/include/isr.h index 22e1772be..ec4049b89 100644 --- a/include/isr.h +++ b/include/isr.h @@ -5,9 +5,11 @@ #define INTBASE (0x80020000) #define INTENNUM_OFF (0x8) +#define INTDISNUM_OFF (0xc) #define INTSRC_OFF (0x30) #define INTENNUM INTBASE + INTENNUM_OFF +#define INTDISNUM INTBASE + INTDISNUM_OFF #define INTSRC INTBASE + INTSRC_OFF #define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) = 5; diff --git a/tests/sleep.c b/tests/sleep.c index d223ad50b..e7b61b965 100644 --- a/tests/sleep.c +++ b/tests/sleep.c @@ -1,6 +1,8 @@ #define GPIO_PAD_DIR0 0x80000000 #define GPIO_DATA0 0x80000008 +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + #define GPIO_PAD_PU_EN0 0x80000010 #define GPIO_PAD_PU_EN1 0x80000014 #define ADC_CONTROL 0x80000018 @@ -11,17 +13,98 @@ #define CRM_STATUS 0x80003018 #define CRM_XTAL_CNTL 0x80000040 +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + #define DELAY 400000 #include "embedded_types.h" #include "isr.h" #include "utils.h" +#include "maca.h" + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + + +typedef void (*pfCallback_t)(void); + +typedef struct +{ + uint8_t sleepType:1;// 0 hibernate / 1 doze + uint8_t ramRet:2; + uint8_t mcuRet:1; + uint8_t digPadRet:1; + pfCallback_t pfToDoBeforeSleep; +}crmSleepCtrl_t; + +void do_nothing(void) { + return; +} + +void (*crm_gotosleep)(crmSleepCtrl_t *foo) = 0x0000364d; __attribute__ ((section ("startup"))) void main(void) { + crmSleepCtrl_t crmSleepCtrl; + reg32(GPIO_PAD_DIR0) = 0x00000100; reg32(GPIO_DATA0) = 0x00000100; + + /* Restore UART regs. to default */ + /* in case there is still bootloader state leftover */ + + *(volatile uint32_t *)UART1_CON = 0x0000c800; /* mask interrupts, 16 bit sample --- helps explain the baud rate */ + + /* INC = 767; MOD = 9999 works: 115200 @ 24 MHz 16 bit sample */ + #define INC 767 + #define MOD 9999 + *(volatile uint32_t *)UART1_BR = INC<<16 | MOD; + + /* see Section 11.5.1.2 Alternate Modes */ + /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ + /* From the datasheet: "The peripheral function will control operation of the pad IF */ + /* THE PERIPHERAL IS ENABLED. */ + *(volatile uint32_t *)UART1_CON = 0x00000003; /* enable receive and transmit */ + *(volatile uint32_t *)GPIO_FUNC_SEL0 = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ + + reg32(0x00401ffc) = 0x01234567; + reg32(0x00407ffc) = 0xdeadbeef; + reg32(0x0040fffc) = 0xface00ff; + reg32(0x00410000) = 0xabcd0123; + + puts("sleep test\n\r"); + puts("0x00401ffc: "); + put_hex32(reg32(0x00401ffc)); + puts("\r\n"); + puts("0x00407ffc: "); + put_hex32(reg32(0x00407ffc)); + puts("\r\n"); + puts("0x0040fffc: "); + put_hex32(reg32(0x0040fffc)); + puts("\r\n"); + puts("0x00410000: "); + put_hex32(reg32(0x00410000)); + puts("\r\n"); + + /* radio must be OFF before sleeping */ + /* otherwise MCU will not wake up properly */ + /* this is undocumented behavior */ + radio_off(); + /* disable all pullups */ /* seems to make a slight difference (2.0uA vs 1.95uA)*/ // reg32(GPIO_PAD_PU_EN0) = 0; @@ -33,23 +116,32 @@ __attribute__ ((section ("startup"))) void main(void) { /* go to sleep */ // reg32(CRM_WU_CNTL) = 0; /* don't wake up */ reg32(CRM_WU_CNTL) = 0x1; /* enable wakeup from wakeup timer */ - reg32(CRM_WU_TIMEOUT) = 1875000; /* wake 10 sec later if doze */ -// reg32(CRM_WU_TIMEOUT) = 20000; /* wake 10 sec later if hibernate w/2kHz*/ +// reg32(CRM_WU_TIMEOUT) = 1875000; /* wake 10 sec later if doze */ + reg32(CRM_WU_TIMEOUT) = 20000; /* wake 10 sec later if hibernate w/2kHz*/ // reg32(CRM_SLEEP_CNTL) = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2.0uA */ // reg32(CRM_SLEEP_CNTL) = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 10.0uA */ // reg32(CRM_SLEEP_CNTL) = 0x51; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 11.7uA */ // reg32(CRM_SLEEP_CNTL) = 0x61; /* hibernate, RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 13.9uA */ // reg32(CRM_SLEEP_CNTL) = 0x71; /* hibernate, all RAM pages, retain state, don't power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ -// reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, all RAM pages, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ + reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, all RAM pages, retain state, power GPIO */ /* approx. 16.1uA - possibly with periodic refresh*/ // reg32(CRM_SLEEP_CNTL) = 2; /* doze , RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 69.2 uA */ - reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ +// reg32(CRM_SLEEP_CNTL) = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ // reg32(CRM_SLEEP_CNTL) = 0x52; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 78.9uA */ // reg32(CRM_SLEEP_CNTL) = 0x62; /* doze , RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 81.2uA */ // reg32(CRM_SLEEP_CNTL) = 0x72; /* doze , all RAM pages, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ // reg32(CRM_SLEEP_CNTL) = 0xf2; /* doze , all RAM pages, retain state, power GPIO */ /* approx. 82.8uA - possibly with periodic refresh*/ + +/* crmSleepCtrl.sleepType = 0; */ +/* crmSleepCtrl.ramRet = 3; */ +/* crmSleepCtrl.mcuRet = 1; */ +/* crmSleepCtrl.digPadRet = 1; */ +/* crmSleepCtrl.pfToDoBeforeSleep = do_nothing; */ + +/* crm_gotosleep(&crmSleepCtrl); */ + /* wait for the sleep cycle to complete */ while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */ @@ -62,6 +154,21 @@ __attribute__ ((section ("startup"))) void main(void) { /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */ reg32(CRM_STATUS) = 1; + puts("\n\r\n\r\n\r"); + puts("0x00401ffc: "); + put_hex32(reg32(0x00401ffc)); + puts("\r\n"); + puts("0x00407ffc: "); + put_hex32(reg32(0x00407ffc)); + puts("\r\n"); + puts("0x0040fffc: "); + put_hex32(reg32(0x0040fffc)); + puts("\r\n"); + puts("0x00410000: "); + put_hex32(reg32(0x00410000)); + puts("\r\n"); + + volatile uint32_t i; while(1) { @@ -75,3 +182,36 @@ __attribute__ ((section ("startup"))) void main(void) { }; } + + + +void putc(uint8_t c) { + while(reg32(UT1CON)==31); /* wait for there to be room in the buffer */ + reg32(UART1_DATA) = c; +} + +void puts(uint8_t *s) { + while(s && *s!=0) { + putc(*s++); + } +} + +void put_hex(uint8_t x) +{ + putc(hex[x >> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +}