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.
Mads said: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 ADULWhere/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?
It is the Code Generator:
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 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
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 */ }
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.