Hello,
I've had issues with the ADC getting the status of a conversion finished. I was reading the MEMRESIFG bits from the CPU_INT.RIS register for the channels I care about, to know when a conversion on a channel finished, via DL_ADC12_getRawInterruptStatus(). Then I would read the result of the conversion with DL_ADC12_getMemResult(), which according to the TRM should clear the MEMRESIFG bit. However this does not happen. Bit remains set and next conversion gives me an invalid value because MEMRESIFG is already set when starting next conversion, so my SW ends it prematurely.
I looked at adc12_single_conversion SDK example which works correctly, because it uses DL_ADC12_getPendingInterrupt() and not DL_ADC12_getRawInterruptStatus(), so it seems the bit is cleared as soon as IIDX register is read. However I cannot use that in my application since it won't always give me the status of the exact channel that I want depending on the state of the system. I modified the SDK example to use DL_ADC12_getRawInterruptStatus() instead, and sure enough, the MEMRESIFG bit is never cleared when reading the converison result register.
See below the modified SDK example to reproduce this:
/*
* Copyright (c) 2020, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ti_msp_dl_config.h"
volatile bool gCheckADC;
volatile uint16_t gAdcResult;
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
gCheckADC = false;
while (1) {
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC) {
__WFE();
}
gAdcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
if (gAdcResult > 0x7ff) {
DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
} else {
DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
}
gCheckADC = false;
DL_ADC12_enableConversions(ADC12_0_INST);
}
}
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getRawInterruptStatus(ADC12_0_INST, DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED)) {
case DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED:
gCheckADC = true;
break;
default:
break;
}
}
Can you please confirm if you see this behavior on TI side?
Thank you,
Florin