diff --git a/README.md b/README.md index 1e6afae..7268aa9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Snooze v5.2.1 +#Snooze v5.3

General Usage

diff --git a/Snooze.cpp b/Snooze.cpp index f6864b5..1be1857 100644 --- a/Snooze.cpp +++ b/Snooze.cpp @@ -112,7 +112,6 @@ SnoozeClass::SnoozeClass( void ) { SIM_SOPT1 &= ~SIM_SOPT1_USBSSTBY_MASK; attachInterruptVector( IRQ_LLWU, wakeupISR ); NVIC_SET_PRIORITY( IRQ_LLWU, 32 ); - //lptmr_init( ); //cmp_init( ); clock_mode = mcg_mode( ); #if defined( USE_HIBERNATE ) @@ -144,15 +143,15 @@ void SnoozeClass::idle( void ) { * * @return wakeup source */ -int SnoozeClass::sleep( SnoozeBlock &configuration ) { +int SnoozeClass::sleep( SnoozeBlock &configuration ) { SnoozeBlock *p = &configuration; enable_periph_irq = true; cmp_set( &p->cmp_mask ); - digital_set( &p->digital_mask ); lptmr_set( &p->lptmr_mask ); #ifdef KINETISK rtc_alarm_set( &p->rtc_mask ); #endif + digital_set( &p->digital_mask ); #ifdef KINETISL pinMode( 17, OUTPUT ); digitalWriteFast( 17, LOW ); @@ -182,12 +181,12 @@ int SnoozeClass::sleep( SnoozeBlock &configuration ) { usbEnable ( ); peripheral_set( &p->setPeripheral.periph_off_mask ); } + digital_disable( &p->digital_mask ); #ifdef KINETISK rtc_disable( &p->rtc_mask ); #endif - cmp_disable( &p->cmp_mask ); lptmr_disable( &p->lptmr_mask ); - digital_disable( &p->digital_mask ); + cmp_disable( &p->cmp_mask ); return wakeupSource; } //--------------------------------------DeepSleep---------------------------------------- @@ -204,7 +203,6 @@ int SnoozeClass::deepSleep( SnoozeBlock &configuration, SLEEP_MODE mode ) { enable_periph_irq = false; sleep_mode = mode; cmp_set( &p->cmp_mask ); - digital_set( &p->digital_mask ); lptmr_set( &p->lptmr_mask ); #ifdef KINETISK rtc_alarm_set( &p->rtc_mask ); @@ -214,6 +212,7 @@ int SnoozeClass::deepSleep( SnoozeBlock &configuration, SLEEP_MODE mode ) { digitalWriteFast( 17, LOW ); #endif tsi_set( &p->tsi_mask ); + digital_set( &p->digital_mask ); llwu_set( &p->llwu_mask ); if ( mode == LLS ) { enter_lls( ); } else if ( mode == VLLS3 ) { enter_vlls3( ); } diff --git a/Snooze.h b/Snooze.h index 5aa2d33..12f12f8 100644 --- a/Snooze.h +++ b/Snooze.h @@ -1,7 +1,7 @@ /* || || @file Snooze.h - || @version 5.2.1 + || @version 5.3 || @author duff || @contact http://forum.pjrc.com/members/25610-duff || diff --git a/library.properties b/library.properties index 4ab23be..6ff5378 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Snooze -version=5.2.1 +version=5.3 author=Colin Duffy maintainer=Colin Duffy sentence=Low Power for Teensy 3.x/LC diff --git a/revision.md b/revision.md index 011b321..4967a58 100644 --- a/revision.md +++ b/revision.md @@ -1,3 +1,7 @@ +>Updated (5/31/15 v5.3)
+* Fixed sleep function low power timer.
+* Fixed digital pin wake on LOW or HIGH interrupt type, now if pin interrupt type is configured LOW and the pin is LOW when going into sleep it will wake immediately, the same goes for if it is HIGH interrupt type.
+ >Updated (5/28/15 v5.2.1)
* Remove debug stuff.
diff --git a/utility/cmp.h b/utility/cmp.h index dbf0d08..86a1d82 100644 --- a/utility/cmp.h +++ b/utility/cmp.h @@ -122,7 +122,7 @@ extern "C" { int priority = nvic_execution_priority( );// get current priority // if running from handler set priority higher than current handler - priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; + priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128; NVIC_SET_PRIORITY( IRQ_CMP0, priority );//set priority to new level __disable_irq( ); diff --git a/utility/digital.h b/utility/digital.h index 45c473e..398eb88 100644 --- a/utility/digital.h +++ b/utility/digital.h @@ -141,119 +141,121 @@ extern "C" { if ( mask->state == false ) return; #if defined(KINETISK) uint64_t _pin = mask->pin; - while ( __builtin_popcountll( _pin ) ) { - uint32_t pin = 63 - __builtin_clzll( _pin );// get pin - uint32_t mode = mask->mode_irqType[pin] >> 4;// get type - uint32_t type = mask->mode_irqType[pin] & 0x0F;// get mode - - volatile uint32_t *config; - config = portConfigRegister( pin ); - - if ( enable_periph_irq ) {// if using sleep must setup pin interrupt to wake - + if ( enable_periph_irq ) {// if using sleep must setup pin interrupt to wake + while ( __builtin_popcountll( _pin ) ) { + uint32_t pin = 63 - __builtin_clzll( _pin );// get pin + if ( pin > 33 ) return; int priority = nvic_execution_priority( );// get current priority - // if running from handler set priority higher than current handler - priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; - + // if running from interrupt set priority higher than current interrupt + priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128; if ( pin == 3 || pin == 4 || pin == 24 || pin == 33 ) { - NVIC_SET_PRIORITY( IRQ_PORTA, priority );//set priority to new level __disable_irq( ); - return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr + return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr handler attachInterruptVector( IRQ_PORTA, digitalISR );// set snooze isr __enable_irq( ); } else if ( pin == 0 || pin == 1 || pin == 16 || pin == 17 || pin == 18 || pin == 19 || pin == 25 || pin == 32 ) { NVIC_SET_PRIORITY( IRQ_PORTB, priority );//set priority to new level __disable_irq( ); - return_portb_irq = _VectorsRam[IRQ_PORTB+16];// save prev isr + return_portb_irq = _VectorsRam[IRQ_PORTB+16];// save prev isr handler attachInterruptVector( IRQ_PORTB, digitalISR );// set snooze isr __enable_irq( ); } else if ( pin == 9 || pin == 10 || pin == 11 || pin == 12 || pin == 13 || pin == 15 || pin == 22 || pin == 23 || pin == 27 || pin == 28 || pin == 29 || pin == 30 ) { NVIC_SET_PRIORITY( IRQ_PORTC, priority );//set priority to new level __disable_irq( ); - return_portc_irq = _VectorsRam[IRQ_PORTC+16];// save prev isr + return_portc_irq = _VectorsRam[IRQ_PORTC+16];// save prev isr handler attachInterruptVector( IRQ_PORTC, digitalISR );// set snooze isr __enable_irq( ); } else if ( pin == 2 || pin == 5 || pin == 6 || pin == 7 || pin == 8 || pin == 14 || pin == 20 || pin == 21 ) { NVIC_SET_PRIORITY( IRQ_PORTD, priority );//set priority to new level __disable_irq( ); - return_portd_irq = _VectorsRam[IRQ_PORTD+16];// save prev isr + return_portd_irq = _VectorsRam[IRQ_PORTD+16];// save prev isr handler attachInterruptVector( IRQ_PORTD, digitalISR );// set snooze isr __enable_irq( ); } else if ( pin == 26 || pin == 31 ) { NVIC_SET_PRIORITY( IRQ_PORTE, priority );//set priority to new level __disable_irq( ); - return_porte_irq = _VectorsRam[IRQ_PORTE+16];// save prev isr + return_porte_irq = _VectorsRam[IRQ_PORTE+16];// save prev isr handler attachInterruptVector( IRQ_PORTE, digitalISR );// set snooze isr __enable_irq( ); } + + _pin &= ~( ( uint64_t )1<pin; + while ( __builtin_popcountll( _pin ) ) { + uint32_t pin = 63 - __builtin_clzll( _pin );// get pin + uint32_t mode = mask->mode_irqType[pin] >> 4;// get type + uint32_t type = mask->mode_irqType[pin] & 0x0F;// get mode + + volatile uint32_t *config; + config = portConfigRegister( pin ); if ( mode == INPUT || mode == INPUT_PULLUP ) {// setup pin mode/type/interrupt *portModeRegister( pin ) = 0; if ( mode == INPUT ) *config = PORT_PCR_MUX( 1 ); else *config = PORT_PCR_MUX( 1 ) | PORT_PCR_PE | PORT_PCR_PS;// pullup - if ( enable_periph_irq ) { - attachDigitalInterrupt( pin, type );// set pin interrupt - } + if ( enable_periph_irq ) attachDigitalInterrupt( pin, type );// set pin interrupt } else { pinMode( pin, mode ); digitalWriteFast( pin, type ); } - _pin &= ~( ( uint64_t )1<pin; - while ( __builtin_popcount( _pin ) ) { - uint32_t pin = 31 - __builtin_clz( _pin );// get pin - uint32_t mode = mask->mode_irqType[pin] >> 4;// get type - uint32_t type = mask->mode_irqType[pin] & 0x0F;// get mode - - volatile uint32_t *config; - config = portConfigRegister( pin ); - - if ( enable_periph_irq ) {// if using sleep must setup pin interrupt to wake + if ( enable_periph_irq ) {// if using sleep must setup pin interrupt to wake + while ( __builtin_popcount( _pin ) ) { + uint32_t pin = 31 - __builtin_clz( _pin );// get pin int priority = nvic_execution_priority( );// get current priority // if running from handler set priority higher than current handler priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; - if ( pin == 3 || pin == 4 ) { NVIC_SET_PRIORITY( IRQ_PORTA, priority );//set priority to new level __disable_irq( ); - return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr + return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr handler attachInterruptVector( IRQ_PORTA, digitalISR );// set snooze isr __enable_irq( ); } else if ( pin == 2 || pin == 5 || pin == 6 || pin == 7 || pin == 8 || pin == 14 || pin == 20 || pin == 21 || pin == 9 || pin == 10 || pin == 11 || pin == 12 || pin == 13 || pin == 15 || pin == 22 || pin == 23 ) { NVIC_SET_PRIORITY( IRQ_PORTCD, priority );//set priority to new level __disable_irq( ); - return_portcd_irq = _VectorsRam[IRQ_PORTCD+16];// save prev isr + return_portcd_irq = _VectorsRam[IRQ_PORTCD+16];// save prev isr handler attachInterruptVector( IRQ_PORTCD, digitalISR );// set snooze isr __enable_irq( ); } + _pin &= ~( ( uint32_t )1<pin; + while ( __builtin_popcount( _pin ) ) { + uint32_t pin = 31 - __builtin_clz( _pin );// get pin + uint32_t mode = mask->mode_irqType[pin] >> 4;// get type + uint32_t type = mask->mode_irqType[pin] & 0x0F;// get mode + + volatile uint32_t *config; + config = portConfigRegister( pin ); if ( mode == INPUT || mode == INPUT_PULLUP ) {// setup pin mode/type/interrupt *portModeRegister( pin ) &= ~digitalPinToBitMask( pin ); // TODO: atomic if ( mode == INPUT ) *config = PORT_PCR_MUX( 1 ); else *config = PORT_PCR_MUX( 1 ) | PORT_PCR_PE | PORT_PCR_PS;// pullup - if ( enable_periph_irq ) { - attachDigitalInterrupt( pin, type );// set pin interrupt - } + if ( enable_periph_irq ) attachDigitalInterrupt( pin, type );// set pin interrupt } else { pinMode( pin, mode ); digitalWriteFast( pin, type ); } - _pin &= ~( ( uint32_t )1<pin; while ( __builtin_popcountll( _pin ) ) { uint32_t pin = 63 - __builtin_clzll( _pin ); + if ( pin > 33 ) { + __enable_irq( );// enable interrupts from digital_set function + return; + } + detachDigitalInterrupt( pin );// remove pin interrupt + _pin &= ~( ( uint64_t )1<pin; + while ( __builtin_popcountll( _pin ) ) { - if ( enable_periph_irq ) {// if using sleep, give back previous isr - - detachDigitalInterrupt( pin );// remove interrupt - + uint32_t pin = 63 - __builtin_clzll( _pin ); + if ( enable_periph_irq ) {// if using sleep, give back previous isr handler if ( pin == 3 || pin == 4 || pin == 24 || pin == 33 ) { NVIC_SET_PRIORITY( IRQ_PORTA, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTA, return_porta_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTA, return_porta_irq );// return prev interrupt handler __enable_irq( ); } else if ( pin == 0 || pin == 1 || pin == 16 || pin == 17 || pin == 18 || pin == 19 || pin == 25 || pin == 32 ) { NVIC_SET_PRIORITY( IRQ_PORTB, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTB, return_portb_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTB, return_portb_irq );// return prev interrupt handler __enable_irq( ); } else if ( pin == 9 || pin == 10 || pin == 11 || pin == 12 || pin == 13 || pin == 15 || pin == 22 || pin == 23 || pin == 27 || pin == 28 || pin == 29 || pin == 30 ) { NVIC_SET_PRIORITY( IRQ_PORTC, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTC, return_portc_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTC, return_portc_irq );// return prev interrupt handler __enable_irq( ); } else if ( pin == 2 || pin == 5 || pin == 6 || pin == 7 || pin == 8 || pin == 14 || pin == 20 || pin == 21 ) { NVIC_SET_PRIORITY( IRQ_PORTD, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTD, return_portd_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTD, return_portd_irq );// return prev interrupt handler __enable_irq( ); - if (*return_portd_irq != portd_isr) { - //return_portd_irq(); - } } else if ( pin == 26 || pin == 31 ) { NVIC_SET_PRIORITY( IRQ_PORTE, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTE, return_porte_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTE, return_porte_irq );// return prev interrupt handler __enable_irq( ); } - } - _pin &= ~( ( uint64_t )1<pin; while ( __builtin_popcount( _pin ) ) { uint32_t pin = 31 - __builtin_clz( _pin ); - - if ( enable_periph_irq ) {// if using sleep give back previous isr - - detachDigitalInterrupt( pin );// remove interrupt - + if ( pin > 33 ) { + __enable_irq( );// enable interrupts from digital_set function + return; + } + detachDigitalInterrupt( pin );// remove pin interrupt + _pin &= ~( ( uint32_t )1<pin; + while ( __builtin_popcount( _pin ) ) { + uint32_t pin = 31 - __builtin_clz( _pin ); + if ( enable_periph_irq ) {// if using sleep give back previous isr handler if ( pin == 3 || pin == 4 ) { NVIC_SET_PRIORITY( IRQ_PORTA, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTA, return_porta_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTA, return_porta_irq );// return prev interrupt handler __enable_irq( ); } else if ( pin == 2 || pin == 5 || pin == 6 || pin == 7 || pin == 8 || pin == 14 || pin == 20 || pin == 21 || pin == 9 || pin == 10 || pin == 11 || pin == 12 || pin == 13 || pin == 15 || pin == 22 || pin == 23 ) { NVIC_SET_PRIORITY( IRQ_PORTCD, 128 );//return priority to core level __disable_irq( ); - attachInterruptVector( IRQ_PORTCD, return_portcd_irq );// return prev interrupt + attachInterruptVector( IRQ_PORTCD, return_portcd_irq );// return prev interrupt handler __enable_irq( ); } } - _pin &= ~( ( uint32_t )1<state == false ) return; if ( enable_periph_irq ) { - int priority = nvic_execution_priority( );// get current priority // if running from handler set priority higher than current handler - priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; + priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128; NVIC_SET_PRIORITY( IRQ_LPTMR, priority );//set priority to new level - __disable_irq( ); return_lptmr_irq = _VectorsRam[IRQ_LPTMR+16];// save prev isr attachInterruptVector( IRQ_LPTMR, lptmrISR ); __enable_irq( ); - - delay(100); - NVIC_ENABLE_IRQ( IRQ_LPTMR ); } - SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL( 3 ); - SIM_SCGC5 |= SIM_SCGC5_LPTIMER; - LPTMR0_CSR = LPTMR_CSR_TCF; - LPTMR0_PSR = LPTMR_PSR_PBYP | LPTMR_LPO; + lptmr_init( ); LPTMR0_CMR = mask->period; + if( enable_periph_irq ) NVIC_ENABLE_IRQ( IRQ_LPTMR ); LPTMR0_CSR = LPTMR_CSR_TEN | LPTMR_CSR_TIE | LPTMR_CSR_TCF; irqEnabledFlag |= LPTMR_IRQ_BIT; } @@ -128,7 +123,6 @@ extern "C" { __disable_irq( ); attachInterruptVector( IRQ_LPTMR, return_lptmr_irq );// return prev interrupt __enable_irq( ); - //detachInterruptVector( IRQ_LPTMR ); } } #ifdef __cplusplus diff --git a/utility/rtc.h b/utility/rtc.h index 6766318..b2f0b2f 100644 --- a/utility/rtc.h +++ b/utility/rtc.h @@ -80,7 +80,7 @@ extern "C" { int priority = nvic_execution_priority( );// get current priority // if running from handler set priority higher than current handler - priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; + priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128; NVIC_SET_PRIORITY( IRQ_RTC_ALARM, priority );//set priority to new level __disable_irq( ); diff --git a/utility/smc.h b/utility/smc.h index 2890aa3..7863e38 100644 --- a/utility/smc.h +++ b/utility/smc.h @@ -518,8 +518,12 @@ extern "C" { void wait( void ) { SYST_CSR &= ~SYST_CSR_TICKINT; // disable systick timer interrupt SCB_SCR &= ~SCB_SCR_SLEEPDEEP_MASK; // Clear the SLEEPDEEP bit to make sure we go into WAIT (sleep) mode instead of deep sleep. + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { asm volatile( "wfi" ); }// WFI instruction will start entry into WAIT mode + //asm volatile( "wfi" ); + SYST_CSR |= SYST_CSR_TICKINT; // renable systick timer interrupt + } #ifdef __cplusplus diff --git a/utility/tsi.h b/utility/tsi.h index f6009d0..e49ad8b 100644 --- a/utility/tsi.h +++ b/utility/tsi.h @@ -92,7 +92,7 @@ extern "C" { int priority = nvic_execution_priority( );// get current priority // if running from handler set priority higher than current handler - priority = ( priority < 256 ) && ( (priority - 16) > 0 ) ? priority - 16 : 128; + priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128; NVIC_SET_PRIORITY( IRQ_TSI, priority );//set priority to new level __disable_irq( ); diff --git a/utility/util.h b/utility/util.h index 5475b85..edddb33 100644 --- a/utility/util.h +++ b/utility/util.h @@ -16,6 +16,11 @@ static DMAMEM volatile uint8_t irqEnabledFlag = 0; #define RTC_IRQ_BIT 0x02 #define LPTMR_IRQ_BIT 0x04 #define TSI_IRQ_BIT 0x08 +#define DIGITALA_IRQ_BIT 0x10 +#define DIGITALB_IRQ_BIT 0x20 +#define DIGITALC_IRQ_BIT 0x40 +#define DIGITALD_IRQ_BIT 0x80 +#define DIGITALE_IRQ_BIT 0x100 static volatile uint32_t PCR3; /*******************************************************************************/ #ifdef __cplusplus @@ -90,13 +95,11 @@ extern "C" { } mask = ( mask << 16 ) | 0x01000000; config = portConfigRegister( pin ); - __disable_irq( ); cfg = *config; cfg &= ~0x000F0000; // disable any previous interrupt *config = cfg; cfg |= mask; *config = cfg; // enable the new interrupt - __enable_irq( ); } //--------------------------------------------------------// static inline @@ -107,9 +110,7 @@ extern "C" { void detachDigitalInterrupt( uint8_t pin ) { volatile uint32_t *config; config = portConfigRegister( pin ); - __disable_irq( ); *config = ( ( *config & ~0x000F0000 ) | 0x01000000 ); - __enable_irq( ); } //--------------------------------------------------------// static inline