diff --git a/libmc1322x/include/utils.h b/libmc1322x/include/utils.h index 215d3e3f9..5f4c79aeb 100644 --- a/libmc1322x/include/utils.h +++ b/libmc1322x/include/utils.h @@ -1,6 +1,9 @@ #ifndef UTILS_H #define UTILS_H +#define mem32(x) ((volatile uint32_t *)(x)) +#define mem16(x) ((volatile uint16_t *)(x)) + #define CAT2(x, y, z) x##y##z #define bit(bit) (1 << bit) diff --git a/tests/Makefile b/tests/Makefile index 4a58a3247..6764e4229 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -6,7 +6,7 @@ MC1322X := .. COBJS := tests.o put.o # all of the target programs to build -TARGETS := blink-red blink-green blink-blue blink-white blink-allio uart1-loopback nvm-read nvm-write romimg flasher tmr tmr-ints +TARGETS := blink-red blink-green blink-blue blink-white blink-allio uart1-loopback nvm-read nvm-write romimg flasher tmr tmr-ints sleep include $(MC1322X)/Makefile.include diff --git a/tests/config.h b/tests/config.h index 9ac55604a..a0b7f38bb 100644 --- a/tests/config.h +++ b/tests/config.h @@ -29,4 +29,7 @@ #define BOOT_OK 1 #define BOOT_SECURE 0 +/* sleep */ +#undef USE_32KHZ /* board should have a HAS_32KHZ define */ + #endif diff --git a/tests/sleep.c b/tests/sleep.c index e7e8ed6e7..985702f57 100644 --- a/tests/sleep.c +++ b/tests/sleep.c @@ -1,114 +1,36 @@ -#define GPIO_PAD_DIR0 0x80000000 -#define GPIO_DATA0 0x80000008 +#include +#include -#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ +#include "tests.h" +#include "config.h" -#define GPIO_PAD_PU_EN0 0x80000010 -#define GPIO_PAD_PU_EN1 0x80000014 -#define ADC_CONTROL 0x80000018 +void main(void) { -#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 + uart_init(INC,MOD); -#define DELAY 400000 - -#define USE_32KHZ 1 - -#include "embedded_types.h" -#include "isr.h" -#include "utils.h" -#include "maca.h" -#include "crm.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; + *mem32(0x00401ffc) = 0x01234567; + *mem32(0x00407ffc) = 0xdeadbeef; + *mem32(0x0040fffc) = 0xface00ff; + *mem32(0x00410000) = 0xabcd0123; puts("sleep test\n\r"); puts("0x00401ffc: "); - put_hex32(reg32(0x00401ffc)); + put_hex32(*mem32(0x00401ffc)); puts("\r\n"); puts("0x00407ffc: "); - put_hex32(reg32(0x00407ffc)); + put_hex32(*mem32(0x00407ffc)); puts("\r\n"); puts("0x0040fffc: "); - put_hex32(reg32(0x0040fffc)); + put_hex32(*mem32(0x0040fffc)); puts("\r\n"); puts("0x00410000: "); - put_hex32(reg32(0x00410000)); + put_hex32(*mem32(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; - 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 */ +// radio_off(); #if USE_32KHZ /* turn on the 32kHz crystal */ @@ -116,24 +38,24 @@ __attribute__ ((section ("startup"))) void main(void) { /* you have to hold it's hand with this on */ /* once you start the 32xHz crystal it can only be stopped with a reset (hard or soft) */ /* first, disable the ring osc */ - clear_bit(reg32(CRM_RINGOSC_CNTL),0); + clear_bit(*CRM_RINGOSC_CNTL,0); /* enable the 32kHZ crystal */ - set_bit(reg32(CRM_XTAL32_CNTL),0); + set_bit(*CRM_XTAL32_CNTL,0); /* set the XTAL32_EXISTS bit */ /* the datasheet says to do this after you've check that RTC_COUNT is changing */ /* the datasheet is not correct */ - set_bit(reg32(CRM_SYS_CNTL),5); + set_bit(*CRM_SYS_CNTL,5); { static volatile uint32_t old; - old = reg32(CRM_RTC_COUNT); + old = *CRM_RTC_COUNT; puts("waiting for xtal\n\r"); - while(reg32(CRM_RTC_COUNT) == old) { + while(*CRM_RTC_COUNT == old) { continue; } /* RTC has started up */ - set_bit(reg32(CRM_SYS_CNTL),5); + set_bit(*CRM_SYS_CNTL,5); puts("32kHZ xtal started\n\r"); } @@ -142,113 +64,75 @@ __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 */ +// *CRM_WU_CNTL = 0; /* don't wake up */ + *CRM_WU_CNTL = 0x1; /* enable wakeup from wakeup timer */ +// *CRM_WU_TIMEOUT = 1875000; /* wake 10 sec later if doze */ #if USE_32KHZ - reg32(CRM_WU_TIMEOUT) = 327680*2; + *CRM_WU_TIMEOUT = 327680*2; #else - reg32(CRM_WU_TIMEOUT) = 20000; /* wake 10 sec later if hibernate w/2kHz*/ + *CRM_WU_TIMEOUT = 20000; /* wake 10 sec later if hibernate ring osc */ #endif /* hobby board: 2kHz = 11uA; 32kHz = 11uA */ -// reg32(CRM_SLEEP_CNTL) = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2kHz = 2.0uA */ +// *CRM_SLEEP_CNTL = 1; /* hibernate, RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 2kHz = 2.0uA */ /* hobby board: 2kHz = 18uA; 32kHz = 19uA */ -// reg32(CRM_SLEEP_CNTL) = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 2kHz = 10.0uA */ +// *CRM_SLEEP_CNTL = 0x41; /* hibernate, RAM page 0 only, retain state, don't power GPIO */ /* approx. 2kHz = 10.0uA */ /* hobby board: 2kHz = 20uA; 32kHz = 21uA */ -// reg32(CRM_SLEEP_CNTL) = 0x51; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 2kHz = 11.7uA */ +// *CRM_SLEEP_CNTL = 0x51; /* hibernate, RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 2kHz = 11.7uA */ /* hobby board: 2kHz = 22uA; 32kHz = 22.5uA */ -// reg32(CRM_SLEEP_CNTL) = 0x61; /* hibernate, RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 2kHz = 13.9uA */ +// *CRM_SLEEP_CNTL = 0x61; /* hibernate, RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 2kHz = 13.9uA */ /* hobby board: 2kHz = 24uA; 32kHz = 25uA */ -// reg32(CRM_SLEEP_CNTL) = 0x71; /* hibernate, all RAM pages, retain state, don't power GPIO */ /* approx. 2kHz = 16.1uA */ -// reg32(CRM_SLEEP_CNTL) = 0xf1; /* hibernate, all RAM pages, retain state, power GPIO */ /* consumption depends on GPIO hookup */ + *CRM_SLEEP_CNTL = 0x71; /* hibernate, all RAM pages, retain state, don't power GPIO */ /* approx. 2kHz = 16.1uA */ +// *CRM_SLEEP_CNTL = 0xf1; /* hibernate, all RAM pages, retain state, power GPIO */ /* consumption depends on GPIO hookup */ -// 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,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 */ /* consumption depends on GPIO hookup */ +// *CRM_SLEEP_CNTL = 2; /* doze , RAM page 0 only, don't retain state, don't power GPIO */ /* approx. 69.2 uA */ +// *CRM_SLEEP_CNTL = 0x42; /* doze , RAM page 0 only, retain state, don't power GPIO */ /* approx. 77.3uA */ +// *CRM_SLEEP_CNTL = 0x52; /* doze , RAM page 0&1 only, retain state, don't power GPIO */ /* approx. 78.9uA */ +// *CRM_SLEEP_CNTL = 0x62; /* doze , RAM page 0,1,2 only, retain state, don't power GPIO */ /* approx. 81.2uA */ +// *CRM_SLEEP_CNTL = 0x72; /* doze , all RAM pages, retain state, don't power GPIO */ /* approx. 83.4uA - possibly with periodic refresh*/ +// *CRM_SLEEP_CNTL = 0xf2; /* doze , all RAM pages, retain state, power GPIO */ /* consumption depends on GPIO hookup */ -/* 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; } + while((*CRM_STATUS & 0x1) == 0) { continue; } /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and powers down */ - reg32(CRM_STATUS) = 1; + *CRM_STATUS = 1; /* asleep */ /* wait for the awake cycle to complete */ - while((reg32(CRM_STATUS) & 0x1) == 0) { continue; } + while((*CRM_STATUS & 0x1) == 0) { continue; } /* write 1 to sleep_sync --- this clears the bit (it's a r1wc bit) and finishes wakeup */ - reg32(CRM_STATUS) = 1; + *CRM_STATUS = 1; puts("\n\r\n\r\n\r"); puts("0x00401ffc: "); - put_hex32(reg32(0x00401ffc)); + put_hex32(*mem32(0x00401ffc)); puts("\r\n"); puts("0x00407ffc: "); - put_hex32(reg32(0x00407ffc)); + put_hex32(*mem32(0x00407ffc)); puts("\r\n"); puts("0x0040fffc: "); - put_hex32(reg32(0x0040fffc)); + put_hex32(*mem32(0x0040fffc)); puts("\r\n"); puts("0x00410000: "); - put_hex32(reg32(0x00410000)); + put_hex32(*mem32(0x00410000)); puts("\r\n"); + *GPIO_PAD_DIR0 = LED_RED; +#define DELAY 400000 volatile uint32_t i; while(1) { - reg32(GPIO_DATA0) = 0x00000100; + *GPIO_DATA0 = LED_RED; for(i=0; i> 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); -}