andy-phung

Untitled

Oct 28th, 2020
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.24 KB | None | 0 0
  1. /*
  2. LowPower_WithWorkAndGPIOInterrupt
  3. Adapted by Stephen Fordyce 2020-03-23 from:
  4. Artemis Low Power: How low can we go?
  5. By: Nathan Seidle
  6. SparkFun Electronics
  7. Date: February 26th, 2020
  8. License: This code is public domain.
  9. */
  10.  
  11. uint32_t msToSleep = 5000; //This is the user editable number of ms to sleep between RTC checks
  12. #define TIMER_FREQ 32768L //Counter/Timer 6 will use the 32kHz clock
  13. uint32_t sysTicksToSleep = msToSleep * TIMER_FREQ / 1000;
  14.  
  15. const byte STATUS_LED = 14;//13 for Redboard onboard LED, 19 for Nano onboard LED
  16. const byte INPUT_BUTTON = 19;//You'll have to add one, it needs to connect to GND for active
  17.  
  18. bool awakeFlag = true; //Stops wakeFromSleep() being run if the system is already awake
  19.  
  20.  
  21. // GPIO Interrupt Service Routine
  22. void myGPIO_ISR(void)
  23. {
  24. detachInterrupt(digitalPinToInterrupt(INPUT_BUTTON)); //Stop interrupt from being triggered again
  25. wakeFromSleep(); //Without waking the processor properly, nothing more will happen. This means wakeFromSleep() is called twice though.
  26. // am_hal_stimer_compare_delta_set(6, 0); //Or, force the timer to run out, and resume from where you left off.
  27. }
  28.  
  29.  
  30. void setup(void) {
  31. Serial.begin(115200);
  32. Serial.println("Artemis Low Power (with timer & GPIO wakeup) Example");
  33. pinMode(STATUS_LED, OUTPUT);
  34. pinMode(INPUT_BUTTON, INPUT_PULLUP);
  35. //Initialise stuff like I2C/Wire/SPI here
  36. }
  37.  
  38.  
  39. void loop(void) {
  40. Serial.println("Starting loop, and flashing LED");
  41. digitalWrite(STATUS_LED, HIGH);
  42. delay(200);
  43. digitalWrite(STATUS_LED, LOW);
  44. Serial.println("Phew, that was hard work");
  45. goToSleep();
  46. }
  47.  
  48.  
  49. //Power everything down and wait for interrupt wakeup
  50. void goToSleep()
  51. {
  52. attachInterrupt(digitalPinToInterrupt(INPUT_BUTTON), myGPIO_ISR, FALLING);
  53.  
  54. //End stuff like I2C/Wire/SPI here
  55.  
  56. power_adc_disable(); //Power down ADC. It it started by default before setup().
  57.  
  58. Serial.println("Going to sleep");
  59. delay(50); //Wait for serial to finish
  60. Serial.end(); //Power down UART(s)
  61. awakeFlag = false;
  62.  
  63. //Disable all pads except the interrupt button
  64. for (int x = 0 ; x < 50 ; x++)
  65. {
  66. if(x != INPUT_BUTTON)
  67. am_hal_gpio_pinconfig(x , g_AM_HAL_GPIO_DISABLE);
  68. }
  69.  
  70. //We use counter/timer 6 to cause us to wake up from sleep but 0 to 7 are available
  71. //CT 7 is used for Software Serial. All CTs are used for Servo.
  72. am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG); //Clear CT6
  73. am_hal_stimer_int_enable(AM_HAL_STIMER_INT_COMPAREG); //Enable C/T G=6
  74.  
  75. //Use the lower power 32kHz clock. Use it to run CT6 as well.
  76. am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  77. am_hal_stimer_config(AM_HAL_STIMER_XTAL_32KHZ | AM_HAL_STIMER_CFG_COMPARE_G_ENABLE);
  78.  
  79. //Setup interrupt to trigger when the number of ms have elapsed
  80. am_hal_stimer_compare_delta_set(6, sysTicksToSleep);
  81.  
  82. //Power down Flash, SRAM, cache
  83. am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE); //Turn off CACHE
  84. am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_512K); //Turn off everything but lower 512k
  85. am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_64K_DTCM); //Turn off everything but lower 64k
  86. //am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_ALL); //Turn off all memory (doesn't recover)
  87.  
  88. // Enable interrupts to the core.
  89. am_hal_interrupt_master_enable();
  90.  
  91. //Enable the timer interrupt in the NVIC.
  92. NVIC_EnableIRQ(STIMER_CMPR6_IRQn);
  93.  
  94. //Go to Deep Sleep.
  95. am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
  96.  
  97. /////////////////////////////////////////////////////////////////////
  98. //<Pause here while sleeping> (and/or while interrupt routines run)//
  99. /////////////////////////////////////////////////////////////////////
  100.  
  101. //Turn off timer interrupt
  102. NVIC_DisableIRQ(STIMER_CMPR6_IRQn);
  103.  
  104. //Turn off GPIO interrupt
  105. detachInterrupt(digitalPinToInterrupt(INPUT_BUTTON));
  106.  
  107. //We're BACK!
  108. wakeFromSleep();
  109. Serial.println("End of goToSleep()");
  110. Serial.println();
  111. }
  112.  
  113.  
  114. //Power everything up gracefully
  115. void wakeFromSleep()
  116. {
  117. if(awakeFlag) //Already awake
  118. return;
  119.  
  120. //Power up SRAM, turn on entire Flash
  121. am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_MAX);
  122.  
  123. //Go back to using the main clock
  124. am_hal_stimer_int_enable(AM_HAL_STIMER_INT_OVERFLOW);
  125. NVIC_EnableIRQ(STIMER_IRQn);
  126. am_hal_stimer_config(AM_HAL_STIMER_CFG_CLEAR | AM_HAL_STIMER_CFG_FREEZE);
  127. am_hal_stimer_config(AM_HAL_STIMER_HFRC_3MHZ);
  128.  
  129. //Turn on ADC
  130. ap3_adc_setup();
  131.  
  132. //Set any pinModes
  133. pinMode(STATUS_LED, OUTPUT);
  134. pinMode(INPUT_BUTTON, INPUT_PULLUP);
  135.  
  136. //Optional - start again (will never reach the end of goToSleep() or wakeFromSleep() though)
  137. //Note - global variables will be preserved if you don't power down SRAM (comment out the line)
  138. //setup();
  139.  
  140. //Restart Serial
  141. Serial.begin(115200);
  142. delay(10);
  143. Serial.println("Back on");
  144. awakeFlag = true;
  145.  
  146. //Initialise stuff like I2C/Wire/SPI here
  147. }
  148.  
  149.  
  150. //Called once number of milliseconds has passed
  151. extern "C" void am_stimer_cmpr6_isr(void)
  152. {
  153. uint32_t ui32Status = am_hal_stimer_int_status_get(false);
  154. if (ui32Status & AM_HAL_STIMER_INT_COMPAREG)
  155. {
  156. am_hal_stimer_int_clear(AM_HAL_STIMER_INT_COMPAREG);
  157. }
  158. }
Advertisement
Add Comment
Please, Sign In to add comment