The TI E2E™ design support forums will undergo maintenance from Sept. 28 to Oct. 2. If you need design support during this time, contact your TI representative or open a new support request with our customer support center.

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.

MSP430FR2522: MSP430FR2422 porting to MSP430FR2522, ADC issue

Part Number: MSP430FR2522
Other Parts Discussed in Thread: MSP430FR2422

Hi,

I'm porting my application from the MSP430FR2422 to the MSP430FR2522. Everything seems to be working properly except for the ADC.

I'm working with two ADC channels, A0 and A4. They way I switch between channels is by calling a StartADCConversion function which configures the channel and starts the conversion. 

Then I get the ADC reading on the ADC interrupt and store it on the structure I passed on the StartADCConversion function.

The issue I'm having is that when I start the conversion with a different channel the ADC gets random readings. Please notice that I wait at least 5 milliseconds between readings.

Code worked fine on the MSP430FR2422 so I'll like to know what is different from the MSP430FR2522.

void StartADCConversion(adc_input_vrbls_t * channel)
{
    //Configure Memory Buffer
    /*
     * Base Address for the ADC Module
     * Input A6 as first multiple sample channel
     * Use positive reference of AVcc
     * Use negative reference of AVss
     */
    ADC_configureMemory(ADC_BASE,
            channel->AdcChannel,
            ADC_VREFPOS_AVCC,
            ADC_VREFNEG_AVSS);

    adcReading = channel;

    //Enable and Start the conversion
    //in Multiple-Channels, Single Conversion Mode
    ADC_startConversion(ADC_BASE,
                        ADC_SINGLECHANNEL);

    _BIS_SR(GIE);
}

  • Hi Stanley,

    Can you tell me more about how you configured the devices? It would also help if you provided the rest of the code.

    Thanks,

    Urica Wang

  • Hi Urica,

    This is how I configure the ADC. And below you can also find the interrupt routine.

    Then on the main loop I call StartADCConversion whenever I need a reading from the specific channel. I allow around 5-30ms between readings.

    void StartADCConversion(adc_input_vrbls_t * channel)
    {
        //Configure Memory Buffer
        /*
         * Base Address for the ADC Module
         * Input A6 as first multiple sample channel
         * Use positive reference of AVcc
         * Use negative reference of AVss
         */
        ADC_configureMemory(ADC_BASE,
                channel->AdcChannel,
                ADC_VREFPOS_AVCC,
                ADC_VREFNEG_AVSS);
    
        adcReading = channel;
    
        //Enable and Start the conversion
        //in Multiple-Channels, Single Conversion Mode
        ADC_startConversion(ADC_BASE,
                            ADC_SINGLECHANNEL);
    
        _BIS_SR(GIE);
    }
    
    void configADC(void)
    {
        //Initialize the ADC Module
        /*
         * Base Address for the ADC Module
         * Use internal ADC bit as sample/hold signal to start conversion
         * USE MODOSC 5MHZ Digital Oscillator as clock source
         * Use default clock divider of 1
         */
        ADC_init(ADC_BASE,
            ADC_SAMPLEHOLDSOURCE_SC,
            ADC_CLOCKSOURCE_ADCOSC,
            ADC_CLOCKDIVIDER_1);
    
        ADC_enable(ADC_BASE);
    
        /*
         * Base Address for the ADC Module
         * Sample/hold for 16 clock cycles
         * Enable Multiple Sampling
         */
        ADC_setupSamplingTimer(ADC_BASE,
                ADC_CYCLEHOLD_16_CYCLES,
                ADC_MULTIPLESAMPLESENABLE);
    
        ADC_clearInterrupt(ADC_BASE,
                ADC_COMPLETED_INTERRUPT);
    
        //Enable Memory Buffer interrupt
        ADC_enableInterrupt(ADC_BASE,
                ADC_COMPLETED_INTERRUPT);
    
    }
    
    
    //ADC10 interrupt service routine
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=ADC_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(ADC_VECTOR)))
    #endif
    void ADC_ISR (void)
    {
        switch (__even_in_range(ADCIV,12)){
            case  0: break; //No interrupt
            case  2: break; //conversion result overflow
            case  4: break; //conversion time overflow
            case  6: break; //ADC10HI
            case  8: break; //ADC10LO
            case 10: break; //ADC10IN
            case 12:        //ADC10IFG0
                adcReading->Voltage = ADC_getResults(ADC_BASE);
                adcReading->ReadingReady = true;
              break;
            default: break;
        }
    }

  • Hi Stanley,

    Thanks for clarifying. Based on the driverlib API documentation, you may need to call ADC_disableConversions() to reinitialize the ADC/reconfigure a memory buffer control when you switch channels. I also see that you are using single-channel single-conversion mode which is sampled once, but you have multiple samples enabled.

    Regards,

    Urica Wang

**Attention** This is a public forum