You've already forked ArduinoLowPower
							
							
				mirror of
				https://github.com/arduino-libraries/ArduinoLowPower.git
				synced 2025-11-04 06:11:38 +03:00 
			
		
		
		
	Import latest code from @bigdinotech
This commit is contained in:
		@@ -7,7 +7,7 @@
 | 
				
			|||||||
#error The library is not compatible with AVR boards
 | 
					#error The library is not compatible with AVR boards
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ARDUINO_ARCH_ARC32
 | 
					#ifdef __ARDUINO_ARC__
 | 
				
			||||||
#include "include/arc32/defines.h"
 | 
					#include "include/arc32/defines.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,9 +39,12 @@ class ArduinoLowPowerClass {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode);
 | 
							void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#ifdef ARDUINO_ARCH_ARC32
 | 
							#ifdef __ARDUINO_ARC__
 | 
				
			||||||
        void wakeFromSleepCallback(void);
 | 
							void wakeFromSleepCallback(void);
 | 
				
			||||||
        #endif
 | 
							void wakeFromDoze(void);
 | 
				
			||||||
 | 
							void detachInterruptWakeup(uint32_t pin);
 | 
				
			||||||
 | 
							uint32_t arc_restore_addr;
 | 
				
			||||||
 | 
							#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		#ifdef ARDUINO_ARCH_SAMD
 | 
							#ifdef ARDUINO_ARCH_SAMD
 | 
				
			||||||
@@ -50,24 +53,27 @@ class ArduinoLowPowerClass {
 | 
				
			|||||||
		#define RTC_ALARM_WAKEUP	0xFF
 | 
							#define RTC_ALARM_WAKEUP	0xFF
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#ifdef ARDUINO_ARCH_ARC32
 | 
							#ifdef __ARDUINO_ARC__
 | 
				
			||||||
        void wakeFromDoze();
 | 
					 | 
				
			||||||
        void switchToHybridOscillator();
 | 
					 | 
				
			||||||
        void switchToCrystalOscillator();
 | 
					 | 
				
			||||||
        void attachWakeInterruptRTC(void (*userCallBack)());
 | 
					 | 
				
			||||||
		void turnOffUSB();
 | 
							void turnOffUSB();
 | 
				
			||||||
        void turnOnUSB();
 | 
							void turnOnUSB();
 | 
				
			||||||
        void setRTCCMR(int milliseconds);
 | 
							void switchToHybridOscillator();
 | 
				
			||||||
        uint32_t readRTC_CCVR();
 | 
							void switchToCrystalOscillator();
 | 
				
			||||||
        bool isSleeping = false;
 | 
							void setRTCCMR(int seconds);
 | 
				
			||||||
        uint32_t millisToRTCTicks(int milliseconds);
 | 
							uint32_t readRTC_CCVR();
 | 
				
			||||||
        void enableRTCInterrupt();
 | 
							bool isSleeping = false;
 | 
				
			||||||
        void x86_C2Request();
 | 
							volatile bool dozing = false;
 | 
				
			||||||
        void (*pmCB)();
 | 
							uint32_t millisToRTCTicks(int milliseconds);
 | 
				
			||||||
        #define RTC_ALARM_WAKEUP	0xFF
 | 
							void enableRTCInterrupt(int seconds);
 | 
				
			||||||
 | 
							void enableAONGPIOInterrupt(int aon_gpio, int mode);
 | 
				
			||||||
 | 
							void enableAONPTimerInterrrupt(int millis);
 | 
				
			||||||
 | 
							static void resetAONPTimer();
 | 
				
			||||||
 | 
							static void wakeFromRTC();
 | 
				
			||||||
 | 
							void x86_C2Request();
 | 
				
			||||||
 | 
							void x86_C2LPRequest();
 | 
				
			||||||
 | 
							void (*pmCB)();
 | 
				
			||||||
 | 
							#define RTC_ALARM_WAKEUP	0xFF
 | 
				
			||||||
		#define RESET_BUTTON_WAKEUP	0xFE
 | 
							#define RESET_BUTTON_WAKEUP	0xFE
 | 
				
			||||||
		#endif
 | 
							#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern ArduinoLowPowerClass LowPower;
 | 
					extern ArduinoLowPowerClass LowPower;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,21 +33,23 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "ArduinoLowPower.h"
 | 
					#include "ArduinoLowPower.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ARDUINO_ARCH_ARC32
 | 
					#ifdef __ARDUINO_ARC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "WInterrupts.h"
 | 
					uint32_t arc_restore_addr;
 | 
				
			||||||
 | 
					uint32_t cpu_context[33];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void PM_InterruptHandler(void)
 | 
					static void PM_InterruptHandler(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *(uint32_t*)RTC_CCR |= 0xFFFFFFFE;
 | 
					  unsigned int flags = interrupt_lock();
 | 
				
			||||||
    uint32_t rtc_eoi = *(uint32_t*)RTC_EOI; //clear match interrupt
 | 
					  LowPower.wakeFromDoze();
 | 
				
			||||||
    LowPower.wakeFromSleepCallback();
 | 
					  LowPower.wakeFromSleepCallback();
 | 
				
			||||||
 | 
					  interrupt_unlock(flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::idle()
 | 
					void ArduinoLowPowerClass::idle()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  turnOffUSB();
 | 
					  turnOffUSB();
 | 
				
			||||||
  
 | 
					  dozing = true;
 | 
				
			||||||
  //switch from external crystal oscillator to internal hybrid oscilator
 | 
					  //switch from external crystal oscillator to internal hybrid oscilator
 | 
				
			||||||
  switchToHybridOscillator();
 | 
					  switchToHybridOscillator();
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
@@ -62,9 +64,9 @@ void ArduinoLowPowerClass::idle()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::idle(uint32_t duration)
 | 
					void ArduinoLowPowerClass::idle(uint32_t duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    idle();
 | 
					  idle();
 | 
				
			||||||
    delayTicks(millisToRTCTicks(duration));
 | 
					  delayTicks(millisToRTCTicks(duration));
 | 
				
			||||||
    wakeFromDoze();
 | 
					  wakeFromDoze();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::wakeFromDoze()
 | 
					void ArduinoLowPowerClass::wakeFromDoze()
 | 
				
			||||||
@@ -72,158 +74,273 @@ void ArduinoLowPowerClass::wakeFromDoze()
 | 
				
			|||||||
  //Powerup hybrid oscillator
 | 
					  //Powerup hybrid oscillator
 | 
				
			||||||
  uint32_t current_val = *(uint32_t*)OSC0_CFG1;
 | 
					  uint32_t current_val = *(uint32_t*)OSC0_CFG1;
 | 
				
			||||||
  *(uint32_t*)OSC0_CFG1 = current_val & 0xFFFFFFFB;
 | 
					  *(uint32_t*)OSC0_CFG1 = current_val & 0xFFFFFFFB;
 | 
				
			||||||
   
 | 
					
 | 
				
			||||||
  //Set system clock to the Hybrid Oscillator
 | 
					  //Set system clock to the Hybrid Oscillator
 | 
				
			||||||
  current_val = *(uint32_t*)CCU_SYS_CLK_CTL;
 | 
					  current_val = *(uint32_t*)CCU_SYS_CLK_CTL;
 | 
				
			||||||
  *(uint32_t*)CCU_SYS_CLK_CTL = current_val | 0x00000001;
 | 
					  *(uint32_t*)CCU_SYS_CLK_CTL = current_val | 0x00000001;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  //switch back to the external crystal oiscillator
 | 
					  //switch back to the external crystal oscillator
 | 
				
			||||||
  void switchToCrystalOscillator();
 | 
					  switchToCrystalOscillator();
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  turnOnUSB();
 | 
					  turnOnUSB();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dozing = false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::sleep()
 | 
					void ArduinoLowPowerClass::sleep()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   turnOffUSB();
 | 
					  uint32_t creg_mst0_ctrl = 0;
 | 
				
			||||||
   //*(uint32_t*)SLP_CFG &= 0xFFFFFEFF;
 | 
					  creg_mst0_ctrl = __builtin_arc_lr(QM_SS_CREG_BASE);
 | 
				
			||||||
   
 | 
					
 | 
				
			||||||
   x86_C2Request();
 | 
					  /*
 | 
				
			||||||
   isSleeping = true;
 | 
					  * Clock gate the sensor peripherals at CREG level.
 | 
				
			||||||
   //*(uint32_t*)CCU_LP_CLK_CTL = (*(uint32_t*)CCU_LP_CLK_CTL) | 0x00000002;
 | 
					  * This clock gating is independent of the peripheral-specific clock
 | 
				
			||||||
   //uint32_t c2 = *(uint32_t*)P_LVL2;
 | 
					  * gating provided in ss_clk.h .
 | 
				
			||||||
   *(uint32_t*)PM1C |= 0x00002000;
 | 
					  */
 | 
				
			||||||
 | 
					  creg_mst0_ctrl |= (QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE |
 | 
				
			||||||
 | 
					   QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE |
 | 
				
			||||||
 | 
					  QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE |
 | 
				
			||||||
 | 
					  QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE |
 | 
				
			||||||
 | 
					  QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  __builtin_arc_sr(creg_mst0_ctrl, QM_SS_CREG_BASE);
 | 
				
			||||||
 | 
					  x86_C2LPRequest();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  idle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __asm__ __volatile__(
 | 
				
			||||||
 | 
					       "sleep %0"
 | 
				
			||||||
 | 
					       :
 | 
				
			||||||
 | 
					       : "i"(QM_SS_SLEEP_MODE_CORE_OFF));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  creg_mst0_ctrl &= ~(QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE |
 | 
				
			||||||
 | 
					         QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE |
 | 
				
			||||||
 | 
					         QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE |
 | 
				
			||||||
 | 
					         QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE |
 | 
				
			||||||
 | 
					         QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  __builtin_arc_sr(creg_mst0_ctrl, QM_SS_CREG_BASE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::sleep(uint32_t duration)
 | 
					void ArduinoLowPowerClass::sleep(uint32_t duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    setRTCCMR(duration);
 | 
					  enableAONPTimerInterrrupt(duration);
 | 
				
			||||||
    enableRTCInterrupt();
 | 
					  sleep();
 | 
				
			||||||
    sleep();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::deepSleep()
 | 
					void ArduinoLowPowerClass::deepSleep()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
   turnOffUSB();
 | 
					  sleep();
 | 
				
			||||||
   
 | 
					 | 
				
			||||||
   x86_C2Request();
 | 
					 | 
				
			||||||
   isSleeping = true;
 | 
					 | 
				
			||||||
   *(uint32_t*)CCU_LP_CLK_CTL  |= 0x00000001;
 | 
					 | 
				
			||||||
   //uint32_t c2 = *(uint32_t*)P_LVL2;
 | 
					 | 
				
			||||||
   *(uint32_t*)PM1C |= 0x00002000;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::deepSleep(uint32_t duration)
 | 
					void ArduinoLowPowerClass::deepSleep(uint32_t duration)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    setRTCCMR(duration);
 | 
					  sleep(duration);
 | 
				
			||||||
    enableRTCInterrupt();
 | 
					 | 
				
			||||||
    deepSleep();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ArduinoLowPowerClass::switchToHybridOscillator()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    //read trim value from OTP
 | 
					 | 
				
			||||||
    uint32_t trimMask = *(uint16_t*)OSCTRIM_ADDR << 20;
 | 
					 | 
				
			||||||
    *(uint32_t*)OSC0_CFG1 = 0x00000002 | trimMask;  //switch to internal oscillator using trim value from OTP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ArduinoLowPowerClass::switchToCrystalOscillator()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    *(uint32_t*)OSC0_CFG1 = 0x00070009;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline void ArduinoLowPowerClass::wakeFromSleepCallback(void)
 | 
					inline void ArduinoLowPowerClass::wakeFromSleepCallback(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(pmCB != NULL)
 | 
					  if(pmCB != NULL)
 | 
				
			||||||
        pmCB();
 | 
					      pmCB();
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void ArduinoLowPowerClass::attachWakeInterruptRTC(void (*userCallBack)())
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    pmCB = userCallBack;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Privates
 | 
					//Privates
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::turnOffUSB()
 | 
					void ArduinoLowPowerClass::turnOffUSB()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *(uint32_t*)USB_PHY_CFG0 |= 0x00000001; 
 | 
					  *(uint32_t*)USB_PHY_CFG0 |= 0x00000001;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::turnOnUSB()
 | 
					void ArduinoLowPowerClass::turnOnUSB()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *(uint32_t*)USB_PHY_CFG0 &= 0xFFFFFFFE;
 | 
					  *(uint32_t*)USB_PHY_CFG0 &= 0xFFFFFFFE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::setRTCCMR(int milliseconds)
 | 
					void ArduinoLowPowerClass::switchToHybridOscillator()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *(uint32_t*)RTC_CMR = readRTC_CCVR() + millisToRTCTicks(milliseconds);
 | 
					  //read trim value from OTP
 | 
				
			||||||
    //*(uint32_t*)RTC_CMR = readRTC_CCVR() + milliseconds;
 | 
					  uint32_t trimMask = *(uint16_t*)OSCTRIM_ADDR << 20;
 | 
				
			||||||
 | 
					  *(uint32_t*)OSC0_CFG1 = 0x00000002 | trimMask;  //switch to internal oscillator using trim value from OTP
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::switchToCrystalOscillator()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  *(uint32_t*)OSC0_CFG1 = 0x00070009;
 | 
				
			||||||
 | 
					  while(!(*(uint32_t*)OSC0_STAT & 0x00000002));   //wait till crystal oscillator is stable
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::setRTCCMR(int seconds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  *(uint32_t*)RTC_CMR = readRTC_CCVR() + seconds;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t ArduinoLowPowerClass::readRTC_CCVR()
 | 
					uint32_t ArduinoLowPowerClass::readRTC_CCVR()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return *(uint32_t*)RTC_CCVR;
 | 
					  return *RTC_CCVR;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint32_t ArduinoLowPowerClass::millisToRTCTicks(int milliseconds)
 | 
					uint32_t ArduinoLowPowerClass::millisToRTCTicks(int milliseconds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return (uint32_t)((double)milliseconds*32.768);
 | 
					  return (uint32_t)((double)milliseconds*32.768);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::enableRTCInterrupt()
 | 
					void ArduinoLowPowerClass::enableRTCInterrupt(int seconds)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    *(uint32_t*)RTC_MASK_INT &= 0xFFFFFFFF;
 | 
					  setRTCCMR(seconds);
 | 
				
			||||||
    *(uint32_t*)RTC_CCR |= 0x00000001;
 | 
					  *(uint32_t*)RTC_MASK_INT &= 0xFFFFFEFE;
 | 
				
			||||||
    *(uint32_t*)RTC_CCR &= 0xFFFFFFFD;
 | 
					  *(uint32_t*)RTC_CCR |= 0x00000001;
 | 
				
			||||||
 | 
					  *(uint32_t*)RTC_CCR &= 0xFFFFFFFD;
 | 
				
			||||||
 | 
					  volatile uint32_t read = *(uint32_t*)RTC_EOI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pmCB = &wakeFromRTC;
 | 
				
			||||||
 | 
					  interrupt_disable(IRQ_RTC_INTR);
 | 
				
			||||||
 | 
					  interrupt_connect(IRQ_RTC_INTR , &PM_InterruptHandler);
 | 
				
			||||||
 | 
					  delayTicks(6400);   //2ms
 | 
				
			||||||
 | 
					  interrupt_enable(IRQ_RTC_INTR);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::enableAONPTimerInterrrupt(int millis)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  pmCB = resetAONPTimer;
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CFG = millisToRTCTicks(millis);
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CTRL |= 0x00000003;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_TIMER_MASK_INT &= 0xFFFFFEFE;
 | 
				
			||||||
 | 
					  interrupt_disable(IRQ_ALWAYS_ON_TMR);
 | 
				
			||||||
 | 
					  interrupt_connect(IRQ_ALWAYS_ON_TMR , &PM_InterruptHandler);
 | 
				
			||||||
 | 
					  delayTicks(6400);   //2ms
 | 
				
			||||||
 | 
					  interrupt_enable(IRQ_ALWAYS_ON_TMR);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::resetAONPTimer()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CFG = 0;
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CTRL |= 0x00000001;
 | 
				
			||||||
 | 
					  delayTicks(6400);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //trick the HOST into waking from AONPTimer
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CFG = 10;
 | 
				
			||||||
 | 
					  *(uint32_t*)AONPT_CTRL |= 0x00000003;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_TIMER_MASK_INT &= 0xFFFFFFFE;
 | 
				
			||||||
 | 
					  interrupt_enable(IRQ_ALWAYS_ON_TMR);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::enableAONGPIOInterrupt(int aon_gpio, int mode)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  switch(mode)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    case CHANGE:    //not supported just do the same as FALLING
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case RISING:
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case FALLING:
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case HIGH:
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case LOW:
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INTTYPE_LEVEL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        *(uint32_t*)AON_GPIO_INT_POL &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_GPIO_SWPORTA_DDR &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_GPIO_INTMASK &= ~(1 << aon_gpio);
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_GPIO_INTEN |= 1 << aon_gpio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  *(uint32_t*)AON_GPIO_MASK_INT &= 0xFFFFFEFE;
 | 
				
			||||||
 | 
					  interrupt_disable(IRQ_ALWAYS_ON_GPIO);
 | 
				
			||||||
 | 
					  interrupt_connect(IRQ_ALWAYS_ON_GPIO , &PM_InterruptHandler);
 | 
				
			||||||
 | 
					  interrupt_enable(IRQ_ALWAYS_ON_GPIO);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::wakeFromRTC()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    *(uint32_t*)RTC_MASK_INT |= 0x00000101;
 | 
				
			||||||
    interrupt_disable(IRQ_RTC_INTR);
 | 
					    interrupt_disable(IRQ_RTC_INTR);
 | 
				
			||||||
    interrupt_connect(IRQ_RTC_INTR , &PM_InterruptHandler);
 | 
					    volatile uint32_t read = *(uint32_t*)RTC_EOI;
 | 
				
			||||||
    interrupt_enable(IRQ_RTC_INTR);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::x86_C2Request()
 | 
					void ArduinoLowPowerClass::x86_C2Request()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    switchToHybridOscillator();
 | 
					    switchToHybridOscillator();
 | 
				
			||||||
    //set the CCU_C2_LP_EN bit
 | 
					 | 
				
			||||||
    *(uint32_t*)CCU_LP_CLK_CTL = (*(uint32_t*)CCU_LP_CLK_CTL) | 0x00000002;
 | 
					 | 
				
			||||||
    //request for the x86 core go into C2 sleep
 | 
					    //request for the x86 core go into C2 sleep
 | 
				
			||||||
    volatile uint32_t c2 = *(volatile uint32_t*)P_LVL2;
 | 
					    volatile uint32_t c2 = *(volatile uint32_t*)P_LVL2;
 | 
				
			||||||
 
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ArduinoLowPowerClass::x86_C2LPRequest()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  switchToHybridOscillator();
 | 
				
			||||||
 | 
					  //request for the x86 core go into C2 sleep
 | 
				
			||||||
 | 
					  *(uint32_t*)CCU_LP_CLK_CTL |= 0x00000002;
 | 
				
			||||||
 | 
					  volatile uint32_t c2lp = *(volatile uint32_t*)P_LVL2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) {
 | 
					void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern uint32_t sizeof_g_APinDescription;
 | 
					    if( pin >= NUM_DIGITAL_PINS  )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        pmCB = callback;
 | 
				
			||||||
 | 
					        switch (pin)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            case AON_GPIO0:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(0, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case AON_GPIO1:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(1, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case AON_GPIO2:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(2, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case AON_GPIO3:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(3, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case INT_BMI160:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(4, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case INT_BLE:
 | 
				
			||||||
 | 
					                enableAONGPIOInterrupt(5, mode);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pin > sizeof_g_APinDescription) {
 | 
					void ArduinoLowPowerClass::detachInterruptWakeup(uint32_t pin)
 | 
				
			||||||
		// check for external wakeup sources
 | 
					{
 | 
				
			||||||
		// RTC library should call this API to enable the alarm subsystem
 | 
					    pmCB = NULL;
 | 
				
			||||||
		switch (pin) {
 | 
					    if( pin >= NUM_DIGITAL_PINS  )
 | 
				
			||||||
			case RTC_ALARM_WAKEUP:
 | 
					    {
 | 
				
			||||||
				attachWakeInterruptRTC(callback);
 | 
					        if(pin == INT_RTC)
 | 
				
			||||||
				break;
 | 
					        {
 | 
				
			||||||
			case RESET_BUTTON_WAKEUP:
 | 
					            interrupt_disable(IRQ_RTC_INTR);
 | 
				
			||||||
				gpio_cfg_data_t pin_cfg = {
 | 
					        }
 | 
				
			||||||
					.gpio_type = GPIO_INTERRUPT,
 | 
					        else if (pin == INT_COMP)
 | 
				
			||||||
					.int_type = LEVEL,
 | 
					        {
 | 
				
			||||||
					.int_polarity = ACTIVE_LOW,
 | 
					            interrupt_disable(IRQ_ALWAYS_ON_TMR);
 | 
				
			||||||
					.int_debounce = DEBOUNCE_OFF,
 | 
					        }
 | 
				
			||||||
					.int_ls_sync = LS_SYNC_OFF,
 | 
					        else if (pin == AON_TIMER)
 | 
				
			||||||
					.gpio_cb = callback
 | 
					        {
 | 
				
			||||||
				};
 | 
					            interrupt_disable(IRQ_COMPARATORS_INTR);
 | 
				
			||||||
				soc_gpio_deconfig(SOC_GPIO_AON, 0);
 | 
					        }
 | 
				
			||||||
				/* set RESET GPIO button to be an input */
 | 
					        else
 | 
				
			||||||
				soc_gpio_set_config(SOC_GPIO_AON, 0, &pin_cfg);
 | 
					        {
 | 
				
			||||||
				SET_PIN_PULLUP(32*3 + 8, 1);
 | 
					           interrupt_disable(IRQ_ALWAYS_ON_GPIO);
 | 
				
			||||||
				break;
 | 
					        }
 | 
				
			||||||
		}
 | 
					    }
 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//pinMode(pin, INPUT_PULLUP);
 | 
					 | 
				
			||||||
	//attachInterrupt(pin, callback, mode);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ArduinoLowPowerClass LowPower;
 | 
					ArduinoLowPowerClass LowPower;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					#define OSC0_STAT       0xB0800004
 | 
				
			||||||
#define OSC0_CFG1       0xB0800008
 | 
					#define OSC0_CFG1       0xB0800008
 | 
				
			||||||
#define CCU_SS_PERIPH_CLK_GATE_CTL  0xB0800028
 | 
					#define CCU_SS_PERIPH_CLK_GATE_CTL  0xB0800028
 | 
				
			||||||
#define CCU_SYS_CLK_CTL 0xB0800038
 | 
					#define CCU_SYS_CLK_CTL 0xB0800038
 | 
				
			||||||
@@ -5,18 +6,43 @@
 | 
				
			|||||||
#define P_LVL2          0xB0800504
 | 
					#define P_LVL2          0xB0800504
 | 
				
			||||||
#define PM1C            0xB0800518
 | 
					#define PM1C            0xB0800518
 | 
				
			||||||
#define SLP_CFG         0xB0800550
 | 
					#define SLP_CFG         0xB0800550
 | 
				
			||||||
 | 
					#define SS_STS          0xB0800604
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AONC_CNT        0xB0800700
 | 
				
			||||||
 | 
					#define AONC_CFG        0xB0800704
 | 
				
			||||||
 | 
					#define AONPT_CNT       0xB0800708
 | 
				
			||||||
 | 
					#define AONPT_STAT      0xB080070C
 | 
				
			||||||
 | 
					#define AONPT_CTRL      0xB0800710
 | 
				
			||||||
 | 
					#define AONPT_CFG       0xB0800714
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define USB_PLL_CFG0    0xB0800014
 | 
					#define USB_PLL_CFG0    0xB0800014
 | 
				
			||||||
#define USB_PHY_CFG0    0xB0800800
 | 
					#define USB_PHY_CFG0    0xB0800800
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RTC_CCVR        0xB0000400
 | 
					#define RTC_CCVR        (volatile int*)0xB0000400 // Current Counter Value Register
 | 
				
			||||||
#define RTC_CMR         0xB0000404
 | 
					#define RTC_CMR         0xB0000404
 | 
				
			||||||
#define RTC_CCR         0xB000040C
 | 
					#define RTC_CCR         0xB000040C
 | 
				
			||||||
#define RTC_EOI         0xB0000418
 | 
					#define RTC_EOI         0xB0000418
 | 
				
			||||||
#define RTC_MASK_INT    0xB0800478
 | 
					#define RTC_MASK_INT    0xB0800478
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AON_TIMER_MASK_INT      0xB08004C8
 | 
				
			||||||
 | 
					#define AON_GPIO_MASK_INT       0xB08004D4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AON_GPIO_SWPORTA_DR         0xB0800B00
 | 
				
			||||||
 | 
					#define AON_GPIO_SWPORTA_DDR        0xB0800B04
 | 
				
			||||||
 | 
					#define AON_GPIO_SWPORTA_CTL        0xB0800B08
 | 
				
			||||||
 | 
					#define AON_GPIO_INTEN              0xB0800B30
 | 
				
			||||||
 | 
					#define AON_GPIO_INTMASK            0xB0800B34
 | 
				
			||||||
 | 
					#define AON_GPIO_INTTYPE_LEVEL      0xB0800B38
 | 
				
			||||||
 | 
					#define AON_GPIO_INT_POL            0xB0800B3C
 | 
				
			||||||
 | 
					#define AON_GPIO_DEBOUNCE           0xB0888B48
 | 
				
			||||||
 | 
					#define AON_GPIO_PORTA_EOI           0xB0800B4C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OSCTRIM_ADDR    0xffffe1f8
 | 
					#define OSCTRIM_ADDR    0xffffe1f8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define QM_SS_SLEEP_MODE_CORE_OFF (0x0)
 | 
				
			||||||
 | 
					#define QM_SS_SLEEP_MODE_CORE_OFF_TIMER_OFF (0x20)
 | 
				
			||||||
 | 
					#define QM_SS_SLEEP_MODE_CORE_TIMERS_RTC_OFF (0x60)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SLEEP_HOST_C0       0
 | 
					#define SLEEP_HOST_C0       0
 | 
				
			||||||
#define SLEEP_HOST_C1       1
 | 
					#define SLEEP_HOST_C1       1
 | 
				
			||||||
#define SLEEP_HOST_C2       2
 | 
					#define SLEEP_HOST_C2       2
 | 
				
			||||||
@@ -26,6 +52,20 @@
 | 
				
			|||||||
#define SLEEP_SS_SS2        6
 | 
					#define SLEEP_SS_SS2        6
 | 
				
			||||||
#define SLEEP_LPSS          7
 | 
					#define SLEEP_LPSS          7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum wakeSource{
 | 
				
			||||||
 | 
					    AON_GPIO0 = 100,
 | 
				
			||||||
 | 
					    AON_GPIO1 = 101,
 | 
				
			||||||
 | 
					    AON_GPIO2 = 102,
 | 
				
			||||||
 | 
					    AON_GPIO3 = 103,
 | 
				
			||||||
 | 
					    AON_GPIO4 = 104,
 | 
				
			||||||
 | 
					    AON_GPIO5 = 105,
 | 
				
			||||||
 | 
					    INT_BMI160 = 104,
 | 
				
			||||||
 | 
					    INT_BLE = 105,
 | 
				
			||||||
 | 
					    INT_RTC = 106,
 | 
				
			||||||
 | 
					    AON_TIMER = 107,
 | 
				
			||||||
 | 
					    INT_COMP = 108,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Pin Muxing */
 | 
					/* Pin Muxing */
 | 
				
			||||||
#define PULLUP_BASE    QRK_PMUX_PULLUP_0
 | 
					#define PULLUP_BASE    QRK_PMUX_PULLUP_0
 | 
				
			||||||
/* Read current pull-up reg, Zero pin bit, OR new mode into these bits, write reg - thereby preserving other pin mode settings */
 | 
					/* Read current pull-up reg, Zero pin bit, OR new mode into these bits, write reg - thereby preserving other pin mode settings */
 | 
				
			||||||
@@ -37,4 +77,6 @@
 | 
				
			|||||||
#include <Arduino.h>
 | 
					#include <Arduino.h>
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
#include <interrupt.h>
 | 
					#include <interrupt.h>
 | 
				
			||||||
#include <board.h>
 | 
					#include <board.h>
 | 
				
			||||||
 | 
					#include "qm_sensor_regs.h"
 | 
				
			||||||
 | 
					#include "ss_power_states.h"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user