Go Down

Topic: pmc_enable_waitmode() -- how to wake up? (Read 618 times) previous topic - next topic

KassidyKnight

I've been reading through the SAM3x8e datasheet to better understand and implement Wait Mode on my DUE. Does anyone know the correct command for generating a fast startup wakeup event after entering wait mode?

According to the datasheet, to generate fast startup while in wait mode, you must:
1) configure the external lines WKUP0-15 as fast startup wake-up pins
2) detect a low level on one of the wake-up inputs

The code I have right now to ENTER wait mode is:
  pmc_set_writeprotect(0);                                                  //disable write protect of pmc registers
  pmc_set_fast_startup_input(PMC_FSMR_FSTT7);                //enable fast startup, wakeup pin 7
  pmc_enable_waitmode(); 

I have then tried to wake it up using the line:
  PMC->PMC_FSMR |= PMC_FSMR_FSTT7; // Generate fast startup event

This wake up line works, but only once. I cannot re-enter wait mode successfully after executing this line of code.

nemiro

I know this is horribly old, but were you able to get this problem solved?  I have been having a heck of a time with the SAM3X8E sleep/wake modes. 

ard_newbie


There are 3 low power modes: backup mode, wait mode and sleep mode. Everything is explained from page 25 of Sam3x datasheet.

Have you read it ? What mode are you trying to enter ? What is your code ?

nemiro

Thank you for replying.  I have looked at it, and to be honest, I'm just a bit lost on where to go with it.  I was looking for a working example of how to implement it, and haven't exactly found anything that actually works.  I have played around with it, as follows (leaving out other items specific to the board I made):


#include <Arduino.h>

#define led         13
#define button    48  //define for power button



void setup() {
  // put your setup code here, to run once:
  SerialUSB.begin(115200);
  SerialUSB.println();
  SerialUSB.println("Begin setup.");
//Set LED "L" to also give a heartbeat
  pinMode(led, OUTPUT);

  pinMode(button, INPUT);
  attachInterrupt(button, wake_ISR, FALLING);
 
  SerialUSB.println("Initial Setup Complete."); 
}



void wake_ISR()        // interrupt to handle a wake up button press
{
  SerialUSB.println("waking up");
  PMC->PMC_FSMR |= PMC_FSMR_FSTT7;
}


void loop() {
  // put your main code here, to run repeatedly:
  SerialUSB.println("LED Loop begins."); 
  for(int i=0;i<10;i++)
    {
    digitalWrite(led, HIGH);
    delay(500);
    digitalWrite(led, LOW);
    delay(500);
    }
  //After blinking for 10 seconds, put it all to sleep
  SerialUSB.println("Going to sleep.");
  pmc_set_writeprotect(0);                      //disable write protect of pmc registers
  pmc_set_fast_startup_input(PMC_FSMR_FSTT7);   //enable fast startup, wakeup pin 7 
  pmc_enable_waitmode();  //lower power mode versus sleep mode 
}


This does not work at all, incidentally.  Commenting PMC->PMC_FSMR |= PMC_FSMR_FSTT7; out of the ISR makes it somewhat functional, in that the processor seems to sleep until the ISR runs.  However, current draw is still around 70mA, which is what it draws when it is awake, anyway. 

My actual goal is to be able to push a Power button, on pin 48, have the routine shut down all attached peripherals (discretely, with other code), and then have the SAM3X8E go into backup power mode (that is the lowest power draw mode, correct?), and then wake up, and basically reset when the power button is pushed again.  The idea is that this will be in a small battery powered device that we do not want running all of the time, and want to save the battery.  I have done this on other projects, and have had good luck.  This is my first go at that SAM3X, and I can really use all the help I can get.  Thanks!

ard_newbie

#4
Mar 24, 2018, 06:42 am Last Edit: Mar 24, 2018, 07:38 am by ard_newbie
Back up mode is the most interesting low power mode, however after Wake up, you run from the
setup().

There are several slightly different ways to enter and exit from back up mode, here is an example sketch with alternate way and event options.

Do not power down your board while in back up mode, or your bord will become a brick for 5 minutes !

Code: [Select]

/**********************************************************
             Backup mode with Alternate Way and Event
***********************************************************/

#define   SUPC_KEY                    (0xA5)
const uint32_t AL = 5;  // Alarm = AL * T

void setup() {

  Serial.begin(250000);
  while (!Serial);
  printf("\n Last software update  : %s   %s\n", __DATE__, __TIME__);

  uint32_t status = (RSTC->RSTC_SR & RSTC_SR_RSTTYP_Msk) >> RSTC_SR_RSTTYP_Pos;
  Serial.print("\nRSTTYP = 0b"); Serial.println(status, BIN);  // Should be 0b001 see page 232

  RTT->RTT_MR = RTT_MR_RTTRST
                | RTT_MR_RTPRES (0x8000);  // T = 1 second

  RTT->RTT_SR;

  RTT->RTT_AR = RTT_AR_ALMV(AL);

  SUPC->SUPC_WUMR |= SUPC_WUMR_RTTEN;

  Serial.print("\n GPBR[0] = "); Serial.println(GPBR->SYS_GPBR[0]);
  delay(1000);

}

void loop() {

  GPBR->SYS_GPBR[0] += 1;            // Increment one of the 8 General Purpose Backup Registers

  if (GPBR->SYS_GPBR[0] < 4) {

    Serial.print("Entering backup mode : Do NOT stop the software now  |:");

    Serial.end();                     // Exit from Serial

    //alternate way to enter backup mode
    SUPC->SUPC_CR = SUPC_CR_VROFF_STOP_VREG | SUPC_CR_KEY(SUPC_KEY);

  }

  Serial.println("Definitive Exit from backup mode");
  Serial.println("Now you can stop the software");
  Serial.println(GPBR->SYS_GPBR[0]);
  delay(5000);

}




nemiro

Thank you so much!  I will give it a go first thing in the morning!

nemiro

Had to fiddle with it a little bit because my board does not have the ATMega onboard to program/serial monitor, but did get it to compile pretty easily.  I am going to claim quite a bit of ignorance as to everything that is happening in this code.  First, here is the output:

 Last software update  : Mar 24 2018   10:45:33

RSTTYP = 0b11

 GPBR[0] = 254
Definitive Exit from backup mode
Now you can stop the software
255
Definitive Exit from backup mode
Now you can stop the software
256
Definitive Exit from backup mode
Now you can stop the software
257
Definitive Exit from backup mode
Now you can stop the software
258
Definitive Exit from backup mode
Now you can stop the software
259
Definitive Exit from backup mode
Now you can stop the software
260


It keeps on counting.  Looking at your comment in the code on about line 15, RSTTYP ought to return as 0b001, which shows as Backup Reset, but it comes over as 0b11, which is Software Reset. 

Following your code down, it appears we are looking for the GPBR to be <4 to enter backup mode, but it just keeps counting away.  Am I reading that wrong? 

ard_newbie

The code I provided is for a DUE and works nicely.

This is the output I have with this code :

Code: [Select]

Last software update  : Mar 24 2018   17:08:18

RSTTYP = 0b0

 GPBR[0] = 0
Entering backup mode : Do NOT stop the software now  |:D
 Last software update  : Mar 24 2018   17:08:18

RSTTYP = 0b1

 GPBR[0] = 1
Entering backup mode : Do NOT stop the software now  |:D
 Last software update  : Mar 24 2018   17:08:18

RSTTYP = 0b1

 GPBR[0] = 2
Entering backup mode : Do NOT stop the software now  |:D
 Last software update  : Mar 24 2018   17:08:18

RSTTYP = 0b1

 GPBR[0] = 3
Definitive Exit from backup mode
Now you can stop the software
4
Definitive Exit from backup mode
Now you can stop the software
5
Definitive Exit from backup mode
Now you can stop the software
6


nemiro

OK, I'm still working with it, trying to understand.  I need to figure out why RSTTYP is wrong.



Go Up