Pin States changed on Sleep

We’re using P12, P42, P43 for rgb leds, utilising pwm (analogWrite). When api.system.scheduler.task.destroy() is called the states of the pin change and we cant seem to figure out where this is happening.

If we dont call api.system.scheduler.task.destroy() then it remains as is. I noticed that this happens after “SLEEP” is printed, when i do any activity and “WAKE_UP” is printed it behaves normally again, ie it goes back to it’s intended state.

Any idea why this happens?

okay, i found out that it’s partly because of this function:
for context i’ve also called this in setup:

uhal_uart_flush(port ,0);
uhal_uart_deinit(port);
void uhal_mcu_suspend(void) {


    if(is_mcu_resumed == false)
        return;

    UBaseType_t uxSavedInterruptStatus;
    if(isInISR())
    {
        uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
    }
    else
    {
        taskENTER_CRITICAL();
    }

    #ifdef SUPPORT_SPI
    uhal_spimst_suspend();
    #endif
    uhal_adc_suspend();
    uhal_pwm_suspend();
    uhal_uart_suspend();
    uhal_twimst_suspend();
    uhal_gpio_suspend();
    uhal_rtc_suspend();

    if(is_mcu_sleeping == true)
      uhal_mcu_set_rx_interrupt();

    is_mcu_resumed = false;

    if(isInISR())
    {
        taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );

    }
    else
    {
        taskEXIT_CRITICAL();
    }

    am_log_inf("uhal_mcu_suspend");
}

image

after commenting out uhal_pwm_suspend(), uhal_uart_suspend(), uhal_adc_suspend() the led stops breathing red and purple, it instead is white the whole time, it’s a little annoying that i cannot predict the led colour and that it’s not immediately obvious what is controlling the pins despite uart being disabled.

okay i’ve further narrowed it to uhal_pwm_suspend(), uhal_uart_suspend(), and udrv_powersave_in_sleep = true

please advise.

Hello @sabith-atlaslabs,

Pin 39 and 40 is used for UART-0 and pin 41 and 42 is used for UART-1. We are assigning pull-up registers to RX pins at sleep mode to be able to wake up it with an AT command. If you are not using AT commands and you will not wake up RAK11720 from sleep mode with AT commands, please disabled following lines on your side inside uhal_powersave.c file.

void uhal_mcu_set_rx_interrupt(void) {

  am_log_inf("Set RX interrupt...");

  uhal_gpio_intc_clear(WB_RXD0);
  uhal_gpio_pin_suspend(WB_RXD0);
  uhal_gpio_set_dir(WB_RXD0, GPIO_DIR_IN);
  uhal_gpio_set_pull(WB_RXD0, GPIO_PULL_UP);
  uhal_gpio_intc_trigger_mode(WB_RXD0, GPIO_INTC_FALLING_EDGE);
  uhal_gpio_register_isr(WB_RXD0, uart0_rx_interrupt_handler);

//   uhal_gpio_intc_clear(WB_RXD1);
//   uhal_gpio_pin_suspend(WB_RXD1);
//   uhal_gpio_set_dir(WB_RXD1, GPIO_DIR_IN);
//   uhal_gpio_set_pull(WB_RXD1, GPIO_PULL_UP);
//   uhal_gpio_intc_trigger_mode(WB_RXD1, GPIO_INTC_FALLING_EDGE);
//   uhal_gpio_register_isr(WB_RXD1, uart1_rx_interrupt_handler);
}

void uhal_mcu_clear_rx_interrupt(void) {

  am_log_inf("Clear RX interrupt...");

  uhal_gpio_intc_clear(WB_RXD0);
  uhal_gpio_pin_suspend(WB_RXD0);

//   uhal_gpio_intc_clear(WB_RXD1);
//   uhal_gpio_pin_suspend(WB_RXD1);

  rx_wait_active = false;
}

Please also comment out following lines at rak_hal_gpio_interrupt_service() function inside uhal_gpio.c file.

// uhal_gpio_intc_clear(WB_RXD1);
// uhal_gpio_pin_suspend(WB_RXD1);

For RUI3 design, if MCU is suspended, we are disabling all peripherals and MCU stays at the lowest power state. Your prediction is correct, uhal_mcu_suspend() and uhal_mcu_resume() functions are used for this purpose. Again, you must comment out related suspend/resume functions to make related peripheral active even at sleep mode.

Please do not hesitate to ask me any further questions.

Best regards,
Sercan.

that didnt quite solve my problem, unfortunately

i tried commenting all of those lines plus udrv_pwm_suspend() and udrv_serial_suspend() but P43 and P42 were still having behaviour uncontrolled from app code.

is there anything im missing maybe?

@sabith-atlaslabs

Can you please try to change these files inside attachment? Let’s see how it will behave.

fixes.zip (13.8 KB)

Additionally, I want to correct that UART-0 pins are 39 and 40 and UART-1 pins are 42 and 43. Sorry for mistake. With following sample project, it is working on my side.

#include "Arduino.h"

uint8_t ledPin1 = P42;
uint8_t ledPin2 = P43;

int val = 0;			// variable for LED brightness value
bool state = false;		// variable for control led brightness status
bool ledSwitch = false;		// variable for switch led

void valChage()
{
    state = !state;		// invert led control brightness status
    if (val == 0)
        ledSwitch = !ledSwitch;	// switch led when one of the led is darkest
}

void setup()
{
    //initialize serial communcation at 115200 bits per second
    Serial.begin(115200);
    delay(2000);

    Serial.println("RAKwireless Arduino LED Breathing Example");
    Serial.println("------------------------------------------------------");
    // initialize the LED pin as an output
    pinMode(ledPin1, OUTPUT);
    pinMode(ledPin2, OUTPUT);
}

void loop()
{
    // call function when led is brightest or darkest
    if (val == 0 || val == 255)
        valChage();

    // determine to make the led lighter or darker
    if (state)
        val++;
    else
        val--;

    // To switch the lighting led
    if (ledSwitch)
        analogWrite(ledPin1, val);	// Light the green led
    else
        analogWrite(ledPin2, val);	// Light the blue led

    api.system.sleep.all(10);
}

Works!

I must’ve missed something, appreciate it.

1 Like