Sleep Mode in RA4M1

Hi All,

How are you? I hope you are doing well.

I am trying to drive my controller into sleep mode, where microcontrollers draws current in terms of micro Amperes.

w.r.f 10.5.1 in RA4M1 user manual. "Example 2: From High-speed mode to Subosc-speed mode"

I have followed the instructions to enter sleep mode from high speed mode. But still when I measure current drawn by microcontroller, its in terms of 8mA.

Please correct me if i am wrong... I have disabled interrupts, stopped different peripherals using module stop function.

fsp_err_t err; 

 err = R_CGC_ClockStart(&g_cgc0_ctrl, CGC_CLOCK_SUBCLOCK, NULL);


do{
err = R_CGC_ClockCheck(&g_cgc0_ctrl,CGC_CLOCK_SUBCLOCK ); /* checks if clock source is stable or not */
}while(err!=FSP_SUCCESS);

cgc_divider_cfg_t p_divider_cfg;  /* divider setting prior to clock switching */
p_divider_cfg.iclk_div = 0;
p_divider_cfg.fclk_div = 1;
p_divider_cfg.bclk_div = 1;
p_divider_cfg.pclka_div =2;
p_divider_cfg.pclkb_div =2;
p_divider_cfg.pclkc_div =2;
p_divider_cfg.pclkd_div =2;


err=R_CGC_SystemClockSet(&g_cgc0_ctrl, CGC_CLOCK_SUBCLOCK, &p_divider_cfg); /* function to switch clock source */

R_CGC_ClockStop(&g_cgc0_ctrl, CGC_CLOCK_HOCO);
R_CGC_ClockStop(&g_cgc0_ctrl, CGC_CLOCK_MOCO);
R_CGC_ClockStop(&g_cgc0_ctrl, CGC_CLOCK_MAIN_OSC);
R_CGC_ClockStop(&g_cgc0_ctrl, CGC_CLOCK_PLL);

#if 1
R_LPM_LowPowerModeEnter(&g_lpm0_ctrl);
#else
R_SYSTEM->SBYCR_b.SSBY = 0;
__WFI(); /* This instruction will cause device enter sleep mode */
#endif

Please let me know, where I'm wrong. I doubt that I'm failing in stopping clock sources, and they have mentioned about "turnoff and stopping" different clock sources, in datasheet. Aren't both are same?

what's procedure to switch clock sources on the go? 

Thanks in Advance.

Parents Reply Children
  • Hi Jeremy,

    I've removed debugger and tried to measure current. Also I've removed some of sensors on board which run under 3.3v circuit.

  • Hi jeremy,

    Does the sleep mode instruction __WFI() has any effect on current consumption?

    When I entered Sub Oscillator low power mode...The current consumption is the same even if I run WFI instruction or comment it. Isn't it supposed to reduce further more current?

    What should be the Ideal current consumption by Microcontroller, when it enter sub osc low power mode.

    Is it possible for a few GPIO pins to consume 2.5mA when 3.3v power supply is given to the controller. Any possible leakage with other peripheral pins?

    I'm using RA4M1 series & RA2L1 controllers.

  • Hi WarrenM, Jeremy, Herald...

    A little help here...

  • How to reduce power consumption by IO pins.?

  • Hi Viswa-

    Read over section 10.5 of this doc for some ideas on what to do with I/Os for lower power.

    https://www.renesas.com/us/en/document/apn/ra4-quick-design-guide?language=en&r=1469026 

    Let us know if it answers your questions.

  • What are you trying to achieve?

    When you enter a low power mode, do you need the CPU and peripherals to be active, or do you want them to stop, and wake up and start operating on an interrupt or after a pre determined amount of time?

    Sleep mode will only put the CPU to sleep.  All other peripherals and clocks will operate, and any interrupt will wake the CPU up.  Sleep mode is probably not the best mode for optimal power saving. 

    If you place the device into Software Standby mode, the CPU and main clocks will stop.  The sub-clock or LOCO (low speed on chip oscillator) will still run.  In this mode only a peripherals, such as AGT and RTC will run.  This will give you the maximum power saving.  

    The device can be woken from software standby mode by an interrupt. 

    However, Sub-osc mode can be used as a low power mode if you do need the CPU and peripherals to operate, all be it very slowly. If you are still seeing high power consumption in sub-osc mode then it is possible that you still have other oscillators running.

    Please see attached.  This is a project written for the EK_RA4M1.  It starts with the RA4M1 running on the PLL. The LED will toggle every 10ms. Press the push button on the EK_RA4M1.  This will then switch to the sub osc mode. The LED will toggle at 100ms.  Press the push button again to start / stop the LED toggling.  With the LED tuned off, I see Icc =~ 8uA/

    Hope this is of interest.

    EK_RA4M1_LOW_POWER_MODES.zip

  • Hi Richard. It helped alot. Thanks for the help. I will try standby mode too...to see better current savings. I have stopped remaining all peripherals in the controllers. 

  • Hi Richard,

    I was able to achieve sleepmode in RA4M1, Thanks to you. I tried to apply the same logic with RA2L1 controllers.

    I failed in enabling in wakeup from CAN rx pin.

    I tried configuring external irq at CAN rx pin, due to controller limitation, the IRQ isn't reflected in vector_data.h, under IRQn_TYPE enum.

    I think this is the reason why CAN wakeup isn't possible.

    Is there a way to update vector_data.h or somehow use this one interrupt to wakeup the device and disable it right after wakeup? 

    Remaining all peripherals have been stopped and interrupts,  disabled prior to this.

  • You appear to have a lot of peripherals configured in the project (with alot of interrupts), the RA2L1 groups interrupts, and only certain interrupt groups can be put at certain locations in the ICU :-

    The configurator is showing an error that it cannot find a slot in the ICU for the Group 4 interrupt IRQ 4, so IRQ4 does not appear in the vector table.

  • Hi Jeremy

    This particular interrupt is multiplexed with CAN Rx line, so we intend to use irq as wakeup source, when there is any CAN data. Is it possible to enable external irq4, while running the code. Since I've disabled all other interrupts and stopped all peripherals modules while going into sleep, immediately after device wakes up again, I've no use of this interrupt again. 

  • You could manually enable the IRQ in the ICU at runtime by modify one of the IELSRn registers, the issue would be with the Interrupt vector table, as the vector table is statically allocated in flash at runtime, so the interrupt handler associated with the IELSRn register would the one setup at compile time. The way around it would be to add a user handler for the event :-

    and then have the user defined interrupt handler jump to the actual interrupt handler required :-

    #include "hal_data.h"

    void r_icu_isr (void);

    volatile bool g_use_irq4 = false;

    void user_irq_4_handler(void)
    {
        if (true == g_use_irq4)
        {
            r_icu_isr(); //Interrupt handler for External IRQ Driver
        }
        else
        {
                       // Handler for different Interrupt populated here
        }

    }

  • Hi jeremy,

    I've tried the setting as you said.

    But I couldn't find the isr I've created anywhere in the generated code.

    Also, Correct me If I'm wrong, if somehow my created ISR runs, my goal has been achieved "the device waking up". But I seriously doubt if it executes, like how CPU(in sleep mode) knows if there's any interrupt occurred. 

    I've tried this enabling isr...with some assumptions. I've removed some peripherals from my configuration, to see which IRQn_TYPE number is assigned to IRQ4. then I tried using that number to open external irq and enable it. But it doesn't seem to work.

    memcpy(&newcfg,&g_external_irq1_cfg,sizeof(external_irq_cfg_t));
    newcfg.irq = (IRQn_Type)28;  

    R_ICU_ExternalIrqOpen(&g_external_irq1_ctrl, &newcfg);    /* IRQ4 enabled on CAN rx line */

    R_ICU_ExternalIrqEnable(&g_external_irq1_ctrl);

    Is there a way enable external irq while running the code? 

  • Hi Viswa-

    Is this still an issue for you? Let us know if it is or if you found a solution.