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

  • 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

  • The INTRTC interrupt on this example wakes up the device every 1 second and is also the hardware trigger interrupt for the ADC to scan the specified channel.

    if a change ADLL to 0xCC and supply the ADC input pin, with 1V, no interrupt should be triggered right?

    Yes, if the input voltage is outside the specified window, not INTAD interrupt should be generated.

    The device will stay in STOP mode until a wake up source occurs. Please note the following:

  • 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