How to re-enable GPIO after deep sleep?

dmaxben
Posts: 79
Joined: Thu Nov 16, 2017 6:04 pm

How to re-enable GPIO after deep sleep?

Postby dmaxben » Wed Feb 28, 2018 6:41 pm

Hi everyone, had a quick question regarding deep sleep using a hardware interrupt for wakeup.

My project is using CAN bus with CAN Rx on GPIO-4, and CAN Tx on GPIO-5.

The goal is to have the ESP go into deep sleep when CAN activity stops, and then when CAN activity is detected, wake-up the ESP32 and start normal operation.

When I want the ESP32 to go to sleep, I have the ESP32 set GPIO-4 (CAN Rx) to act as the hardware interrupt for wakeup.

As a CAN message comes in, the CAN Rx pin changes state, which causes the ESP32 to wake up. I know that using this method might result in one or two missed CAN messages while the ESP32 wakes up and starts the main loop again, but Im not worried about that.

Everything works perfectly upon first boot, the ESP32 prints all the correct CAN messages that Im sending to it, then Ill stop sending CAN messages, then goes to sleep, and once its asleep, Ill then send out a couple more CAN messages to it...the ESP32 then wakes up properly...HOWEVER....after wakeup, the CAN controller doesnt re-initialize correctly. You have to cycle power or press the hardware reset button to get CAN bus working again.

After lots of searching, I found out that once a rtc_GPIO is set to be a hardware interrupt/wakeup, after the ESP32 has been woken up by a change in state of the GPIO, you have to manually reset the rtc_GPIO to be a standard digital GPIO again. I assume thats what is happening here, the ESP32 restarts upon wake up, and CAN doesnt initialize and start working because GPIO-4 is still set as an rtc_GPIO.

I found that

rtc_gpio_deinit(gpio_num)

will reset the pin back to being a normal GPIO.

However, it doesnt seem to be working correctly, maybe I have some wrong syntax, or not using the function correctly?

In this simple example, for bench testing purposes and proof of "sleep/wake up on CAN receive" concept, Im basically just having the ESP go to sleep after a set period of time (counter), and then once its asleep, I send it some CAN frames. Im using Arduino if that makes any difference?

Code: Select all

int counter = 0;

CAN_device_t CAN_cfg = {
  .speed=CAN_SPEED_500KBPS,    // CAN Node baudrade
  .tx_pin_id = GPIO_NUM_5,    // CAN TX pin
  .rx_pin_id = GPIO_NUM_4,    // CAN RX pin
  .rx_queue=NULL,         // FreeRTOS queue for RX frames
};

char HSmsgString[128];

void setup() {

  Serial.begin(115200);

esp_err_t rtc_gpio_deinit(GPIO_NUM_4);    // reset the rtc_GPIO wake up pin to be a normal digital GPIO-4 again

    CAN_cfg.rx_queue = xQueueCreate(10,sizeof(CAN_frame_t));
   //start CAN Module
   CAN_init();
}

void loop() {

CAN_frame_t rx_frame;
    if(xQueueReceive(CAN_cfg.rx_queue,&rx_frame, 3*portTICK_PERIOD_MS)==pdTRUE){

        sprintf(HSmsgString, "HS-CAN Standard ID: 0x%.3lX       DLC: %1d  Data:",rx_frame.MsgID,  rx_frame.FIR.B.DLC);
         Serial.print(HSmsgString);
             for(byte r = 0; r<len; r++){
        sprintf(HSmsgString, " 0x%.2X", rx_frame.data.u8[r]);
        Serial.print(HSmsgString);
      }
      Serial.println();     // print the received CAN traffic to the serial terminal
    }

counter++;

if (counter > 2000){                          // wait a couple seconds, then put the ESP32 to sleep
    Serial.println("going to sleep!");
  delay(2000);
  CAN_stop();
  delay(5);
   esp_sleep_enable_ext0_wakeup(GPIO_NUM_4, LOW);    // enable the external wakeup on GPIO 4 (which is tied to CAN Rx)
esp_deep_sleep_start();    // ESP32 goes to sleep until it sees GPIO-4 (CAN Rx) change state as a "wake up" message comes in
}
}
Hopefully its something simple Im missing...any ideas?

Thanks

WiFive
Posts: 2978
Joined: Tue Dec 01, 2015 7:35 am

Re: How to re-enable GPIO after deep sleep?

Postby WiFive » Thu Mar 01, 2018 3:29 am

Why is esp_err_t there?

dmaxben
Posts: 79
Joined: Thu Nov 16, 2017 6:04 pm

Re: How to re-enable GPIO after deep sleep?

Postby dmaxben » Thu Mar 01, 2018 3:41 am

WiFive wrote:Why is esp_err_t there?
It wouldn’t compile without esp_err_t in there...said “rtc_deinit... not declared in this scope”

WiFive
Posts: 2978
Joined: Tue Dec 01, 2015 7:35 am

Re: How to re-enable GPIO after deep sleep?

Postby WiFive » Thu Mar 01, 2018 5:06 am

Well you have to include driver/rtc_io.h. the way it is written it is a function declaration not a function call so it doesn't do anything.

dmaxben
Posts: 79
Joined: Thu Nov 16, 2017 6:04 pm

Re: How to re-enable GPIO after deep sleep?

Postby dmaxben » Thu Mar 01, 2018 12:55 pm

WiFive wrote:Well you have to include driver/rtc_io.h. the way it is written it is a function declaration not a function call so it doesn't do anything.

Doh!!!! Stupid me, I totally forgot to include that header file.

Many thanks again for the help...seems to work perfectly now. :D

Who is online

Users browsing this forum: No registered users and 17 guests