How to: RL78/G13 snooze and stop mode configuration

Hello,

I am using IAR EW 4.21.1. I have a R5F100SL targetboard, for which i want to test the snooze and stop mode capabilities. The plan is to use the RTC to wake up every 15 minutes to sample the ADC. If the ADC is above 3.5 Volts, go to normal operation and continuously sample the ADC. If the voltage is not above 3.5V return to stop mode and wake up again 15 minutes later.

I have looked at the ADC snooze example but cant seem to get it to work. With that i mean, when i enter debug, i can see that the ADC never gets initialized.

I have tried on my own, this is my code so far:

    PIOR = 0x00U;
    R_PORT_Create();
    R_CGC_Create();

    
    LED01 = LEDOFF;
    LED02 = LEDOFF;
    
    ADCEN = 1U;  /* supply AD clock */
    ADM0 = _00_AD_ADM0_INITIALVALUE;  /* disable AD conversion and clear ADM0 register */
    ADMK = 1U;  /* disable INTAD interrupt */
    ADIF = 0U;  /* clear INTAD interrupt flag */
    /* Set INTAD low priority */
    ADPR1 = 1U;
    ADPR0 = 1U;
    /* Set ANI0 pin as analog input */
    PM2 |= 0x01U;
    ADM0 = _08_AD_CONVERSION_CLOCK_32 | _00_AD_TIME_MODE_NORMAL_1;
    ADM1 = _C0_AD_TRIGGER_HARDWARE_WAIT | _20_AD_CONVMODE_ONESELECT | _03_AD_TRIGGER_INTIT;
    ADM2 = _00_AD_POSITIVE_VDD | _00_AD_NEGATIVE_VSS | _00_AD_WAKEUP_OFF | _00_AD_AREA_MODE_1 | _01_AD_RESOLUTION_8BIT;
    ADUL = 0xCC; // Set upper limit to 204 /255
    ADLL = 0x99; // Set lower limit to 153/255
    ADS = _00_AD_INPUT_CHANNEL_0;
    ADCE = 1U;    /* enable AD comparator */
    
    //Now ADC should have been created
    
    ADIF = 0U;    /* clear INTAD interrupt flag */
    ADMK = 0U;    /* enable INTAD interrupt */
    
    //Now the ADC should also have been started.
    
    AWC = 1;
    STOP();
    AWC = 0;
    LED01 = LEDON;
    ADIF = 0U;
    ADM2 = _00_AD_WAKEUP_OFF;
   

Hope you can help me out or at least point me in the right direction.

Best regards, Mads

Parents
  • Hello,

    Thanks for posting your question online.

    I have created in the past a simple demo project on ADC snooze mode where the device wakes up from RTC interrupt.

    The example is on e2studio. Could you check if it could be useful ?

    I also recommend using the generated drivers of Code Generator. It saves a lot of time and gets you started on a basic level quickly.

    G13_ADC_Snooze.zip

    Regards

  • Hello,

    Thank you for your very quick reply.

    I have downloaded and opened your code in E2Studio. I have no problem with using E2 for testing, but later i will switch over to IAR again. The code seems to work fine on my targetboard.

    I do however, have a little trouble understanding what the code does. For example if a change ADLL to 0xCC and supply the ADC input pin, with 1V, no interrupt should be triggered right?

    Also how to make the CPU stay in snooze/stop mode until ADC readings are >> ADUL. 

    What exactly does the RTC do and how to use it to wake up in specific intervals?

    Thanks you for your help so far.

    Best regards,
    Mads

  • Ok, so the RTC via INTRTC triggers the ADC, while in STOP mode, correct? Then in snooze mode, the ADC will generate an interrupt via INTAD, IF the input voltage is inside the specified window of ADLL and ADUL

    Where/how do i manage for how often the RTC wakes up the device?

    Best regards, Mads

  • Without a sub-clock oscillator (fSUB), you can only configure INTRTC as a constant period interrupt:

    If you have a sub-clock:

    you can have INTRTC as alarm interrupt too:

  • Where is the auto-generator tool in E2 studio?

  • Hello again,

    I have a question regarding the INTAD.

    In the while loop:

        {
        	AWC = 1U; 	// Enable AD Snooze mode
    
        	STOP();		// Go in STOP mode
    
        	AWC = 0; 	// Disable AD Snooze mode
    
        	R_ADC_Get_Result(&adc_result); // Read ADC value
    
        }

    When do i determine when the INTAD gets triggered and correspond accordingly?

    I can see that i can change the INTRTC to wake up the ADC, but i can't figure out where/how to see that the INTAD gets genereated, if the input voltage is inside the specified window of ADLL and ADUL.

    Hope you can help me out once again

    Best regards, Mads

  • When INTAD is triggered, the corresponding service routine will be called:

  • Hello again,

    I am still trying to wrap my head around, exactly how this works.

    First of, here is what i am doing at the moment:

    RTC is making a hardwaretrigger every second, this seems to work fine.

    ADC is configured to area mode 1, whit ADLL = 1V and ADUL = 2V. 

    I have put a breakpoint inside r_adc_interrupt() which works when i supply between 1-2V on the ADC input pin.

    If i resume the main while loop, while supplying 3V to the ADC pin, the interrupt does not get triggered, as it is supposed to. However, if i change the supply to the ADC pin to 1.5V, the program never breaks.

    So my question is, why does the program break when i start with 1.5V supply, but not when i change the supply into the 1-2V range, while the program is running? Have i misunderstood the whole concept?

    Your help is very much appreciated.

    Best regards, Mads

  • Hello,

    I think in my attached example the operation mode is one-shot select mode- not continuous mode- so the channel will be converted only once.

    If you want continuous mode you need to change the setting on ADC configurations:

    Some information on operation modes:

    They are explained in detail on hardware manual.

  • Hello,

    We unfortunately have some problems with understanding this SNOOZE/STOP mode. I have 2 questions/topics for you:

    1. While debugging, If i supply the ADC within ADLL and ADUL, i trigger the interrupt routine 'r_adc_interrupt' if i have a breakpoint at AWC = 1U; in the while loop and a breakpoint in the 'r_adc_interrupt' itself. However, if i remove the breakpoint at the AWC = 1U; in the while loop, i do not trigger the ISR, however i can see that ADCR reads the correct value. Why is this happening?
    See code below.

    void main(void)
    {
        R_MAIN_UserInit();
        /* Start user code. Do not edit comment generated here */
          while (1U)
          {
    
              AWC = 1U; 	// Enable AD Snooze mode
    
              STOP();		// Go in STOP mode
    
              AWC = 0; 	// Disable AD Snooze mode
    
              R_ADC_Get_Result(&adc_result); // Read ADC value
    
          }
    
        /* End user code. Do not edit comment generated here */
    }
    #pragma vector = INTAD_vect
    __interrupt static void r_adc_interrupt(void)
    {
            LED01 = LEDON;
    	ADIF = 0U;
        /* End user code. Do not edit comment generated here */
    }
    /***********************************************************************************************************************
    * Function Name: R_MAIN_UserInit
    * Description  : This function adds user code before implementing main function.
    * Arguments    : None
    * Return Value : None
    ***********************************************************************************************************************/
    void R_MAIN_UserInit(void)
    {
        /* Start user code. Do not edit comment generated here */
        EI();
         
        R_ADC_Start();
        R_RTC_Start();
    
        // ANI0 = P117
        LED01 = LEDOFF;
        LED02 = LEDOFF; 
        /* End user code. Do not edit comment generated here */
    }


    2. I have flashed the targetboard with the code and disconnected the debugger. If i observe the power consumption, i get even more confused. See picture below, what is happening for around 3 seconds when the consumption is high? It does not matter if i supply the ADC or not, the 'r_adc_interrupt' does not seem to get triggered anyway. What is going on?




    Once again, hope you can help out. If You need anymore information, let me know.

    Best regards, Mads

  • 1. Try to change the optimization level to Debug Precedence.

    2. The interrupt may not get triggered, but the ADC is waking up back to normal mode from the wake-up interrupt. The supply current is still too high though, you may need to take care of the floating pins.

    Any input pins should be connected to pull up or pull down resistor with Vcc or Vss.

Reply
  • 1. Try to change the optimization level to Debug Precedence.

    2. The interrupt may not get triggered, but the ADC is waking up back to normal mode from the wake-up interrupt. The supply current is still too high though, you may need to take care of the floating pins.

    Any input pins should be connected to pull up or pull down resistor with Vcc or Vss.

Children
No Data