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.

MSP430FR5869: ADC sometimes stop convert in Repeat-signal-channel mode

Part Number: MSP430FR5869

Hi:

I'm using ADC12 in Repeat-signal-channel mode,the ADC12SHSx is 0, the clock source is SMCLK which is 8Mhz and adc clock divider is 1MHz.

And I'm using DMA to transfer adc result, the low power mode is LPM3. 

For most time, the MCU works fine, but sometime it stoped.

In debug mode, I find ADC12 stop convert with ADC12SC keep 1 (datasheet says ADC12SC is reset automatically), ADC12BUSY keep 1,

and DMA doesn't transfer any data.

Can anyone help me solve this problem? thanks very much!

  • Hi,

    Are you triggering the ADC manually, or are you using timer trigger mode? Either way, it sounds like this might be the ADC42 errata. Please see the erratasheet on the product page for a full description and workaround, and please let me know if that solves the issue.

    Regards,
    Nathan
  • I'm using manual trigger mode, and I have already seen the erratasheet, but I don't thought it's the ADC42 errata,

    because everytime after ADC conversion is done,  I reset the ADC12ENC,  then poll ADC12BUSY until it's reset, after that I disable the ADC12.

    The next time I use ADC, I re-enable ADC module and re-enable conversion.

    	ADC12_B_disableConversions (ADC12_B_BASE, ADC12_B_COMPLETECONVERSION);
    
    	while (ADC12_B_isBusy(ADC12_B_BASE))
    	{
    	    vTaskDelay (1);
    	}
    	ADC12_B_disable (ADC12_B_BASE);

  • Hi,

    Could you also please provide the code where you re-enable the ADC and conversions (ans start conversions, I am assuming)? Any code related to the ADC would be useful in trying to figure out what is going wrong here.

    Regards,
    Nathan
  • Hi,

    There is a good news, since changing the low power mode from LPM3 to LPM2, the device has worked fine for 2.5 days.

    But I'm not sure the problem has been totally solved, I will keep test it.

    Below is my init code:

    COMMON_initADC (channel, refSource);
    COMMON_initDMA ();
    
    ADC12_B_startConversion(ADC12_B_BASE, ADC12_B_START_AT_ADC12MEM0, ADC12_B_REPEATED_SINGLECHANNEL);


    function COMMON_initADC:

    static	void	COMMON_initADC (uint8_t channel, uint16_t refSource)
    {
    
    		ADC12_B_initParam initParam;
    		ADC12_B_configureMemoryParam configParam;
    
    		initParam.sampleHoldSignalSourceSelect = ADC12_B_SAMPLEHOLDSOURCE_SC;
    		initParam.clockSourceSelect = ADC12_B_CLOCKSOURCE_SMCLK;		//	8MHz
    		initParam.clockSourcePredivider = ADC12_B_CLOCKPREDIVIDER__1;
    		initParam.clockSourceDivider = ADC12_B_CLOCKDIVIDER_8;			//	1M Hz
    		initParam.internalChannelMap = ADC12_B_TEMPSENSEMAP;
    		ADC12_B_init (ADC12_B_BASE, &initParam);
    
    		ADC12_B_enable (ADC12_B_BASE);
    
    
    		ADC12_B_setupSamplingTimer(ADC12_B_BASE,
    									ADC12_B_CYCLEHOLD_384_CYCLES,
    									ADC12_B_CYCLEHOLD_384_CYCLES,
    									ADC12_B_MULTIPLESAMPLESENABLE);
    
    
    		configParam.memoryBufferControlIndex = ADC12_B_MEMORY_0;
    		configParam.inputSourceSelect = channel;
    		configParam.refVoltageSourceSelect = refSource;
    		configParam.endOfSequence = ADC12_B_NOTENDOFSEQUENCE;
    		configParam.windowComparatorSelect = ADC12_B_WINDOW_COMPARATOR_DISABLE;
    		configParam.differentialModeSelect = ADC12_B_DIFFERENTIAL_MODE_DISABLE;
    		ADC12_B_configureMemory(ADC12_B_BASE, &configParam);
    
    }

    function COMMON_initDMA:

    static	void	COMMON_initDMA (void)
    {
    		DMA_initParam	dmaParam;
    
    		dmaParam.channelSelect = DMA_CHANNEL_2;
    		dmaParam.transferModeSelect = DMA_TRANSFER_SINGLE;
    		dmaParam.transferSize = OVERSAMPLE_BUFFER_SIZE;
    		dmaParam.triggerSourceSelect = DMA_TRIGGERSOURCE_26;	// adc12 end of conversion
    		dmaParam.transferUnitSelect = DMA_SIZE_SRCWORD_DSTWORD;
    		dmaParam.triggerTypeSelect = DMA_TRIGGER_HIGH;
    		DMA_init (&dmaParam);
    		DMA_setSrcAddress (DMA_CHANNEL_2, ADC12_B_getMemoryAddressForDMA(ADC12_B_BASE, ADC12_B_MEMORY_0), DMA_DIRECTION_UNCHANGED);
    		DMA_setDstAddress (DMA_CHANNEL_2, (uint32_t)&measureOversampleBuffer[0], DMA_DIRECTION_INCREMENT);
    
    		DMA_clearInterrupt (DMA_CHANNEL_2);
    		DMA_enableInterrupt (DMA_CHANNEL_2);
    
    
    		ADC12_B_getResults (ADC12_B_BASE, ADC12_B_MEMORY_0);
    		DMA_enableTransfers (DMA_CHANNEL_2);
    }

  • Hi,

    In LPM3, SMCLK is turned off unless requested. You are using SMCLK as the source for the ADC, so this is likely why you no longer see the issue in LPM2. If you would like to use LPM3, I would suggest you look into using ACLK instead, though this will be a much slower clock.

    Regards,
    Nathan
  • Hi:

    What I don't understand is why the SMCLK turned off while ADC was requesting it?

    It looks just like the ADC41 errata except the clock source and the trigger source doesn't match.

  • Hi,

    I agree that if the ADC is requesting SMCLK, that it should be turned on, though this isn't ideal and could be causing an issue (though not one that is known). If you are using one of the timers listed in the ADC41 errata, then this could be the issue. I realize you are using SMCLK, not ADC12OSC. Could you please post your clock initialization code so I can see what SMCLK is being sourced from?

    Regards,
    Nathan
  • Hi:

    I just find I'm using DCOCLK instead of HFXTCLK as clock source, but I should use the HFXTCLK, it's a mistake.

    Althought is it the reason ADC stopped?

    /*
     * Clock System Initialization
     */
    void Clock_init(void)
    {
        FRAMCtl_configureWaitStateControl (FRAMCTL_ACCESS_TIME_CYCLES_0);
    
        // Set DCO frequency to default 8MHz
        CS_setDCOFreq(CS_DCORSEL_0, CS_DCOFSEL_6);
    
        CS_setExternalClockSource (32768, 8000000L);
    
    #if 0
        CS_turnOnHFXT (HFXTDRIVE_3);
    
    //         Configure MCLK to 8 Mhz, and SMCLK to 8 Mhz
        CS_initClockSignal(CS_MCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
        CS_initClockSignal(CS_SMCLK, CS_HFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    
    #else    // Configure MCLK to 8 Mhz, and SMCLK to 8 Mhz
        CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
        CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    #endif
    
        // Intializes the XT1 crystal oscillator
        CS_turnOnLFXT(CS_LFXT_DRIVE_3);
    
        CS_initClockSignal(CS_ACLK, CS_LFXTCLK_SELECT, CS_CLOCK_DIVIDER_1);
    }
    

  • Hi,

    If you are using DCOCLK, that indicates that this is not the ADC41 errata. However, it is possible that using the DCO, which will be less consistent than an external crystal, could be causing your issue, especially because you only see it occasionally. Assuming you have a high frequency crystal connected, please try using HFXTCLK and see if you still see the issue at all.

    Regards,
    Nathan

**Attention** This is a public forum