mirror of
https://github.com/arduino-libraries/ArduinoLowPower.git
synced 2025-04-19 11:42:14 +03:00
[ARC32] RTC wakeup from idle() works
code from https://github.com/bigdinotech/Arduino101Power/
This commit is contained in:
parent
e99fcefe8b
commit
7304fe0419
@ -8,10 +8,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ARC32
|
||||
#include "include/arc32/power_states.h"
|
||||
#include "include/arc32/ss_power_states.h"
|
||||
#include "include/arc32/qm_sensor_regs.h"
|
||||
#include "include/arc32/qm_soc_regs.h"
|
||||
#include "include/arc32/defines.h"
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
@ -24,15 +21,28 @@ class ArduinoLowPowerClass {
|
||||
public:
|
||||
void idle(void);
|
||||
void idle(uint32_t millis);
|
||||
void idle(int millis) {
|
||||
idle((uint32_t)millis);
|
||||
}
|
||||
|
||||
void sleep(void);
|
||||
void sleep(uint32_t millis);
|
||||
void sleep(int millis) {
|
||||
sleep((uint32_t)millis);
|
||||
}
|
||||
|
||||
void deepSleep(void);
|
||||
void deepSleep(uint32_t millis);
|
||||
void deepSleep(int millis) {
|
||||
deepSleep((uint32_t)millis);
|
||||
}
|
||||
|
||||
void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode);
|
||||
|
||||
#ifdef ARDUINO_ARCH_ARC32
|
||||
void wakeFromSleepCallback(void);
|
||||
#endif
|
||||
|
||||
private:
|
||||
#ifdef ARDUINO_ARCH_SAMD
|
||||
void setAlarmIn(uint32_t millis);
|
||||
@ -41,18 +51,20 @@ class ArduinoLowPowerClass {
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_ARC32
|
||||
void ss_power_soc_lpss_enable();
|
||||
void ss_power_soc_lpss_disable();
|
||||
void ss_power_cpu_ss1(const ss_power_cpu_ss1_mode_t mode);
|
||||
void ss_power_cpu_ss2();
|
||||
void ss_power_soc_sleep_restore();
|
||||
void ss_power_soc_deep_sleep_restore();
|
||||
void ss_power_sleep_wait();
|
||||
void power_soc_set_ss_restore_flag();
|
||||
void power_soc_sleep();
|
||||
void power_soc_deep_sleep();
|
||||
void setAlarmIn(uint32_t millis);
|
||||
#define RTC_ALARM_WAKEUP 0xFF
|
||||
void wakeFromDoze();
|
||||
void switchToHybridOscillator();
|
||||
void switchToCrystalOscillator();
|
||||
void attachWakeInterruptRTC(void (*userCallBack)());
|
||||
void turnOffUSB();
|
||||
void turnOnUSB();
|
||||
void setRTCCMR(int milliseconds);
|
||||
uint32_t readRTC_CCVR();
|
||||
bool isSleeping = false;
|
||||
uint32_t millisToRTCTicks(int milliseconds);
|
||||
void enableRTCInterrupt();
|
||||
void x86_C2Request();
|
||||
void (*pmCB)();
|
||||
#define RTC_ALARM_WAKEUP 0xFF
|
||||
#define RESET_BUTTON_WAKEUP 0xFE
|
||||
#endif
|
||||
|
||||
|
@ -25,6 +25,9 @@
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* code ported from https://github.com/bigdinotech/Arduino101Power/
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@ -34,298 +37,158 @@
|
||||
|
||||
#include "WInterrupts.h"
|
||||
|
||||
/* Sensor Subsystem sleep operand definition.
|
||||
* Only a subset applies as internal sensor RTC
|
||||
* is not available.
|
||||
*
|
||||
* OP | Core | Timers | RTC
|
||||
* 000 | 0 | 1 | 1 <-- used for SS1
|
||||
* 001 | 0 | 0 | 1
|
||||
* 010 | 0 | 1 | 0
|
||||
* 011 | 0 | 0 | 0 <-- used for SS2
|
||||
* 100 | 0 | 0 | 0
|
||||
* 101 | 0 | 0 | 0
|
||||
* 110 | 0 | 0 | 0
|
||||
* 111 | 0 | 0 | 0
|
||||
*
|
||||
* sleep opcode argument:
|
||||
* - [7:5] : Sleep Operand
|
||||
* - [4] : Interrupt enable
|
||||
* - [3:0] : Interrupt threshold value
|
||||
*/
|
||||
#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)
|
||||
|
||||
void ArduinoLowPowerClass::power_soc_sleep()
|
||||
static void PM_InterruptHandler(void)
|
||||
{
|
||||
/* Go to sleep */
|
||||
QM_SCSS_PMU->slp_cfg &= ~QM_SCSS_SLP_CFG_LPMODE_EN;
|
||||
QM_SCSS_PMU->pm1c |= QM_SCSS_PM1C_SLPEN;
|
||||
*(uint32_t*)RTC_CCR |= 0xFFFFFFFE;
|
||||
uint32_t rtc_eoi = *(uint32_t*)RTC_EOI; //clear match interrupt
|
||||
LowPower.wakeFromSleepCallback();
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::power_soc_deep_sleep()
|
||||
void ArduinoLowPowerClass::idle()
|
||||
{
|
||||
/* Switch to linear regulators.
|
||||
* For low power deep sleep mode, it is a requirement that the platform
|
||||
* voltage regulators are not in switching mode.
|
||||
*/
|
||||
/*
|
||||
vreg_plat1p8_set_mode(VREG_MODE_LINEAR);
|
||||
vreg_plat3p3_set_mode(VREG_MODE_LINEAR);
|
||||
*/
|
||||
turnOffUSB();
|
||||
|
||||
//switch from external crystal oscillator to internal hybrid oscilator
|
||||
switchToHybridOscillator();
|
||||
|
||||
//Set system clock to the RTC Crystal Oscillator
|
||||
uint32_t current_val = *(uint32_t*)CCU_SYS_CLK_CTL;
|
||||
*(uint32_t*)CCU_SYS_CLK_CTL = current_val & 0xFFFFFFFE;
|
||||
|
||||
/* Enable low power sleep mode */
|
||||
QM_SCSS_PMU->slp_cfg |= QM_SCSS_SLP_CFG_LPMODE_EN;
|
||||
QM_SCSS_PMU->pm1c |= QM_SCSS_PM1C_SLPEN;
|
||||
//Powerdown hybrid oscillator
|
||||
current_val = *(uint32_t*)OSC0_CFG1;
|
||||
*(uint32_t*)OSC0_CFG1 = current_val | 0x00000004;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::ss_power_soc_lpss_enable()
|
||||
void ArduinoLowPowerClass::idle(uint32_t duration)
|
||||
{
|
||||
uint32_t creg_mst0_ctrl = 0;
|
||||
|
||||
creg_mst0_ctrl = __builtin_arc_lr(QM_SS_CREG_BASE);
|
||||
|
||||
/*
|
||||
* Clock gate the sensor peripherals at CREG level.
|
||||
* This clock gating is independent of the peripheral-specific clock
|
||||
* gating provided in ss_clk.h .
|
||||
*/
|
||||
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);
|
||||
|
||||
QM_SCSS_CCU->ccu_lp_clk_ctl |= QM_SCSS_CCU_SS_LPS_EN;
|
||||
idle();
|
||||
delayTicks(millisToRTCTicks(duration));
|
||||
wakeFromDoze();
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::ss_power_soc_lpss_disable()
|
||||
void ArduinoLowPowerClass::wakeFromDoze()
|
||||
{
|
||||
uint32_t creg_mst0_ctrl = 0;
|
||||
//Powerup hybrid oscillator
|
||||
uint32_t current_val = *(uint32_t*)OSC0_CFG1;
|
||||
*(uint32_t*)OSC0_CFG1 = current_val & 0xFFFFFFFB;
|
||||
|
||||
//Set system clock to the Hybrid Oscillator
|
||||
current_val = *(uint32_t*)CCU_SYS_CLK_CTL;
|
||||
*(uint32_t*)CCU_SYS_CLK_CTL = current_val | 0x00000001;
|
||||
|
||||
creg_mst0_ctrl = __builtin_arc_lr(QM_SS_CREG_BASE);
|
||||
|
||||
/*
|
||||
* Restore clock gate of the sensor peripherals at CREG level.
|
||||
* CREG is not used anywhere else so we can safely restore
|
||||
* the configuration to its POR default.
|
||||
*/
|
||||
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);
|
||||
|
||||
QM_SCSS_CCU->ccu_lp_clk_ctl &= ~QM_SCSS_CCU_SS_LPS_EN;
|
||||
//switch back to the external crystal oiscillator
|
||||
void switchToCrystalOscillator();
|
||||
|
||||
turnOnUSB();
|
||||
}
|
||||
|
||||
/* Enter SS1 :
|
||||
* SLEEP + sleep operand
|
||||
* __builtin_arc_sleep is not used here as it does not propagate sleep operand.
|
||||
*/
|
||||
void ArduinoLowPowerClass::ss_power_cpu_ss1(const ss_power_cpu_ss1_mode_t mode)
|
||||
void ArduinoLowPowerClass::sleep()
|
||||
{
|
||||
/* The sensor cannot be woken up with an edge triggered
|
||||
* interrupt from the RTC and the AON Counter.
|
||||
* Switch to Level triggered interrupts and restore
|
||||
* the setting when waking up.
|
||||
*/
|
||||
__builtin_arc_sr(IRQ_RTC_INTR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_LEVEL_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
__builtin_arc_sr(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_LEVEL_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
/* Enter SS1 */
|
||||
switch (mode) {
|
||||
case SS_POWER_CPU_SS1_TIMER_OFF:
|
||||
__asm__ __volatile__(
|
||||
"sleep %0"
|
||||
:
|
||||
: "i"(QM_SS_SLEEP_MODE_CORE_OFF_TIMER_OFF));
|
||||
break;
|
||||
case SS_POWER_CPU_SS1_TIMER_ON:
|
||||
default:
|
||||
__asm__ __volatile__("sleep %0"
|
||||
:
|
||||
: "i"(QM_SS_SLEEP_MODE_CORE_OFF));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Restore the RTC and AONC to edge interrupt after when waking up. */
|
||||
__builtin_arc_sr(QM_IRQ_RTC_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_EDGE_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
__builtin_arc_sr(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_EDGE_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
turnOffUSB();
|
||||
//*(uint32_t*)SLP_CFG &= 0xFFFFFEFF;
|
||||
|
||||
x86_C2Request();
|
||||
isSleeping = true;
|
||||
//*(uint32_t*)CCU_LP_CLK_CTL = (*(uint32_t*)CCU_LP_CLK_CTL) | 0x00000002;
|
||||
//uint32_t c2 = *(uint32_t*)P_LVL2;
|
||||
*(uint32_t*)PM1C |= 0x00002000;
|
||||
}
|
||||
|
||||
/* Enter SS2 :
|
||||
* SLEEP + sleep operand
|
||||
* __builtin_arc_sleep is not used here as it does not propagate sleep operand.
|
||||
*/
|
||||
void ArduinoLowPowerClass::ss_power_cpu_ss2(void)
|
||||
void ArduinoLowPowerClass::sleep(uint32_t duration)
|
||||
{
|
||||
/* The sensor cannot be woken up with an edge triggered
|
||||
* interrupt from the RTC and the AON Counter.
|
||||
* Switch to Level triggered interrupts and restore
|
||||
* the setting when waking up.
|
||||
*/
|
||||
__builtin_arc_sr(QM_IRQ_RTC_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_LEVEL_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
__builtin_arc_sr(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_LEVEL_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
/* Enter SS2 */
|
||||
__asm__ __volatile__("sleep %0"
|
||||
:
|
||||
: "i"(QM_SS_SLEEP_MODE_CORE_TIMERS_RTC_OFF));
|
||||
|
||||
/* Restore the RTC and AONC to edge interrupt after when waking up. */
|
||||
__builtin_arc_sr(QM_IRQ_RTC_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_EDGE_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
|
||||
__builtin_arc_sr(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT);
|
||||
__builtin_arc_sr(QM_SS_IRQ_EDGE_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER);
|
||||
setRTCCMR(duration);
|
||||
enableRTCInterrupt();
|
||||
sleep();
|
||||
}
|
||||
|
||||
/* FIXME: use a .global symbol in linker for arc_restore_addr */
|
||||
uint32_t arc_restore_addr;
|
||||
uint32_t cpu_context[33];
|
||||
void ArduinoLowPowerClass::ss_power_soc_sleep_restore(void)
|
||||
void ArduinoLowPowerClass::deepSleep()
|
||||
{
|
||||
/*
|
||||
* Save sensor restore trap address.
|
||||
* The first parameter in this macro represents the label defined in
|
||||
* the qm_ss_restore_context() macro, which is actually the restore
|
||||
* trap address.
|
||||
*/
|
||||
qm_ss_set_resume_vector(sleep_restore_trap, arc_restore_addr);
|
||||
|
||||
/* Save ARC execution context. */
|
||||
qm_ss_save_context(cpu_context);
|
||||
|
||||
/* Set restore flags. */
|
||||
power_soc_set_ss_restore_flag();
|
||||
|
||||
/* Enter sleep. */
|
||||
power_soc_sleep();
|
||||
|
||||
/*
|
||||
* Restore sensor execution context.
|
||||
* The sensor startup code will jump to this location after waking up
|
||||
* from sleep. The restore trap address is the label defined in the
|
||||
* macro and the label is exposed here through the first parameter.
|
||||
*/
|
||||
qm_ss_restore_context(sleep_restore_trap, cpu_context);
|
||||
turnOffUSB();
|
||||
|
||||
x86_C2Request();
|
||||
isSleeping = true;
|
||||
*(uint32_t*)CCU_LP_CLK_CTL |= 0x00000001;
|
||||
//uint32_t c2 = *(uint32_t*)P_LVL2;
|
||||
*(uint32_t*)PM1C |= 0x00002000;
|
||||
}
|
||||
void ArduinoLowPowerClass::ss_power_soc_deep_sleep_restore(void)
|
||||
|
||||
void ArduinoLowPowerClass::deepSleep(uint32_t duration)
|
||||
{
|
||||
/*
|
||||
* Save sensor restore trap address.
|
||||
* The first parameter in this macro represents the label defined in
|
||||
* the qm_ss_restore_context() macro, which is actually the restore
|
||||
* trap address.
|
||||
*/
|
||||
qm_ss_set_resume_vector(deep_sleep_restore_trap, arc_restore_addr);
|
||||
|
||||
/* Save ARC execution context. */
|
||||
qm_ss_save_context(cpu_context);
|
||||
|
||||
/* Set restore flags. */
|
||||
power_soc_set_ss_restore_flag();
|
||||
|
||||
/* Enter sleep. */
|
||||
power_soc_deep_sleep();
|
||||
|
||||
/*
|
||||
* Restore sensor execution context.
|
||||
* The sensor startup code will jump to this location after waking up
|
||||
* from sleep. The restore trap address is the label defined in the
|
||||
* macro and the label is exposed here through the first parameter.
|
||||
*/
|
||||
qm_ss_restore_context(deep_sleep_restore_trap, cpu_context);
|
||||
setRTCCMR(duration);
|
||||
enableRTCInterrupt();
|
||||
deepSleep();
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::ss_power_sleep_wait(void)
|
||||
void ArduinoLowPowerClass::switchToHybridOscillator()
|
||||
{
|
||||
/*
|
||||
* Save sensor restore trap address.
|
||||
* The first parameter in this macro represents the label defined in
|
||||
* the qm_ss_restore_context() macro, which is actually the restore
|
||||
* trap address.
|
||||
*/
|
||||
qm_ss_set_resume_vector(sleep_restore_trap, arc_restore_addr);
|
||||
|
||||
/* Save ARC execution context. */
|
||||
qm_ss_save_context(cpu_context);
|
||||
|
||||
/* Set restore flags. */
|
||||
power_soc_set_ss_restore_flag();
|
||||
|
||||
/* Enter SS1 and stay in it until sleep and wake-up. */
|
||||
while (1) {
|
||||
ss_power_cpu_ss1(SS_POWER_CPU_SS1_TIMER_ON);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore sensor execution context.
|
||||
* The sensor startup code will jump to this location after waking up
|
||||
* from sleep. The restore trap address is the label defined in the
|
||||
* macro and the label is exposed here through the first parameter.
|
||||
*/
|
||||
qm_ss_restore_context(sleep_restore_trap, cpu_context);
|
||||
//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::power_soc_set_ss_restore_flag(void)
|
||||
void ArduinoLowPowerClass::switchToCrystalOscillator()
|
||||
{
|
||||
QM_SCSS_GP->gps0 |= BIT(QM_GPS0_BIT_SENSOR_WAKEUP);
|
||||
*(uint32_t*)OSC0_CFG1 = 0x00070009;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::idle() {
|
||||
ss_power_cpu_ss1(SS_POWER_CPU_SS1_TIMER_ON);
|
||||
inline void ArduinoLowPowerClass::wakeFromSleepCallback(void)
|
||||
{
|
||||
if(pmCB != NULL)
|
||||
pmCB();
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::idle(uint32_t millis) {
|
||||
setAlarmIn(millis);
|
||||
idle();
|
||||
void ArduinoLowPowerClass::attachWakeInterruptRTC(void (*userCallBack)())
|
||||
{
|
||||
pmCB = userCallBack;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::sleep() {
|
||||
ss_power_soc_lpss_enable();
|
||||
//ss_power_cpu_ss2();
|
||||
power_soc_deep_sleep();
|
||||
ss_power_soc_lpss_disable();
|
||||
//Privates
|
||||
|
||||
void ArduinoLowPowerClass::turnOffUSB()
|
||||
{
|
||||
*(uint32_t*)USB_PHY_CFG0 |= 0x00000001;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::sleep(uint32_t millis) {
|
||||
setAlarmIn(millis);
|
||||
sleep();
|
||||
void ArduinoLowPowerClass::turnOnUSB()
|
||||
{
|
||||
*(uint32_t*)USB_PHY_CFG0 &= 0xFFFFFFFE;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::deepSleep() {
|
||||
sleep();
|
||||
void ArduinoLowPowerClass::setRTCCMR(int milliseconds)
|
||||
{
|
||||
*(uint32_t*)RTC_CMR = readRTC_CCVR() + millisToRTCTicks(milliseconds);
|
||||
//*(uint32_t*)RTC_CMR = readRTC_CCVR() + milliseconds;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::deepSleep(uint32_t millis) {
|
||||
sleep(millis);
|
||||
uint32_t ArduinoLowPowerClass::readRTC_CCVR()
|
||||
{
|
||||
return *(uint32_t*)RTC_CCVR;
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::setAlarmIn(uint32_t millis) {
|
||||
uint32_t ArduinoLowPowerClass::millisToRTCTicks(int milliseconds)
|
||||
{
|
||||
return (uint32_t)((double)milliseconds*32.768);
|
||||
}
|
||||
|
||||
//if (!rtc.isConfigured()) {
|
||||
// attachInterruptWakeup(RTC_ALARM_WAKEUP, NULL, 0);
|
||||
//}
|
||||
void ArduinoLowPowerClass::enableRTCInterrupt()
|
||||
{
|
||||
*(uint32_t*)RTC_MASK_INT &= 0xFFFFFFFF;
|
||||
*(uint32_t*)RTC_CCR |= 0x00000001;
|
||||
*(uint32_t*)RTC_CCR &= 0xFFFFFFFD;
|
||||
interrupt_disable(IRQ_RTC_INTR);
|
||||
interrupt_connect(IRQ_RTC_INTR , &PM_InterruptHandler);
|
||||
interrupt_enable(IRQ_RTC_INTR);
|
||||
}
|
||||
|
||||
//uint32_t now = rtc.getEpoch();
|
||||
//rtc.setAlarmEpoch(now + millis/1000);
|
||||
//rtc.enableAlarm(rtc.MATCH_HHMMSS);
|
||||
void ArduinoLowPowerClass::x86_C2Request()
|
||||
{
|
||||
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
|
||||
volatile uint32_t c2 = *(volatile uint32_t*)P_LVL2;
|
||||
|
||||
}
|
||||
|
||||
void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) {
|
||||
@ -337,8 +200,8 @@ void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callb
|
||||
// RTC library should call this API to enable the alarm subsystem
|
||||
switch (pin) {
|
||||
case RTC_ALARM_WAKEUP:
|
||||
//rtc.begin();
|
||||
//rtc.attachInterrupt(callback);
|
||||
attachWakeInterruptRTC(callback);
|
||||
break;
|
||||
case RESET_BUTTON_WAKEUP:
|
||||
gpio_cfg_data_t pin_cfg = {
|
||||
.gpio_type = GPIO_INTERRUPT,
|
||||
@ -351,6 +214,8 @@ void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callb
|
||||
soc_gpio_deconfig(SOC_GPIO_AON, 0);
|
||||
/* set RESET GPIO button to be an input */
|
||||
soc_gpio_set_config(SOC_GPIO_AON, 0, &pin_cfg);
|
||||
SET_PIN_PULLUP(32*3 + 8, 1);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
40
src/include/arc32/defines.h
Normal file
40
src/include/arc32/defines.h
Normal file
@ -0,0 +1,40 @@
|
||||
#define OSC0_CFG1 0xB0800008
|
||||
#define CCU_SS_PERIPH_CLK_GATE_CTL 0xB0800028
|
||||
#define CCU_SYS_CLK_CTL 0xB0800038
|
||||
#define CCU_LP_CLK_CTL 0xB080002C
|
||||
#define P_LVL2 0xB0800504
|
||||
#define PM1C 0xB0800518
|
||||
#define SLP_CFG 0xB0800550
|
||||
|
||||
#define USB_PLL_CFG0 0xB0800014
|
||||
#define USB_PHY_CFG0 0xB0800800
|
||||
|
||||
#define RTC_CCVR 0xB0000400
|
||||
#define RTC_CMR 0xB0000404
|
||||
#define RTC_CCR 0xB000040C
|
||||
#define RTC_EOI 0xB0000418
|
||||
#define RTC_MASK_INT 0xB0800478
|
||||
|
||||
#define OSCTRIM_ADDR 0xffffe1f8
|
||||
|
||||
#define SLEEP_HOST_C0 0
|
||||
#define SLEEP_HOST_C1 1
|
||||
#define SLEEP_HOST_C2 2
|
||||
#define SLEEP_HOST_C2_LP 3
|
||||
#define SLEEP_SS_SS0 4
|
||||
#define SLEEP_SS_SS1 5
|
||||
#define SLEEP_SS_SS2 6
|
||||
#define SLEEP_LPSS 7
|
||||
|
||||
/* Pin Muxing */
|
||||
#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 */
|
||||
#define SET_PULLUP_REG( mux_reg, enable, pin ) MMIO_REG_VAL(mux_reg) = ( MMIO_REG_VAL(mux_reg) & ~( 1 << (pin) ) ) | ( (enable) << (pin) )
|
||||
/* Calculate mux register address from pin number and calculate pin number within that register - call SET_MUX_REG */
|
||||
#define SET_PIN_PULLUP( pin_no, enable) SET_PULLUP_REG( ((((pin_no)/32)*4 )+ PULLUP_BASE), (enable), (pin_no) % 32)
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include <interrupt.h>
|
||||
#include <board.h>
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __POWER_STATES_H__
|
||||
#define __POWER_STATES_H__
|
||||
|
||||
/**
|
||||
* SoC Power mode control for Quark SE Microcontrollers.
|
||||
*
|
||||
* Available SoC states are:
|
||||
* - Low Power Sensing Standby (LPSS)
|
||||
* - Sleep
|
||||
*
|
||||
* LPSS can only be enabled from the Sensor core,
|
||||
* refer to @ref ss_power_soc_lpss_enable for further details.
|
||||
*
|
||||
* @defgroup groupSoCPower Quark SE SoC Power states
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enter SoC sleep state.
|
||||
*
|
||||
* Put the SoC into sleep state until next SoC wake event.
|
||||
*
|
||||
* - Core well is turned off
|
||||
* - Always on well is on
|
||||
* - Hybrid Clock is off
|
||||
* - RTC Clock is on
|
||||
*
|
||||
* Possible SoC wake events are:
|
||||
* - Low Power Comparator Interrupt
|
||||
* - AON GPIO Interrupt
|
||||
* - AON Timer Interrupt
|
||||
* - RTC Interrupt
|
||||
*/
|
||||
void power_soc_sleep(void);
|
||||
|
||||
/**
|
||||
* Enter SoC deep sleep state.
|
||||
*
|
||||
* Put the SoC into deep sleep state until next SoC wake event.
|
||||
*
|
||||
* - Core well is turned off
|
||||
* - Always on well is on
|
||||
* - Hybrid Clock is off
|
||||
* - RTC Clock is on
|
||||
*
|
||||
* Possible SoC wake events are:
|
||||
* - Low Power Comparator Interrupt
|
||||
* - AON GPIO Interrupt
|
||||
* - AON Timer Interrupt
|
||||
* - RTC Interrupt
|
||||
*
|
||||
* This function puts 1P8V regulators and 3P3V into Linear Mode.
|
||||
*/
|
||||
void power_soc_deep_sleep(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __POWER_STATES_H__ */
|
@ -1,673 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __SENSOR_REGISTERS_H__
|
||||
#define __SENSOR_REGISTERS_H__
|
||||
|
||||
/**
|
||||
* Quark SE SoC Sensor Subsystem Registers.
|
||||
*
|
||||
* For detailed description please read the SOC datasheet.
|
||||
*
|
||||
* @defgroup groupSSSEREG SoC Registers (Sensor Subsystem)
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define BIT(x) (1U << (x))
|
||||
|
||||
/* Bitwise OR operation macro for registers in the auxiliary memory space. */
|
||||
#define QM_SS_REG_AUX_OR(reg, mask) \
|
||||
(__builtin_arc_sr(__builtin_arc_lr(reg) | (mask), reg))
|
||||
/* Bitwise NAND operation macro for registers in the auxiliary memory space. */
|
||||
#define QM_SS_REG_AUX_NAND(reg, mask) \
|
||||
(__builtin_arc_sr(__builtin_arc_lr(reg) & (~(mask)), reg))
|
||||
|
||||
/* Sensor Subsystem status32 register. */
|
||||
#define QM_SS_AUX_STATUS32 (0xA)
|
||||
/** Interrupt priority threshold. */
|
||||
#define QM_SS_STATUS32_E_MASK (0x1E)
|
||||
/** Interrupt enable. */
|
||||
#define QM_SS_STATUS32_IE_MASK BIT(31)
|
||||
/* Sensor Subsystem control register. */
|
||||
#define QM_SS_AUX_IC_CTRL (0x11)
|
||||
/* Sensor Subsystem cache invalidate register. */
|
||||
#define QM_SS_AUX_IC_IVIL (0x19)
|
||||
/* Sensor Subsystem vector base register. */
|
||||
#define QM_SS_AUX_INT_VECTOR_BASE (0x25)
|
||||
|
||||
/**
|
||||
* @name SS Interrupt
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define QM_SS_EXCEPTION_NUM (16) /* Exceptions and traps in ARC EM core. */
|
||||
#define QM_SS_INT_TIMER_NUM (2) /* Internal interrupts in ARC EM core. */
|
||||
#define QM_SS_IRQ_SENSOR_NUM (18) /* IRQ's from the Sensor Subsystem. */
|
||||
#define QM_SS_IRQ_COMMON_NUM (32) /* IRQ's from the common SoC fabric. */
|
||||
#define QM_SS_INT_VECTOR_NUM \
|
||||
(QM_SS_EXCEPTION_NUM + QM_SS_INT_TIMER_NUM + QM_SS_IRQ_SENSOR_NUM + \
|
||||
QM_SS_IRQ_COMMON_NUM)
|
||||
#define QM_SS_IRQ_NUM (QM_SS_IRQ_SENSOR_NUM + QM_SS_IRQ_COMMON_NUM)
|
||||
|
||||
/**
|
||||
* SS IRQ context type.
|
||||
*
|
||||
* Applications should not modify the content.
|
||||
* This structure is only intended to be used by
|
||||
* qm_irq_save_context and qm_irq_restore_context functions.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t status32_irq_threshold; /**< STATUS32 Interrupt Threshold. */
|
||||
uint32_t status32_irq_enable; /**< STATUS32 Interrupt Enable. */
|
||||
uint32_t irq_ctrl; /**< Interrupt Context Saving Control Register. */
|
||||
|
||||
/**
|
||||
* IRQ configuration:
|
||||
* - IRQ Priority:BIT(6):BIT(2)
|
||||
* - IRQ Trigger:BIT(1)
|
||||
* - IRQ Enable:BIT(0)
|
||||
*/
|
||||
uint8_t irq_config[QM_SS_INT_VECTOR_NUM - 1];
|
||||
} qm_irq_context_t;
|
||||
|
||||
/** General Purpose register map. */
|
||||
typedef struct {
|
||||
volatile uint32_t gps0; /**< General Purpose Sticky Register 0 */
|
||||
volatile uint32_t gps1; /**< General Purpose Sticky Register 1 */
|
||||
volatile uint32_t gps2; /**< General Purpose Sticky Register 2 */
|
||||
volatile uint32_t gps3; /**< General Purpose Sticky Register 3 */
|
||||
volatile uint32_t reserved;
|
||||
volatile uint32_t gp0; /**< General Purpose Scratchpad Register 0 */
|
||||
volatile uint32_t gp1; /**< General Purpose Scratchpad Register 1 */
|
||||
volatile uint32_t gp2; /**< General Purpose Scratchpad Register 2 */
|
||||
volatile uint32_t gp3; /**< General Purpose Scratchpad Register 3 */
|
||||
volatile uint32_t reserved1;
|
||||
volatile uint32_t id; /**< Identification Register */
|
||||
volatile uint32_t rev; /**< Revision Register */
|
||||
volatile uint32_t wo_sp; /**< Write-One-to-Set Scratchpad Register */
|
||||
volatile uint32_t
|
||||
wo_st; /**< Write-One-to-Set Sticky Scratchpad Register */
|
||||
} qm_scss_gp_reg_t;
|
||||
|
||||
#define QM_SCSS_GP_BASE (0xB0800100)
|
||||
#define QM_SCSS_GP ((qm_scss_gp_reg_t *)QM_SCSS_GP_BASE)
|
||||
|
||||
/* The GPS0 register usage. */
|
||||
#define QM_GPS0_BIT_FM (0) /**< Start Firmware Manager. */
|
||||
#define QM_GPS0_BIT_X86_WAKEUP (1) /**< Lakemont core reset type. */
|
||||
#define QM_GPS0_BIT_SENSOR_WAKEUP (2) /**< Sensor core reset type. */
|
||||
|
||||
/** System Core register map. */
|
||||
typedef struct {
|
||||
volatile uint32_t osc0_cfg0; /**< Hybrid Oscillator Configuration 0. */
|
||||
volatile uint32_t osc0_stat1; /**< Hybrid Oscillator status 1. */
|
||||
volatile uint32_t osc0_cfg1; /**< Hybrid Oscillator configuration 1. */
|
||||
volatile uint32_t osc1_stat0; /**< RTC Oscillator status 0. */
|
||||
volatile uint32_t osc1_cfg0; /**< RTC Oscillator Configuration 0. */
|
||||
volatile uint32_t usb_pll_cfg0; /**< USB Phase lock look configuration. */
|
||||
volatile uint32_t
|
||||
ccu_periph_clk_gate_ctl; /**< Peripheral Clock Gate Control. */
|
||||
volatile uint32_t
|
||||
ccu_periph_clk_div_ctl0; /**< Peripheral Clock Divider Control. 0 */
|
||||
volatile uint32_t
|
||||
ccu_gpio_db_clk_ctl; /**< Peripheral Clock Divider Control 1. */
|
||||
volatile uint32_t
|
||||
ccu_ext_clock_ctl; /**< External Clock Control Register. */
|
||||
/** Sensor Subsystem peripheral clock gate control. */
|
||||
volatile uint32_t ccu_ss_periph_clk_gate_ctl;
|
||||
volatile uint32_t ccu_lp_clk_ctl; /**< System Low Power Clock Control. */
|
||||
volatile uint32_t reserved;
|
||||
volatile uint32_t ccu_mlayer_ahb_ctl; /**< AHB Control Register. */
|
||||
volatile uint32_t ccu_sys_clk_ctl; /**< System Clock Control Register. */
|
||||
volatile uint32_t osc_lock_0; /**< Clocks Lock Register. */
|
||||
} qm_scss_ccu_reg_t;
|
||||
|
||||
#define QM_SCSS_CCU ((qm_scss_ccu_reg_t *)SCSS_REGISTER_BASE)
|
||||
|
||||
/** Power Management register map. */
|
||||
typedef struct {
|
||||
volatile uint32_t p_lvl2; /**< Processor level 2 */
|
||||
volatile uint32_t reserved[4];
|
||||
volatile uint32_t pm1c; /**< Power management 1 control */
|
||||
volatile uint32_t reserved1[9];
|
||||
volatile uint32_t aon_vr; /**< AON Voltage Regulator */
|
||||
volatile uint32_t plat3p3_vr; /**< Platform 3p3 voltage regulator */
|
||||
volatile uint32_t plat1p8_vr; /**< Platform 1p8 voltage regulator */
|
||||
volatile uint32_t host_vr; /**< Host Voltage Regulator */
|
||||
volatile uint32_t slp_cfg; /**< Sleeping Configuration */
|
||||
/** Power Management Network (PMNet) Control and Status */
|
||||
volatile uint32_t pmnetcs;
|
||||
volatile uint32_t pm_wait; /**< Power Management Wait */
|
||||
volatile uint32_t reserved2;
|
||||
volatile uint32_t p_sts; /**< Processor Status */
|
||||
volatile uint32_t reserved3[3];
|
||||
volatile uint32_t rstc; /**< Reset Control */
|
||||
volatile uint32_t rsts; /**< Reset Status */
|
||||
volatile uint32_t reserved4[6];
|
||||
volatile uint32_t vr_lock; /**< Voltage regulator lock */
|
||||
volatile uint32_t pm_lock; /**< Power Management Lock */
|
||||
} qm_scss_pmu_reg_t;
|
||||
|
||||
#define QM_SCSS_PMU_BASE (0xB0800504)
|
||||
#define QM_SCSS_PMU ((qm_scss_pmu_reg_t *)QM_SCSS_PMU_BASE)
|
||||
|
||||
#define QM_SS_CFG_ARC_RUN_REQ_A BIT(24)
|
||||
#define QM_P_STS_HALT_INTERRUPT_REDIRECTION BIT(26)
|
||||
#define QM_P_STS_ARC_HALT BIT(14)
|
||||
|
||||
#define QM_AON_VR_VSEL_MASK (0xFFE0)
|
||||
#define QM_AON_VR_VSEL_1V2 (0x8)
|
||||
#define QM_AON_VR_VSEL_1V35 (0xB)
|
||||
#define QM_AON_VR_VSEL_1V8 (0x10)
|
||||
#define QM_AON_VR_EN BIT(7)
|
||||
#define QM_AON_VR_VSTRB BIT(5)
|
||||
|
||||
#define QM_SCSS_SLP_CFG_LPMODE_EN BIT(8)
|
||||
#define QM_SCSS_SLP_CFG_RTC_DIS BIT(7)
|
||||
#define QM_SCSS_PM1C_SLPEN BIT(13)
|
||||
#define QM_SCSS_HOST_VR_EN BIT(7)
|
||||
#define QM_SCSS_PLAT3P3_VR_EN BIT(7)
|
||||
#define QM_SCSS_PLAT1P8_VR_EN BIT(7)
|
||||
#define QM_SCSS_HOST_VR_VREG_SEL BIT(6)
|
||||
#define QM_SCSS_PLAT3P3_VR_VREG_SEL BIT(6)
|
||||
#define QM_SCSS_PLAT1P8_VR_VREG_SEL BIT(6)
|
||||
#define QM_SCSS_VR_ROK BIT(10)
|
||||
#define QM_SCSS_VR_EN BIT(7)
|
||||
#define QM_SCSS_VR_VREG_SEL BIT(6)
|
||||
|
||||
#define QM_SCSS_CCU_SS_LPS_EN BIT(0)
|
||||
|
||||
typedef enum {
|
||||
QM_SS_IRQ_LEVEL_SENSITIVE = 0,
|
||||
QM_SS_IRQ_EDGE_SENSITIVE = 1
|
||||
} qm_ss_irq_trigger_t;
|
||||
|
||||
#define QM_SS_AUX_IRQ_CTRL (0xE)
|
||||
#define QM_SS_AUX_IRQ_HINT (0x201)
|
||||
#define QM_SS_AUX_IRQ_PRIORITY (0x206)
|
||||
#define QM_SS_AUX_IRQ_STATUS (0x406)
|
||||
#define QM_SS_AUX_IRQ_SELECT (0x40B)
|
||||
#define QM_SS_AUX_IRQ_ENABLE (0x40C)
|
||||
#define QM_SS_AUX_IRQ_TRIGGER (0x40D)
|
||||
|
||||
/** Always-On Timer Interrupt. */
|
||||
#define QM_IRQ_AONPT_0_INT 28
|
||||
#define QM_IRQ_AONPT_0_INT_MASK_OFFSET 32
|
||||
#define QM_IRQ_AONPT_0_INT_VECTOR 64
|
||||
|
||||
/** RTC Single Interrupt. */
|
||||
#define QM_IRQ_RTC_0_INT 11
|
||||
#define QM_IRQ_RTC_0_INT_MASK_OFFSET 12
|
||||
#define QM_IRQ_RTC_0_INT_VECTOR 47
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SS Timer
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
QM_SS_TIMER_COUNT = 0,
|
||||
QM_SS_TIMER_CONTROL,
|
||||
QM_SS_TIMER_LIMIT
|
||||
} qm_ss_timer_reg_t;
|
||||
|
||||
/**
|
||||
* Sensor Subsystem Timers.
|
||||
*/
|
||||
typedef enum { QM_SS_TIMER_0 = 0, QM_SS_TIMER_NUM } qm_ss_timer_t;
|
||||
|
||||
/*
|
||||
* SS TIMER context type.
|
||||
*
|
||||
* Application should not modify the content.
|
||||
* This structure is only intended to be used by the qm_ss_timer_save_context
|
||||
* and qm_ss_timer_restore_context functions.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t timer_count; /**< Timer count. */
|
||||
uint32_t timer_control; /**< Timer control. */
|
||||
uint32_t timer_limit; /**< Timer limit. */
|
||||
} qm_ss_timer_context_t;
|
||||
|
||||
#define QM_SS_TIMER_0_BASE (0x21)
|
||||
#define QM_SS_TIMER_1_BASE (0x100)
|
||||
#define QM_SS_TSC_BASE QM_SS_TIMER_1_BASE
|
||||
|
||||
#define QM_SS_TIMER_CONTROL_INT_EN_OFFSET (0)
|
||||
#define QM_SS_TIMER_CONTROL_NON_HALTED_OFFSET (1)
|
||||
#define QM_SS_TIMER_CONTROL_WATCHDOG_OFFSET (2)
|
||||
#define QM_SS_TIMER_CONTROL_INT_PENDING_OFFSET (3)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* GPIO registers and definitions.
|
||||
*
|
||||
* @name SS GPIO
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Sensor Subsystem GPIO register block type. */
|
||||
typedef enum {
|
||||
QM_SS_GPIO_SWPORTA_DR = 0,
|
||||
QM_SS_GPIO_SWPORTA_DDR,
|
||||
QM_SS_GPIO_INTEN = 3,
|
||||
QM_SS_GPIO_INTMASK,
|
||||
QM_SS_GPIO_INTTYPE_LEVEL,
|
||||
QM_SS_GPIO_INT_POLARITY,
|
||||
QM_SS_GPIO_INTSTATUS,
|
||||
QM_SS_GPIO_DEBOUNCE,
|
||||
QM_SS_GPIO_PORTA_EOI,
|
||||
QM_SS_GPIO_EXT_PORTA,
|
||||
QM_SS_GPIO_LS_SYNC
|
||||
} qm_ss_gpio_reg_t;
|
||||
|
||||
/**
|
||||
* SS GPIO context type.
|
||||
*
|
||||
* Application should not modify the content.
|
||||
* This structure is only intended to be used by the qm_ss_gpio_save_context and
|
||||
* qm_ss_gpio_restore_context functions.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t gpio_swporta_dr; /**< Port A Data. */
|
||||
uint32_t gpio_swporta_ddr; /**< Port A Data Direction. */
|
||||
uint32_t gpio_inten; /**< Interrupt Enable. */
|
||||
uint32_t gpio_intmask; /**< Interrupt Mask. */
|
||||
uint32_t gpio_inttype_level; /**< Interrupt Type. */
|
||||
uint32_t gpio_int_polarity; /**< Interrupt Polarity. */
|
||||
uint32_t gpio_debounce; /**< Debounce Enable. */
|
||||
uint32_t gpio_ls_sync; /**< Synchronization Level. */
|
||||
} qm_ss_gpio_context_t;
|
||||
|
||||
#define QM_SS_GPIO_NUM_PINS (16)
|
||||
#define QM_SS_GPIO_LS_SYNC_CLK_EN BIT(31)
|
||||
#define QM_SS_GPIO_LS_SYNC_SYNC_LVL BIT(0)
|
||||
|
||||
/** Sensor Subsystem GPIO. */
|
||||
typedef enum { QM_SS_GPIO_0 = 0, QM_SS_GPIO_1, QM_SS_GPIO_NUM } qm_ss_gpio_t;
|
||||
|
||||
#define QM_SS_GPIO_0_BASE (0x80017800)
|
||||
#define QM_SS_GPIO_1_BASE (0x80017900)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* I2C registers and definitions.
|
||||
*
|
||||
* @name SS I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Sensor Subsystem I2C register block type. */
|
||||
typedef enum {
|
||||
QM_SS_I2C_CON = 0,
|
||||
QM_SS_I2C_DATA_CMD,
|
||||
QM_SS_I2C_SS_SCL_CNT,
|
||||
QM_SS_I2C_FS_SCL_CNT = 0x04,
|
||||
QM_SS_I2C_INTR_STAT = 0x06,
|
||||
QM_SS_I2C_INTR_MASK,
|
||||
QM_SS_I2C_TL,
|
||||
QM_SS_I2C_INTR_CLR = 0x0A,
|
||||
QM_SS_I2C_STATUS,
|
||||
QM_SS_I2C_TXFLR,
|
||||
QM_SS_I2C_RXFLR,
|
||||
QM_SS_I2C_SDA_CONFIG,
|
||||
QM_SS_I2C_TX_ABRT_SOURCE,
|
||||
QM_SS_I2C_ENABLE_STATUS = 0x11
|
||||
} qm_ss_i2c_reg_t;
|
||||
|
||||
/**
|
||||
* SS I2C context type.
|
||||
*
|
||||
* Application should not modify the content.
|
||||
* This structure is only intended to be used by the qm_ss_gpio_save_context and
|
||||
* qm_ss_gpio_restore_context functions.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t i2c_con;
|
||||
uint32_t i2c_ss_scl_cnt;
|
||||
uint32_t i2c_fs_scl_cnt;
|
||||
} qm_ss_i2c_context_t;
|
||||
|
||||
#define QM_SS_I2C_CON_ENABLE BIT(0)
|
||||
#define QM_SS_I2C_CON_ABORT BIT(1)
|
||||
#define QM_SS_I2C_CON_SPEED_SS BIT(3)
|
||||
#define QM_SS_I2C_CON_SPEED_FS BIT(4)
|
||||
#define QM_SS_I2C_CON_SPEED_MASK (0x18)
|
||||
#define QM_SS_I2C_CON_IC_10BITADDR BIT(5)
|
||||
#define QM_SS_I2C_CON_IC_10BITADDR_OFFSET (5)
|
||||
#define QM_SS_I2C_CON_IC_10BITADDR_MASK (5)
|
||||
#define QM_SS_I2C_CON_RESTART_EN BIT(7)
|
||||
#define QM_SS_I2C_CON_TAR_SAR_OFFSET (9)
|
||||
#define QM_SS_I2C_CON_TAR_SAR_MASK (0x7FE00)
|
||||
#define QM_SS_I2C_CON_TAR_SAR_10_BIT_MASK (0x3FF)
|
||||
#define QM_SS_I2C_CON_SPKLEN_OFFSET (22)
|
||||
#define QM_SS_I2C_CON_SPKLEN_MASK (0x3FC00000)
|
||||
#define QM_SS_I2C_CON_CLK_ENA BIT(31)
|
||||
|
||||
#define QM_SS_I2C_DATA_CMD_CMD BIT(8)
|
||||
#define QM_SS_I2C_DATA_CMD_STOP BIT(9)
|
||||
#define QM_SS_I2C_DATA_CMD_PUSH (0xC0000000)
|
||||
#define QM_SS_I2C_DATA_CMD_POP (0x80000000)
|
||||
|
||||
#define QM_SS_I2C_SS_FS_SCL_CNT_HCNT_OFFSET (16)
|
||||
#define QM_SS_I2C_SS_FS_SCL_CNT_16BIT_MASK (0xFFFF)
|
||||
|
||||
#define QM_SS_I2C_INTR_STAT_RX_UNDER BIT(0)
|
||||
#define QM_SS_I2C_INTR_STAT_RX_OVER BIT(1)
|
||||
#define QM_SS_I2C_INTR_STAT_RX_FULL BIT(2)
|
||||
#define QM_SS_I2C_INTR_STAT_TX_OVER BIT(3)
|
||||
#define QM_SS_I2C_INTR_STAT_TX_EMPTY BIT(4)
|
||||
#define QM_SS_I2C_INTR_STAT_TX_ABRT BIT(6)
|
||||
|
||||
#define QM_SS_I2C_INTR_MASK_ALL (0x0)
|
||||
#define QM_SS_I2C_INTR_MASK_RX_UNDER BIT(0)
|
||||
#define QM_SS_I2C_INTR_MASK_RX_OVER BIT(1)
|
||||
#define QM_SS_I2C_INTR_MASK_RX_FULL BIT(2)
|
||||
#define QM_SS_I2C_INTR_MASK_TX_OVER BIT(3)
|
||||
#define QM_SS_I2C_INTR_MASK_TX_EMPTY BIT(4)
|
||||
#define QM_SS_I2C_INTR_MASK_TX_ABRT BIT(6)
|
||||
|
||||
#define QM_SS_I2C_TL_TX_TL_OFFSET (16)
|
||||
#define QM_SS_I2C_TL_RX_TL_MASK (0xFF)
|
||||
#define QM_SS_I2C_TL_TX_TL_MASK (0xFF0000)
|
||||
|
||||
#define QM_SS_I2C_INTR_CLR_ALL (0xFF)
|
||||
#define QM_SS_I2C_INTR_CLR_TX_ABRT BIT(6)
|
||||
|
||||
#define QM_SS_I2C_TX_ABRT_SOURCE_NAK_MASK (0x09)
|
||||
#define QM_SS_I2C_TX_ABRT_SOURCE_ALL_MASK (0x1FFFF)
|
||||
#define QM_SS_I2C_TX_ABRT_SBYTE_NORSTRT BIT(9)
|
||||
#define QM_SS_I2C_TX_ABRT_SOURCE_ART_LOST BIT(12)
|
||||
|
||||
#define QM_SS_I2C_ENABLE_CONTROLLER_EN BIT(0)
|
||||
#define QM_SS_I2C_ENABLE_STATUS_IC_EN BIT(0)
|
||||
|
||||
#define QM_SS_I2C_STATUS_BUSY_MASK (0x21)
|
||||
#define QM_SS_I2C_STATUS_RFNE BIT(3)
|
||||
#define QM_SS_I2C_STATUS_TFE BIT(2)
|
||||
#define QM_SS_I2C_STATUS_TFNF BIT(1)
|
||||
|
||||
#define QM_SS_I2C_IC_LCNT_MAX (65525)
|
||||
#define QM_SS_I2C_IC_LCNT_MIN (8)
|
||||
#define QM_SS_I2C_IC_HCNT_MAX (65525)
|
||||
#define QM_SS_I2C_IC_HCNT_MIN (6)
|
||||
|
||||
#define QM_SS_I2C_FIFO_SIZE (8)
|
||||
|
||||
/** Sensor Subsystem I2C */
|
||||
typedef enum { QM_SS_I2C_0 = 0, QM_SS_I2C_1, QM_SS_I2C_NUM } qm_ss_i2c_t;
|
||||
|
||||
#define QM_SS_I2C_0_BASE (0x80012000)
|
||||
#define QM_SS_I2C_1_BASE (0x80012100)
|
||||
|
||||
/** @} */
|
||||
/** Sensor Subsystem ADC @{*/
|
||||
|
||||
/** Sensor Subsystem ADC registers */
|
||||
typedef enum {
|
||||
QM_SS_ADC_SET = 0, /**< ADC and sequencer settings register. */
|
||||
QM_SS_ADC_DIVSEQSTAT, /**< ADC clock and sequencer status register. */
|
||||
QM_SS_ADC_SEQ, /**< ADC sequence entry register. */
|
||||
QM_SS_ADC_CTRL, /**< ADC control register. */
|
||||
QM_SS_ADC_INTSTAT, /**< ADC interrupt status register. */
|
||||
QM_SS_ADC_SAMPLE /**< ADC sample register. */
|
||||
} qm_ss_adc_reg_t;
|
||||
|
||||
/** Sensor Subsystem ADC */
|
||||
typedef enum {
|
||||
QM_SS_ADC_0 = 0, /**< ADC first module. */
|
||||
QM_SS_ADC_NUM
|
||||
} qm_ss_adc_t;
|
||||
|
||||
/**
|
||||
* SS ADC context type.
|
||||
*
|
||||
* The application should not modify the content of this structure.
|
||||
*
|
||||
* This structure is intented to be used by qm_ss_adc_save_context and
|
||||
* qm_ss_adc_restore_context functions only.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t adc_set; /**< ADC settings. */
|
||||
uint32_t adc_divseqstat; /**< ADC clock divider and sequencer status. */
|
||||
uint32_t adc_seq; /**< ADC sequencer entry. */
|
||||
uint32_t adc_ctrl; /**< ADC control. */
|
||||
} qm_ss_adc_context_t;
|
||||
|
||||
/* SS ADC register base. */
|
||||
#define QM_SS_ADC_BASE (0x80015000)
|
||||
|
||||
/* For 1MHz, the max divisor is 7. */
|
||||
#define QM_SS_ADC_DIV_MAX (7)
|
||||
|
||||
#define QM_SS_ADC_FIFO_LEN (32)
|
||||
|
||||
#define QM_SS_ADC_SET_POP_RX BIT(31)
|
||||
#define QM_SS_ADC_SET_FLUSH_RX BIT(30)
|
||||
#define QM_SS_ADC_SET_THRESHOLD_MASK (0x3F000000)
|
||||
#define QM_SS_ADC_SET_THRESHOLD_OFFSET (24)
|
||||
#define QM_SS_ADC_SET_SEQ_ENTRIES_MASK (0x3F0000)
|
||||
#define QM_SS_ADC_SET_SEQ_ENTRIES_OFFSET (16)
|
||||
#define QM_SS_ADC_SET_SEQ_MODE BIT(13)
|
||||
#define QM_SS_ADC_SET_SAMPLE_WIDTH_MASK (0x1F)
|
||||
|
||||
#define QM_SS_ADC_DIVSEQSTAT_CLK_RATIO_MASK (0x1FFFFF)
|
||||
|
||||
#define QM_SS_ADC_CTRL_CLR_SEQERROR BIT(19)
|
||||
#define QM_SS_ADC_CTRL_CLR_UNDERFLOW BIT(18)
|
||||
#define QM_SS_ADC_CTRL_CLR_OVERFLOW BIT(17)
|
||||
#define QM_SS_ADC_CTRL_CLR_DATA_A BIT(16)
|
||||
#define QM_SS_ADC_CTRL_MSK_SEQERROR BIT(11)
|
||||
#define QM_SS_ADC_CTRL_MSK_UNDERFLOW BIT(10)
|
||||
#define QM_SS_ADC_CTRL_MSK_OVERFLOW BIT(9)
|
||||
#define QM_SS_ADC_CTRL_MSK_DATA_A BIT(8)
|
||||
#define QM_SS_ADC_CTRL_SEQ_TABLE_RST BIT(6)
|
||||
#define QM_SS_ADC_CTRL_SEQ_PTR_RST BIT(5)
|
||||
#define QM_SS_ADC_CTRL_SEQ_START BIT(4)
|
||||
#define QM_SS_ADC_CTRL_CLK_ENA BIT(2)
|
||||
#define QM_SS_ADC_CTRL_ADC_ENA BIT(1)
|
||||
|
||||
#define QM_SS_ADC_CTRL_MSK_ALL_INT (0xF00)
|
||||
#define QM_SS_ADC_CTRL_CLR_ALL_INT (0xF0000)
|
||||
|
||||
#define QM_SS_ADC_SEQ_DELAYODD_OFFSET (21)
|
||||
#define QM_SS_ADC_SEQ_MUXODD_OFFSET (16)
|
||||
#define QM_SS_ADC_SEQ_DELAYEVEN_OFFSET (5)
|
||||
|
||||
#define QM_SS_ADC_SEQ_DUMMY (0x480)
|
||||
|
||||
#define QM_SS_ADC_INTSTAT_SEQERROR BIT(3)
|
||||
#define QM_SS_ADC_INTSTAT_UNDERFLOW BIT(2)
|
||||
#define QM_SS_ADC_INTSTAT_OVERFLOW BIT(1)
|
||||
#define QM_SS_ADC_INTSTAT_DATA_A BIT(0)
|
||||
|
||||
/** End of Sensor Subsystem ADC @}*/
|
||||
|
||||
/**
|
||||
* CREG Registers.
|
||||
*
|
||||
* @name SS CREG
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Sensor Subsystem CREG */
|
||||
typedef enum {
|
||||
QM_SS_IO_CREG_MST0_CTRL = 0x0, /**< Master control register. */
|
||||
QM_SS_IO_CREG_SLV0_OBSR = 0x80, /**< Slave control register. */
|
||||
QM_SS_IO_CREG_SLV1_OBSR = 0x180 /**< Slave control register. */
|
||||
} qm_ss_creg_reg_t;
|
||||
|
||||
/* MST0_CTRL fields */
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_PWR_MODE_OFFSET (1)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_PWR_MODE_MASK (0x7)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_DELAY_OFFSET (3)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_DELAY_MASK (0xFFF8)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_REQ BIT(16)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_CMD_OFFSET (17)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_CMD_MASK (0xE0000)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_OFFSET (20)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_MASK (0x7F00000)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_MAX (0x7F)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE BIT(27)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE BIT(28)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE BIT(29)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE BIT(30)
|
||||
#define QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE BIT(31)
|
||||
/* SLV0_OBSR fields */
|
||||
#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_VAL_OFFSET (5)
|
||||
#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_VAL_MASK (0xFE0)
|
||||
#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_ACK BIT(4)
|
||||
#define QM_SS_IO_CREG_SLV0_OBSR_ADC_PWR_MODE_STS BIT(3)
|
||||
|
||||
#define SS_CLK_PERIPH_ALL_IN_CREG \
|
||||
(SS_CLK_PERIPH_ADC | SS_CLK_PERIPH_I2C_1 | SS_CLK_PERIPH_I2C_0 | \
|
||||
SS_CLK_PERIPH_SPI_1 | SS_CLK_PERIPH_SPI_0)
|
||||
|
||||
/* SS CREG base. */
|
||||
#define QM_SS_CREG_BASE (0x80018000)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* I2C registers and definitions.
|
||||
*
|
||||
* @name SS SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Sensor Subsystem SPI register map. */
|
||||
typedef enum {
|
||||
QM_SS_SPI_CTRL = 0, /**< SPI control register. */
|
||||
QM_SS_SPI_SPIEN = 2, /**< SPI enable register. */
|
||||
QM_SS_SPI_TIMING = 4, /**< SPI serial clock divider value. */
|
||||
QM_SS_SPI_FTLR, /**< Threshold value for TX/RX FIFO. */
|
||||
QM_SS_SPI_TXFLR = 7, /**< Number of valid data entries in TX FIFO. */
|
||||
QM_SS_SPI_RXFLR, /**< Number of valid data entries in RX FIFO. */
|
||||
QM_SS_SPI_SR, /**< SPI status register. */
|
||||
QM_SS_SPI_INTR_STAT, /**< Interrupt status register. */
|
||||
QM_SS_SPI_INTR_MASK, /**< Interrupt mask register. */
|
||||
QM_SS_SPI_CLR_INTR, /**< Interrupt clear register. */
|
||||
QM_SS_SPI_DR, /**< RW buffer for FIFOs. */
|
||||
} qm_ss_spi_reg_t;
|
||||
|
||||
/**
|
||||
* Sensor Subsystem SPI context type.
|
||||
*
|
||||
* Applications should not modify the content.
|
||||
* This structure is only intended to be used by
|
||||
* the qm_ss_spi_save_context and qm_ss_spi_restore_context functions.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t spi_ctrl; /**< Control Register. */
|
||||
uint32_t spi_spien; /**< SPI Enable Register. */
|
||||
uint32_t spi_timing; /**< Timing Register. */
|
||||
} qm_ss_spi_context_t;
|
||||
|
||||
/** Sensor Subsystem SPI modules. */
|
||||
typedef enum {
|
||||
QM_SS_SPI_0 = 0, /**< SPI module 0 */
|
||||
QM_SS_SPI_1, /**< SPI module 1 */
|
||||
QM_SS_SPI_NUM
|
||||
} qm_ss_spi_t;
|
||||
|
||||
#define QM_SS_SPI_0_BASE (0x80010000)
|
||||
#define QM_SS_SPI_1_BASE (0x80010100)
|
||||
|
||||
#define QM_SS_SPI_CTRL_DFS_OFFS (0)
|
||||
#define QM_SS_SPI_CTRL_DFS_MASK (0x0000000F)
|
||||
#define QM_SS_SPI_CTRL_BMOD_OFFS (6)
|
||||
#define QM_SS_SPI_CTRL_BMOD_MASK (0x000000C0)
|
||||
#define QM_SS_SPI_CTRL_SCPH BIT(6)
|
||||
#define QM_SS_SPI_CTRL_SCPOL BIT(7)
|
||||
#define QM_SS_SPI_CTRL_TMOD_OFFS (8)
|
||||
#define QM_SS_SPI_CTRL_TMOD_MASK (0x00000300)
|
||||
#define QM_SS_SPI_CTRL_SRL BIT(11)
|
||||
#define QM_SS_SPI_CTRL_CLK_ENA BIT(15)
|
||||
#define QM_SS_SPI_CTRL_NDF_OFFS (16)
|
||||
#define QM_SS_SPI_CTRL_NDF_MASK (0xFFFF0000)
|
||||
|
||||
#define QM_SS_SPI_SPIEN_EN BIT(0)
|
||||
#define QM_SS_SPI_SPIEN_SER_OFFS (4)
|
||||
#define QM_SS_SPI_SPIEN_SER_MASK (0x000000F0)
|
||||
|
||||
#define QM_SS_SPI_TIMING_SCKDV_OFFS (0)
|
||||
#define QM_SS_SPI_TIMING_SCKDV_MASK (0x0000FFFF)
|
||||
#define QM_SS_SPI_TIMING_RSD_OFFS (16)
|
||||
#define QM_SS_SPI_TIMING_RSD_MASK (0x00FF0000)
|
||||
|
||||
#define QM_SS_SPI_FTLR_RFT_OFFS (0)
|
||||
#define QM_SS_SPI_FTLR_RFT_MASK (0x0000FFFF)
|
||||
#define QM_SS_SPI_FTLR_TFT_OFFS (16)
|
||||
#define QM_SS_SPI_FTLR_TFT_MASK (0xFFFF0000)
|
||||
|
||||
#define QM_SS_SPI_SR_BUSY BIT(0)
|
||||
#define QM_SS_SPI_SR_TFNF BIT(1)
|
||||
#define QM_SS_SPI_SR_TFE BIT(2)
|
||||
#define QM_SS_SPI_SR_RFNE BIT(3)
|
||||
#define QM_SS_SPI_SR_RFF BIT(4)
|
||||
|
||||
#define QM_SS_SPI_INTR_TXEI BIT(0)
|
||||
#define QM_SS_SPI_INTR_TXOI BIT(1)
|
||||
#define QM_SS_SPI_INTR_RXUI BIT(2)
|
||||
#define QM_SS_SPI_INTR_RXOI BIT(3)
|
||||
#define QM_SS_SPI_INTR_RXFI BIT(4)
|
||||
#define QM_SS_SPI_INTR_ALL (0x0000001F)
|
||||
|
||||
#define QM_SS_SPI_INTR_STAT_TXEI QM_SS_SPI_INTR_TXEI
|
||||
#define QM_SS_SPI_INTR_STAT_TXOI QM_SS_SPI_INTR_TXOI
|
||||
#define QM_SS_SPI_INTR_STAT_RXUI QM_SS_SPI_INTR_RXUI
|
||||
#define QM_SS_SPI_INTR_STAT_RXOI QM_SS_SPI_INTR_RXOI
|
||||
#define QM_SS_SPI_INTR_STAT_RXFI QM_SS_SPI_INTR_RXFI
|
||||
|
||||
#define QM_SS_SPI_INTR_MASK_TXEI QM_SS_SPI_INTR_TXEI
|
||||
#define QM_SS_SPI_INTR_MASK_TXOI QM_SS_SPI_INTR_TXOI
|
||||
#define QM_SS_SPI_INTR_MASK_RXUI QM_SS_SPI_INTR_RXUI
|
||||
#define QM_SS_SPI_INTR_MASK_RXOI QM_SS_SPI_INTR_RXOI
|
||||
#define QM_SS_SPI_INTR_MASK_RXFI QM_SS_SPI_INTR_RXFI
|
||||
|
||||
#define QM_SS_SPI_CLR_INTR_TXEI QM_SS_SPI_INTR_TXEI
|
||||
#define QM_SS_SPI_CLR_INTR_TXOI QM_SS_SPI_INTR_TXOI
|
||||
#define QM_SS_SPI_CLR_INTR_RXUI QM_SS_SPI_INTR_RXUI
|
||||
#define QM_SS_SPI_CLR_INTR_RXOI QM_SS_SPI_INTR_RXOI
|
||||
#define QM_SS_SPI_CLR_INTR_RXFI QM_SS_SPI_INTR_RXFI
|
||||
|
||||
#define QM_SS_SPI_DR_DR_OFFS (0)
|
||||
#define QM_SS_SPI_DR_DR_MASK (0x0000FFFF)
|
||||
#define QM_SS_SPI_DR_WR BIT(30)
|
||||
#define QM_SS_SPI_DR_STROBE BIT(31)
|
||||
#define QM_SS_SPI_DR_W_MASK (0xc0000000)
|
||||
#define QM_SS_SPI_DR_R_MASK (0x80000000)
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
||||
#endif /* __SENSOR_REGISTERS_H__ */
|
@ -1,295 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __QM_SS_POWER_STATES_H__
|
||||
#define __QM_SS_POWER_STATES_H__
|
||||
|
||||
#include "qm_sensor_regs.h"
|
||||
|
||||
/**
|
||||
* SS Power mode control for Quark SE Microcontrollers.
|
||||
*
|
||||
* @defgroup groupSSPower SS Power states
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sensor Subsystem SS1 Timers mode type.
|
||||
*/
|
||||
typedef enum {
|
||||
SS_POWER_CPU_SS1_TIMER_OFF = 0, /**< Disable SS Timers in SS1. */
|
||||
SS_POWER_CPU_SS1_TIMER_ON /**< Keep SS Timers enabled in SS1. */
|
||||
} ss_power_cpu_ss1_mode_t;
|
||||
|
||||
/**
|
||||
* Enable LPSS state entry.
|
||||
*
|
||||
* Put the SoC into LPSS on next C2/C2LP and SS2 state combination.<BR>
|
||||
* This function needs to be called on the Sensor Core to
|
||||
* Clock Gate ADC, I2C0, I2C1, SPI0 and SPI1 sensor peripherals.<BR>
|
||||
* Clock Gating sensor peripherals is a requirement to enter LPSS state.<BR>
|
||||
* After LPSS, ss_power_soc_lpss_disable needs to be called to
|
||||
* restore clock gating.<BR>
|
||||
*
|
||||
* This needs to be called before any transition to C2/C2LP and SS2
|
||||
* in order to enter LPSS.<BR>
|
||||
* SoC Hybrid Clock is gated in this state.<BR>
|
||||
* Core Well Clocks are gated.<BR>
|
||||
* RTC is the only clock running.
|
||||
*
|
||||
* Possible SoC wake events are:
|
||||
* - Low Power Comparator Interrupt
|
||||
* - AON GPIO Interrupt
|
||||
* - AON Timer Interrupt
|
||||
* - RTC Interrupt
|
||||
*/
|
||||
//void ss_power_soc_lpss_enable(void);
|
||||
|
||||
/**
|
||||
* Enter SoC sleep state and restore after wake up.
|
||||
*
|
||||
* Put the ARC core into sleep state until next SoC wake event
|
||||
* and continue execution after wake up where the application stopped.
|
||||
*
|
||||
* If the library is built with ENABLE_RESTORE_CONTEXT=1, then this function
|
||||
* will use the arc_restore_addr to save restore trap address which brings back
|
||||
* the ARC CPU to the point where this function was called.
|
||||
* This means that applications should refrain from using them.
|
||||
*
|
||||
* This function calls qm_ss_save_context and qm_ss_restore_context
|
||||
* in order to restore execution where it stopped.
|
||||
* All power management transitions are done by power_soc_sleep().
|
||||
*/
|
||||
//void ss_power_soc_sleep_restore(void);
|
||||
/**
|
||||
* Enter SoC sleep state and restore after wake up.
|
||||
*
|
||||
* Put the ARC core into sleep state until next SoC wake event
|
||||
* and continue execution after wake up where the application stopped.
|
||||
*
|
||||
* If the library is built with ENABLE_RESTORE_CONTEXT=1, then this function
|
||||
* will use the arc_restore_addr to save restore trap address which brings back
|
||||
* the ARC CPU to the point where this function was called.
|
||||
* This means that applications should refrain from using them.
|
||||
*
|
||||
* This function calls qm_ss_save_context and qm_ss_restore_context
|
||||
* in order to restore execution where it stopped.
|
||||
* All power management transitions are done by power_soc_deep_sleep().
|
||||
*/
|
||||
//void ss_power_soc_deep_sleep_restore(void);
|
||||
|
||||
/**
|
||||
* Save context, enter ARC SS1 power save state and restore after wake up.
|
||||
*
|
||||
* This routine is same as ss_power_soc_sleep_restore(), just instead of
|
||||
* going to sleep it will go to SS1 power save state.
|
||||
* Note: this function has a while(1) which will spin until we enter
|
||||
* (and exit) sleep and the power state change will be managed by the other
|
||||
* core.
|
||||
*/
|
||||
//void ss_power_sleep_wait(void);
|
||||
|
||||
/**
|
||||
* Enable the SENSOR startup restore flag.
|
||||
*/
|
||||
//void power_soc_set_ss_restore_flag(void);
|
||||
|
||||
/**
|
||||
* Disable LPSS state entry.
|
||||
*
|
||||
* Clear LPSS enable flag.<BR>
|
||||
* Disable Clock Gating of ADC, I2C0, I2C1, SPI0 and SPI1 sensor
|
||||
* peripherals.<BR>
|
||||
* This will prevent entry in LPSS when cores are in C2/C2LP and SS2 states.
|
||||
*/
|
||||
//void ss_power_soc_lpss_disable(void);
|
||||
|
||||
/**
|
||||
* Enter Sensor SS1 state.
|
||||
*
|
||||
* Put the Sensor Subsystem into SS1.<BR>
|
||||
* Processor Clock is gated in this state.
|
||||
*
|
||||
* A wake event causes the Sensor Subsystem to transition to SS0.<BR>
|
||||
* A wake event is a sensor subsystem interrupt.
|
||||
*
|
||||
* According to the mode selected, Sensor Subsystem Timers can be disabled.
|
||||
*
|
||||
* @param[in] mode Mode selection for SS1 state.
|
||||
*/
|
||||
//void ss_power_cpu_ss1(const ss_power_cpu_ss1_mode_t mode);
|
||||
|
||||
/**
|
||||
* Enter Sensor SS2 state or SoC LPSS state.
|
||||
*
|
||||
* Put the Sensor Subsystem into SS2.<BR>
|
||||
* Sensor Complex Clock is gated in this state.<BR>
|
||||
* Sensor Peripherals are gated in this state.<BR>
|
||||
*
|
||||
* This enables entry in LPSS if:
|
||||
* - Sensor Subsystem is in SS2
|
||||
* - Lakemont is in C2 or C2LP
|
||||
* - LPSS entry is enabled
|
||||
*
|
||||
* A wake event causes the Sensor Subsystem to transition to SS0.<BR>
|
||||
* There are two kinds of wake event depending on the Sensor Subsystem
|
||||
* and SoC state:
|
||||
* - SS2: a wake event is a Sensor Subsystem interrupt
|
||||
* - LPSS: a wake event is a Sensor Subsystem interrupt or a Lakemont interrupt
|
||||
*
|
||||
* LPSS wake events apply if LPSS is entered.
|
||||
* If Host wakes the SoC from LPSS,
|
||||
* Sensor also transitions back to SS0.
|
||||
*/
|
||||
//void ss_power_cpu_ss2(void);
|
||||
|
||||
/**
|
||||
* Save resume vector.
|
||||
*
|
||||
* Saves the resume vector in the global "arc_restore_addr" location.
|
||||
* The ARC will jump to the resume vector once a wake up event is
|
||||
* triggered and x86 resumes the ARC.
|
||||
*/
|
||||
#define qm_ss_set_resume_vector(_restore_label, arc_restore_addr) \
|
||||
__asm__ __volatile__("mov r0, @arc_restore_addr\n\t" \
|
||||
"st " #_restore_label ", [r0]\n\t" \
|
||||
: /* Output operands. */ \
|
||||
: /* Input operands. */ \
|
||||
: /* Clobbered registers list. */ \
|
||||
"r0")
|
||||
|
||||
/* Save execution context.
|
||||
*
|
||||
* This routine saves CPU registers onto cpu_context,
|
||||
* array.
|
||||
*
|
||||
*/
|
||||
#define qm_ss_save_context(cpu_context) \
|
||||
__asm__ __volatile__("push_s r0\n\t" \
|
||||
"mov r0, @cpu_context\n\t" \
|
||||
"st r1, [r0, 4]\n\t" \
|
||||
"st r2, [r0, 8]\n\t" \
|
||||
"st r3, [r0, 12]\n\t" \
|
||||
"st r4, [r0, 16]\n\t" \
|
||||
"st r5, [r0, 20]\n\t" \
|
||||
"st r6, [r0, 24]\n\t" \
|
||||
"st r7, [r0, 28]\n\t" \
|
||||
"st r8, [r0, 32]\n\t" \
|
||||
"st r9, [r0, 36]\n\t" \
|
||||
"st r10, [r0, 40]\n\t" \
|
||||
"st r11, [r0, 44]\n\t" \
|
||||
"st r12, [r0, 48]\n\t" \
|
||||
"st r13, [r0, 52]\n\t" \
|
||||
"st r14, [r0, 56]\n\t" \
|
||||
"st r15, [r0, 60]\n\t" \
|
||||
"st r16, [r0, 64]\n\t" \
|
||||
"st r17, [r0, 68]\n\t" \
|
||||
"st r18, [r0, 72]\n\t" \
|
||||
"st r19, [r0, 76]\n\t" \
|
||||
"st r20, [r0, 80]\n\t" \
|
||||
"st r21, [r0, 84]\n\t" \
|
||||
"st r22, [r0, 88]\n\t" \
|
||||
"st r23, [r0, 92]\n\t" \
|
||||
"st r24, [r0, 96]\n\t" \
|
||||
"st r25, [r0, 100]\n\t" \
|
||||
"st r26, [r0, 104]\n\t" \
|
||||
"st r27, [r0, 108]\n\t" \
|
||||
"st r28, [r0, 112]\n\t" \
|
||||
"st r29, [r0, 116]\n\t" \
|
||||
"st r30, [r0, 120]\n\t" \
|
||||
"st r31, [r0, 124]\n\t" \
|
||||
"lr r31, [ic_ctrl]\n\t" \
|
||||
"st r31, [r0, 128]\n\t" \
|
||||
: /* Output operands. */ \
|
||||
: /* Input operands. */ \
|
||||
[ic_ctrl] "i"(QM_SS_AUX_IC_CTRL) \
|
||||
: /* Clobbered registers list. */ \
|
||||
"r0")
|
||||
|
||||
/* Restore execution context.
|
||||
*
|
||||
* This routine restores CPU registers from cpu_context,
|
||||
* array.
|
||||
*
|
||||
* This routine is called from the bootloader to restore the execution context
|
||||
* from before entering in sleep mode.
|
||||
*/
|
||||
#define qm_ss_restore_context(_restore_label, cpu_context) \
|
||||
__asm__ __volatile__( \
|
||||
#_restore_label \
|
||||
":\n\t" \
|
||||
"mov r0, @cpu_context\n\t" \
|
||||
"ld r1, [r0, 4]\n\t" \
|
||||
"ld r2, [r0, 8]\n\t" \
|
||||
"ld r3, [r0, 12]\n\t" \
|
||||
"ld r4, [r0, 16]\n\t" \
|
||||
"ld r5, [r0, 20]\n\t" \
|
||||
"ld r6, [r0, 24]\n\t" \
|
||||
"ld r7, [r0, 28]\n\t" \
|
||||
"ld r8, [r0, 32]\n\t" \
|
||||
"ld r9, [r0, 36]\n\t" \
|
||||
"ld r10, [r0, 40]\n\t" \
|
||||
"ld r11, [r0, 44]\n\t" \
|
||||
"ld r12, [r0, 48]\n\t" \
|
||||
"ld r13, [r0, 52]\n\t" \
|
||||
"ld r14, [r0, 56]\n\t" \
|
||||
"ld r15, [r0, 60]\n\t" \
|
||||
"ld r16, [r0, 64]\n\t" \
|
||||
"ld r17, [r0, 68]\n\t" \
|
||||
"ld r18, [r0, 72]\n\t" \
|
||||
"ld r19, [r0, 76]\n\t" \
|
||||
"ld r20, [r0, 80]\n\t" \
|
||||
"ld r21, [r0, 84]\n\t" \
|
||||
"ld r22, [r0, 88]\n\t" \
|
||||
"ld r23, [r0, 92]\n\t" \
|
||||
"ld r24, [r0, 96]\n\t" \
|
||||
"ld r25, [r0, 100]\n\t" \
|
||||
"ld r26, [r0, 104]\n\t" \
|
||||
"ld r27, [r0, 108]\n\t" \
|
||||
"ld r28, [r0, 112]\n\t" \
|
||||
"ld r29, [r0, 116]\n\t" \
|
||||
"ld r30, [r0, 120]\n\t" \
|
||||
"ld r31, [r0, 124]\n\t" \
|
||||
"ld r0, [r0, 128]\n\t" \
|
||||
"sr r0, [ic_ctrl]\n\t" \
|
||||
"pop_s r0\n\t" \
|
||||
"sr 0,[0x101]\n\t" /* Setup Sensor Subsystem TimeStamp Counter */ \
|
||||
"sr 0,[0x100]\n\t" \
|
||||
"sr -1,[0x102]\n\t" \
|
||||
: /* Output operands. */ \
|
||||
: /* Input operands. */ \
|
||||
[ic_ctrl] "i"(QM_SS_AUX_IC_CTRL) \
|
||||
: /* Clobbered registers list. */ \
|
||||
"r0")
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* __QM_SS_POWER_STATES_H__ */
|
Loading…
x
Reference in New Issue
Block a user