rtc_gpio_set_level() not getting set reliable when ULP program is running

aliasthefourth
Posts: 5
Joined: Sun Feb 28, 2021 8:22 pm

rtc_gpio_set_level() not getting set reliable when ULP program is running

Postby aliasthefourth » Sun May 09, 2021 6:38 pm

The the rtc_gpio_set_level(PUMP_1_PIN, pump1_state) in line 44 only gets set in abought 80% of cases. Once ulp_run(ulp_program_start_pos); (line 93) is commented out, i.e., the ULP progrum is not started, the problem goes away.

I used plafromIO and Espressif ESP32 Dev Module under the Arduino framework to build the project.

#include <Arduino.h>
#include "driver/rtc_io.h"
#include "esp32/ulp.h"
#include <rom/rtc.h>

#define uS_TO_S_FACTOR 1000000
#define sleep_time 1 //s
#define PUMP_1_PIN GPIO_NUM_0

RTC_DATA_ATTR unsigned int bootCounter = 0;
RTC_DATA_ATTR bool pump1_state = false;

void ulp_PWM_start();
#define slow_mem_variable_range_start 100 // Make sure the range starts outside the size of the UPL program
#define ulp_program_start_pos 0

void setup()
{
Serial.begin(115200);
if(rtc_get_reset_reason(0) != DEEPSLEEP_RESET) // initialize ULP when powering up
{
Serial.println("CPU0 reset reason not DEEPSLEEP_RESET => initializing program");
// initialize the RTC GPIO port for pumps
rtc_gpio_init(PUMP_1_PIN); // initialize the RTC GPIO port for pumps
rtc_gpio_set_direction(PUMP_1_PIN, RTC_GPIO_MODE_INPUT_OUTPUT); // set the port mode
rtc_gpio_hold_dis(PUMP_1_PIN); // disable hold before setting the level
rtc_gpio_set_level(PUMP_1_PIN, pump1_state);
rtc_gpio_hold_en(PUMP_1_PIN); // enable hold for the RTC GPIO port
Serial.println("CPU0 reset reason not DEEPSLEEP_RESET => starting ULP program");
ulp_PWM_start();
}

Serial.println();
Serial.println("Boot number: " + String(bootCounter));
++bootCounter;

bool new_pump1_state = !pump1_state; // toogle state
// Has Pump 1 changed?
if (pump1_state != new_pump1_state)
{
pump1_state = new_pump1_state;
Serial.println("Pump 1 has chaged state to " + String(pump1_state));
rtc_gpio_hold_dis(PUMP_1_PIN); // disable hold before setting the level
rtc_gpio_set_level(PUMP_1_PIN, pump1_state);
Serial.print("rtc_gpio_get_level = ");
Serial.println(rtc_gpio_get_level(PUMP_1_PIN));
while (rtc_gpio_get_level(PUMP_1_PIN) != pump1_state) // catch if RTC level did not get set
{
Serial.println("rtc_gpio for pump 1 not set :-{( ");
rtc_gpio_set_level(PUMP_1_PIN, pump1_state);
Serial.print("rtc_gpio_get_level = ");
Serial.println(rtc_gpio_get_level(PUMP_1_PIN));
}
rtc_gpio_hold_en(PUMP_1_PIN);
}
esp_sleep_enable_timer_wakeup(sleep_time * uS_TO_S_FACTOR);
Serial.println("Going to sleep ZZZZZZZZZZZZ");
Serial.flush(); // does not seem necessary
esp_deep_sleep_start();
}

void loop()
{
// mothing to do here
}

void ulp_PWM_start()
{
// set up ULP PWM Pin 1
const int PWM_Bit_1 = RTCIO_GPIO25_CHANNEL + 14; //if connected to GPIOx (specify by +14)
// GPIOx initialization (set to output and initial value is 0)
rtc_gpio_init(GPIO_NUM_25);
rtc_gpio_set_direction(GPIO_NUM_25, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(GPIO_NUM_25, 0);

// Define ULP program
const ulp_insn_t ulp_prog[] = {
M_LABEL(0), // UPL Loop start
I_WR_REG(RTC_GPIO_OUT_REG, PWM_Bit_1, PWM_Bit_1, 1), // PWM 1 on
I_WR_REG(RTC_GPIO_OUT_REG, PWM_Bit_1, PWM_Bit_1, 0), // PWM 1 off
M_BX(0),
};

// Run ULP program
size_t ulp_program_size = sizeof(ulp_prog) / sizeof(ulp_insn_t);
// Serial.begin(115200);
// delay(100);
Serial.print("ULP prograqm ulp_program_size: ");
Serial.println(ulp_program_size);
memset(RTC_SLOW_MEM, ulp_program_start_pos, ulp_program_size); // overrides RTC_DATA_ATTR data!!! How do I make sure no such conflict occurs???
// Run ULP program
ulp_process_macros_and_load(0, ulp_prog, &ulp_program_size);
ulp_run(ulp_program_start_pos);
}

Who is online

Users browsing this forum: MicroController and 70 guests