This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Guys,
I've spent literally 5 hours trying to figure out why my code doesn't work on F5529. It seems that even though I start the ADC12 conversion the ISR isn't triggered and the CPU won't wake up from the LPM. Code snippets are below:
[here set the timer to 0 and call the get_adc_data(), ADC reading to be done on A0, P6.0, ref to AVcc, single samples in the software loop] int get_adc_data() { int adcVal[AS_NUM_OF_ADC_READS]; int i, adcValAvgPrev, adcValAvg; P6SEL |= BIT0; ADC12CTL0 = ADC12ON + ADC12SHT02; ADC12IE = 0x01; ADC12CTL1 = ADC12CONSEQ_0; ADC12CTL2 |= ADC12RES_1; // 10-bit resolution ADC12MCTL0 |= ADC12INCH_0 + ADC12SREF_0; // V(R+) = AVCC and V(R-) = AVSS ADC12CTL0 |= ADC12ENC; for (i = 0; i < AS_NUM_OF_ADC_READS; i++) { uart_puts("ADC before LPM\n\r"); ADC12IE |= 0x01; __bis_status_register(LPM0_bits + GIE); uart_puts("ADC after LPM\n\r"); adcVal[i] = ADC12MEM0; adcValAvgPrev = !i ? adcVal[i] : adcValAvg; // if it's the first iteration then adcValAvgPrev = adcVal[0] adcValAvg = adcValAvgPrev + ((adcVal[i] - adcValAvgPrev) / i); } ADC12CTL0 &= ~ADC12ENC; return adcValAvg; } #pragma vector = ADC12_VECTOR __interrupt void ADC12_ISR(void) { __bic_status_register_on_exit(CPUOFF); } #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer0_A0(void) { if (!(++timer_ms % 5000)) { am_probe_finished_flag = 1; __bic_status_register_on_exit(CPUOFF); } }
I know that multiple readings can be done better with ADC12MEMx, but this is not a problem here, I will fix it once I have ISR being triggered. Can you please take a short look to see what may be wrong? I have no idea...
Best Regards,
tml
I wonder why you see the 'ADC after LPM' message at all.
If the ADC triggers an interrupt ad your ADC ISR is called, it will exit LPM. However, it foes not clear the interrutp (you don't read ADC10MEM in your ISR or clear the ADC10IFG0 bit). So the ISR will be called again immediately after exiting, and main() cannto continue (only the timer ISR will interrupt this eternal loop).
It is possible too (I never tested or checked) that the CPU will execute one single instruction between each ISR call. In this case, main would very slooowly continue to execute to the point where the 'ADC after LPM' message output is started (which then will happen fast, if it is interrupt driven with higher priority than ADC interrupt). And the 5s delay until then is pure coincidence.
Clear the ADC10IFG0 bit or the ADC10IE0 bit inside your ISR, or do an __bic_SR_register_on_exit(CPUOFF|GIE); to prevent further interrupts until you have read ADC12MEM0.
Also, when you got a result, you should deactivate the timer timeout somehow. Else sooner or later the timer will exit LPM (if you're in it at all at this moment) and flag a timeout, even if you are waiting for something else in LPM somewhere else in your code.
Hi,
I finally found the issue. The key to the success is:
28.2.10.1 ADC12IV, Interrupt Vector Generator of SLAU208M:
This is common to all MSP interrupts. IIRC, there are only two exceptions: the timer CCR0 interrupts (which have only one interrupt source and the CCR0.CCIFG bit is auto-cleared when the ISR is started) and the ADC10 interrupt (same reason).tml said:"ADC12IFGx bits are reset automatically by accessing their associated ADC12MEMx register or may be reset with software."
**Attention** This is a public forum