12 Replies Latest reply on Aug 15, 2016 2:32 AM by Lockdog

    Quark D2000 doesn't wake up after deep sleep

    Lockdog

      I'm trying to wake up quark board after deep sleep, using comparator:

       

      #define WAKEUP_COMPARATOR_PIN (3) /*A0*/
      
      int main(void)
      {
        qm_rc_t rc;
        qm_ac_config_t ac_cfg;
      
      
      
        ac_cfg.reference = BIT(WAKEUP_COMPARATOR_PIN);
        ac_cfg.polarity = 0x0;
        ac_cfg.power = BIT(WAKEUP_COMPARATOR_PIN);
        ac_cfg.int_en = BIT(WAKEUP_COMPARATOR_PIN);
        ac_cfg.callback = ac_callback;
        qm_ac_set_config(&ac_cfg);
      
        qm_irq_request(QM_IRQ_AC, qm_ac_isr);
        qm_pmux_select(QM_PIN_ID_3, QM_PMUX_FN_1);
        qm_pmux_input_en(QM_PIN_ID_3, true);
      
      
        QM_PUTS("Weak Up Interrupt Ready\r\n");
      
      
        while(1)
        {
        QM_PUTS("Go to deep sleep.");
        soc_deep_sleep();
        QM_PUTS("Weak Up");
        }
      }
      
      void ac_callback()
      {
        QM_PUTS("Interrupt");
        QM_SCSS_INT->int_comparators_host_mask |= BIT(WAKEUP_COMPARATOR_PIN);
      }
      

       

      And interrupt works fine before deep-sleep, but it can't to wake up after.

       

      UPD. This example: qmsi/main.c at fd5a6a783df1ab99260302ea25e1efb6208dbd8f · 01org/qmsi · GitHub  didn't work too.

        • 1. Re: Quark D2000 doesn't wake up after deep sleep
          Intel_Alvarado

          Hi,

           

          According to the Intel Quark Microcontroller Software Interface document https://downloadcenter.intel.com/download/25619 , section 4.13 you can see a notes that says: “Enter into deep sleep mode. All clocks are gated. The only way to return from this is to have an interrupt trigger on the low power comparators.”

          In the link you posted there’s a comment that says “Comparator pin will fire an interrupt when the input voltage is greater than the reference voltage (0.95V).”

          I also find a couple of threads with questions related to yours:

          https://communities.intel.com/message/410412#410412

          https://communities.intel.com/message/395782#395782

          One of the users also posted that “I've made some measurements and it seems that to wakeup from deep sleep the A5 pin needs to be pulled down.”

          Make sure to meet all these requirements.

           

          -Sergio

          • 2. Re: Quark D2000 doesn't wake up after deep sleep
            Lockdog

            Hello, Sergio,

            thanks for the reply.

            I've used low power comparator as described in document, and provide 3.3V to the input pin which connected to the comparator. Threads, that you provided doesn't resolve my problem at all. Example from Intel Studio doesn't work too.

             

            >>"A5 pin needs to be pulled down.”

            How I can do that? Is there any internal pull down and how I could configure it in this case? Or the only way is to use external pull-down resistor?

             

            UPD. I added the pulldown resistor and no any changes.

            UPD2. "A5 pin needs to be pulled down.” - it need for reducing the power consumption only and doesn't affect on interrupt.

            • 3. Re: Quark D2000 doesn't wake up after deep sleep
              Intel_Alvarado

              We’ll investigate further and post a reply soon.

               

              -Sergio

              • 4. Re: Quark D2000 doesn't wake up after deep sleep
                Intel_Alvarado

                According to https://communities.intel.com/message/396065#396065 , pin A5 should be connected to GND.

                Why is the Intel Studio not working, does it show any error logs or is it not responding? Can you try the power example? Notice the example says:

                 

                 

                “/* On the Quark Microcontroller D2000 Development Platform this pin is marked as"A5". This pin should be connected to ground before running the example! If not, the irq would be run before going into deep sleep. The callback will turn-of the gpio/comparator irq. This will result in the board not being able to recover from deep sleep.”

                 

                Follow the suggestions on the thread and let us know your results.

                 

                -Sergio

                • 5. Re: Quark D2000 doesn't wake up after deep sleep
                  Lockdog

                  Hi,

                  thanks for the reply.

                  Power example works as it should if I connect A5 to the GND, before running. But when I'm trying to write my own code interrupt, doesn't work. Also, I'm trying to use soc_sleep and waking up by RTC and it doesn't working too!

                  Please help. My code below:

                   

                  int main(void)
                  {
                    uart_cfg();
                    QM_PUTS("Magnetometer app started\r");
                    mag_init();
                    ac_init();
                    rtc_init();
                    while(1)
                    {
                    QM_PUTS("Go to sleep\r");
                    soc_sleep();
                    QM_PUTS("Weak Up\r");
                    }
                  }
                  
                  void bmc150_mag_set_h_threshold(void)
                  {
                    /*ENABLE INTERRUPT*/
                    write_register(0x12, BMC150_REG_INTERRUPT, 0x47);
                  
                  
                    /*SET THRES ON X*/
                    write_register(0x12, BMC150_REG_HIGH_THRESHOLD_AXES_SET, 0x37);
                  
                  
                    /*SET THRES VALUE (XDATA/16)*/
                    write_register(0x12, BMC150_REG_HIGH_THRESHOLD, X_H_THRESHOLD);
                  }
                  
                  void ac_init(void)
                  {
                    qm_ac_config_t ac_cfg;
                  
                  
                    ac_cfg.reference = BIT(WAKEUP_COMPARATOR_PIN);
                    ac_cfg.polarity = 0x0;
                    ac_cfg.power = BIT(WAKEUP_COMPARATOR_PIN);
                    ac_cfg.int_en = BIT(WAKEUP_COMPARATOR_PIN);
                    ac_cfg.callback = ac_callback;
                    qm_ac_set_config(&ac_cfg);
                  
                  
                    qm_irq_request(QM_IRQ_AC, qm_ac_isr);
                  
                  
                    qm_pmux_select(WAKEUP_COMPARATOR_PIN, QM_PMUX_FN_1);
                    qm_pmux_input_en(WAKEUP_COMPARATOR_PIN, true);
                  
                  
                    #ifdef DEBUG0
                    QM_PUTS("Comparator Ready\r");
                    #endif
                  }
                  
                  
                  int mag_init(void)
                  {
                    bmc150_init(BMC150_J14_POS_0);
                    bmc150_mag_set_power(BMC150_MAG_POWER_ACTIVE);
                   bmc150_mag_set_preset(BMC150_MAG_PRESET_LOW_POWER);
                    bmc150_mag_set_h_threshold();
                    #ifdef DEBUG0
                    QM_PUTS("BMC150 Ready\r");
                    #endif
                    return 0;
                  }
                  
                  void uart_cfg(void)
                  {
                    qm_uart_config_t cfg;
                  
                    qm_uart_get_config(QM_UART_0, &cfg);
                    cfg.baud_divisor = QM_UART_CFG_BAUD_DL_PACK(0, 104, 3);
                    qm_uart_set_config(QM_UART_0, &cfg);
                  
                    qm_pmux_select(QM_PIN_ID_12, QM_PMUX_FN_2); /* configure UART_A_TXD */
                    qm_pmux_select(QM_PIN_ID_13, QM_PMUX_FN_2); /* configure UART_A_RXD */
                    qm_pmux_input_en(QM_PIN_ID_13, true); /* UART_A_RXD is an input */
                  
                    #ifdef DEBUG0
                    QM_PUTS("UART Ready\r");
                    #endif
                  }
                  
                  
                  void rtc_init(void)
                  {
                    qm_rtc_config_t rtc;
                  
                    clk_periph_enable(CLK_PERIPH_RTC_REGISTER | CLK_PERIPH_CLK);
                  
                    rtc.init_val = 0;
                    rtc.alarm_en = true;
                    rtc.alarm_val = ALARM;
                    rtc.callback = bmc150_mag_callback;
                    qm_rtc_set_config(QM_RTC_0, &rtc);
                  
                    qm_irq_request(QM_IRQ_RTC_0, qm_rtc_isr_0);
                  
                    #ifdef DEBUG0
                    QM_PUTS("RTC Ready\r");
                    #endif
                  }
                  
                  void bmc150_mag_callback(void)
                  {
                    bmc150_mag_t mag = {0};
                    bmc150_read_mag(&mag);
                    QM_PRINTF("mag x %d y %d z %d\r\n", mag.x, mag.y, mag.z);
                    qm_rtc_set_alarm(QM_RTC_0, (QM_RTC[QM_RTC_0].rtc_ccvr + ALARM));
                  }
                  
                  void bmc150_mag_read_reg_int(void)
                  {
                    QM_PRINTF("\r\nINTERRUPT\r\n");
                    uint8_t raw_mag[1];
                    read_register(0x12, 0x4A, raw_mag, sizeof(raw_mag));
                    QM_PRINTF("INT: %d\r\n", raw_mag[0]);
                  }
                  
                  void ac_callback()
                  {
                    bmc150_mag_read_reg_int();
                  }
                  
                  • 6. Re: Quark D2000 doesn't wake up after deep sleep
                    Intel_Alvarado

                    Thank you for providing the code. We’ll run some tests and post our reply soon.

                     

                    -Sergio

                    • 7. Re: Quark D2000 doesn't wake up after deep sleep
                      Lockdog

                      Hello, Sergio

                      Do you have any results?

                      • 8. Re: Quark D2000 doesn't wake up after deep sleep
                        Intel_Alvarado

                        We’re still investigating on your case. We’ll post a reply soon. Thank you for your patience.

                         

                        -Sergio

                        • 9. Re: Quark D2000 doesn't wake up after deep sleep
                          Intel_Alvarado

                          Take a look at this power example https://github.com/quark-mcu/qmsi/blob/master/examples/power_profiler/main.c . This is the newest example used for deep sleep testing. If you’re writing your own code, make sure to base your code on this example, not in one of the previous examples. Try testing this code first.

                           

                          If this code works using the comparators and the RTC, you can move on and write your own code. I’d suggest you try small parts of the circuit first before attempting to connect the whole circuit. Focus first in waking up in the deep sleep wake up source. Once it is working then you can focus on the RTC wake up source.

                           

                          -Sergio

                          • 10. Re: Quark D2000 doesn't wake up after deep sleep
                            Lockdog

                            @Intel_Alvarado

                            Example works right. But when I try to implement the deep sleep part in my code it doesn't work. Which part may conflicted with it?

                            • 11. Re: Quark D2000 doesn't wake up after deep sleep
                              jdel_

                              Hello Lockdog,

                               

                              Checking your code, you are using a high power comparator as a wake up pin.

                              Please use one of AI[18:6] for wake-up.

                               

                              Refering to section 3.3 of the D2000 datasheet: Intel® Quark™ Microcontroller D2000: Datasheet :

                              Any wake capable analog inputs shall be connected only to any of AI[18:6] and not to AI[5:0].

                               

                              Your example is using: #define WAKEUP_COMPARATOR_PIN (3) /*A0*/.

                              If you check the example in example/quark_d2000/main.c, the example is using:

                              #define WAKEUP_COMPARATOR_PIN (6) /*A5*/

                               

                              I hope this solves your issue.

                               

                              - Julien

                              2 of 2 people found this helpful
                              • 12. Re: Quark D2000 doesn't wake up after deep sleep
                                Lockdog

                                Hi, Julien,

                                thanks for your note, it helped me to moving forward

                                I have found mistake in my code: when interrupt happens it call the function which try to read data by i2c, but deep sleep routine still didn't recover gpio registers and quark hangs up. Second point is that we need to configuring analog comparator every time before deep-sleep.