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.

SIMPLELINK-MSP432-SDK: Wrong ADC-Port extraction on ADCBuf dirver.

Part Number: SIMPLELINK-MSP432-SDK

Let's assume i have a configuration for the ADCBuf like mine, where the ADCChannel are mixedup and not sorted from 0 to 31.

Also, there are many analog inputs left for the channel configuration.

ADCBufMSP432_Channels adcBuf0MSP432Channels[MSP_EXP432P401R_ADCBUF0CHANNELCOUNT] = {

    {

        .adcPin = ADCBufMSP432_P4_0_A13,

        .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,

        .refVoltage = 2500000

    },

    {

        .adcPin = ADCBufMSP432_P5_3_A2,

        .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,

        .refVoltage = 1450000

    },

    {

        .adcPin = ADCBufMSP432_P5_1_A4,

        .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,

        .refVoltage = 1450000

    },

    {

        .adcPin = ADCBufMSP432_P5_2_A3,

        .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,

        .refVoltage = 1450000

    },

    {

        .adcPin = ADCBufMSP432_P4_0_A13,

        .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,

        .refVoltage = 1450000

    }

};

So if I am using the ADCBufChannel0 which is referred to the analog port A13 for the mux on Port 4.0.

The pin will be set as expected, but the selection of the analog input for the multiplexer not.

I found the code part where it fails to configure the analog port for the given channel.

        MAP_ADC14_configureConversionMemory(ADC_MEM0,

                refSource,

                conversions->adcChannel, false);

 

        channelInt = ADC_INT0;

Normal the pin configuration is like:

#define ADCBufMSP432_P4_0_A13 ((13 << 10) | 0x0340) /* ch 13, port 4, pin 0 */

So the analog input information is stored 10 bits above the pin configuration.

so i added a single line which now extract this information and give this to the conversion configuration.

uint8_t adcChannel = (hwAttrs->channelSetting[conversions->adcChannel].adcPin >> 10);

MAP_ADC14_configureConversionMemory(ADC_MEM0,
refSource,
adcChannel, false);

channelInt = ADC_INT0;

Let me know if I am wrong with my fix but otherwise i have to list all adcports until this one which i want do use.

Bests

Richard

 

  • Hello Richard,

    Could you please share your MSP_EXP432P401R_ADCBufChannelName enmu.

    typedef enum MSP_EXP432P401R_ADCBufChannelName {
        MSP_EXP432P401R_ADCBUFCHANNEL0 = 0,
        MSP_EXP432P401R_ADCBUFCHANNEL1,
    
        MSP_EXP432P401R_ADCBUFCHANNELCOUNT
    } MSP_EXP432P401R_ADCBufChannelName;

    Also it looks like ADCBufMSP432_P4_0_A13 is defined twice in adcBufMSP432Channels

        {
    
            .adcPin = ADCBufMSP432_P4_0_A13,
    
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    
            .refVoltage = 1450000
    
        }
    

    Thanks,

     David

  • Hello David,

    sure here is my enum and config:

    ADCBufMSP432_Channels adcBuf0MSP432Channels[MSP_EXP432P401R_ADCBUF0CHANNELCOUNT] = {
        {
            .adcPin = ADCBufMSP432_P5_4_A1,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_3_A2,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_1_A4,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_2_A3,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P4_0_A13,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        }
    };
    
    /* ADC configuration structure */
    const ADCBufMSP432_HWAttrs adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .intPriority =  ~0,
            .channelSetting = adcBuf0MSP432Channels,
            .adcTimerTriggerSource = ADCBufMSP432_TIMERA0_CAPTURECOMPARE2
        }
    };
    
    extern ADCBuf_FxnTable ADCBufMSP432FIX_fxnTable;
    
    const ADCBuf_Config ADCBuf_config[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .fxnTablePtr = &ADCBufMSP432FIX_fxnTable,
            .object = &adcbufMSP432Objects[MSP_EXP432P401R_ADCBUF0],
            .hwAttrs = &adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUF0]
        }
    };
    typedef enum MSP_EXP432P401R_ADCBufName {
        MSP_EXP432P401R_ADCBUF0 = 0,
        MSP_EXP432P401R_ADCBUFCOUNT
    } MSP_EXP432P401R_ADCBufName;
    
    /*!
     *  @def    MSP_EXP432P401R_ADCBuf0ChannelName
     *  @brief  Enum of ADCBuf channels on the MSP_EXP432P401R dev board
     */
    typedef enum MSP_EXP432P401R_ADCBuf0ChannelName {
        MSP_EXP432P401R_ADCBUF0CHANNEL0 = 0,
        MSP_EXP432P401R_ADCBUF0CHANNEL1,
        MSP_EXP432P401R_ADCBUF0CHANNEL2,
        MSP_EXP432P401R_ADCBUF0CHANNEL3,
        MSP_EXP432P401R_ADCBUF0CHANNEL4,
        MSP_EXP432P401R_ADCBUF0CHANNELCOUNT
    } MSP_EXP432P401R_ADCBuf0ChannelName;

    Hope this will help.

    Bests 

    Richard

  • The both definition was for testing purpose.
    I forgot to clean it up before i posted here, sorry for that misstake

    Richard
  • Hi Richard,

    Unfortunately, I have not been able to reproduce this behavior. Could you please also share your ADC code or your complete project??

    Thanks,

    David
  • I can give u my instruction which i do.

    ADCBuf_Conversion conversion;
    
    conversion.adcChannel = MSP_EXP432P401R_ADCBUF0CHANNEL0;
    conversion.sampleBuffer = sampleBuffer;
    conversion.samplesRequestedCount = numRxBytes;
    
    if(ADCBuf_convert(h->ADC_h, &conversion, 1) != ADCBuf_STATUS_SUCCESS) {
    pthread_mutex_unlock(&(adc_mutex[h->dev]));
    return -4;
    }
    
    if(ADCBuf_convertAdjustedToMicroVolts(h->ADC_h, h->dev, sampleBuffer, rxBuffer, numRxBytes)) {
    pthread_mutex_unlock(&(adc_mutex[h->dev]));
    return -5;
    }

    this is my call, just for notification my configuration and my enum:

    /*
     *  =============================== ADCBuf ===============================
     */
    #include <ti/drivers/ADCBuf.h>
    #include <ti/drivers/adcbuf/ADCBufMSP432.h>
    
    /* ADC objects */
    ADCBufMSP432_Object adcbufMSP432Objects[MSP_EXP432P401R_ADCBUFCOUNT];
    
    ADCBufMSP432_Channels adcBuf0MSP432Channels[MSP_EXP432P401R_ADCBUF0CHANNELCOUNT] = {
        {
            .adcPin = ADCBufMSP432_P5_4_A1,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_3_A2,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_1_A4,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P5_2_A3,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        },
        {
            .adcPin = ADCBufMSP432_P4_0_A13,
            .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
            .refVoltage = 1450000
        }
    };
    
    /* ADC configuration structure */
    const ADCBufMSP432_HWAttrs adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .intPriority =  ~0,
            .channelSetting = adcBuf0MSP432Channels,
            .adcTimerTriggerSource = ADCBufMSP432_TIMERA0_CAPTURECOMPARE2
        }
    };
    
    extern ADCBuf_FxnTable ADCBufMSP432FIX_fxnTable;
    
    const ADCBuf_Config ADCBuf_config[MSP_EXP432P401R_ADCBUFCOUNT] = {
        {
            .fxnTablePtr = &ADCBufMSP432FIX_fxnTable,
            .object = &adcbufMSP432Objects[MSP_EXP432P401R_ADCBUF0],
            .hwAttrs = &adcbufMSP432HWAttrs[MSP_EXP432P401R_ADCBUF0]
        }
    };
    
    const uint_least8_t ADCBuf_count = MSP_EXP432P401R_ADCBUFCOUNT;
    /*!
     *  @def    MSP_EXP432P401R_ADCBufName
     *  @brief  Enum of ADC hardware peripherals on the MSP_EXP432P401R dev board
     */
    typedef enum MSP_EXP432P401R_ADCBufName {
        MSP_EXP432P401R_ADCBUF0 = 0,
        MSP_EXP432P401R_ADCBUFCOUNT
    } MSP_EXP432P401R_ADCBufName;
    
    /*!
     *  @def    MSP_EXP432P401R_ADCBuf0ChannelName
     *  @brief  Enum of ADCBuf channels on the MSP_EXP432P401R dev board
     */
    typedef enum MSP_EXP432P401R_ADCBuf0ChannelName {
        MSP_EXP432P401R_ADCBUF0CHANNEL0 = 0,
        MSP_EXP432P401R_ADCBUF0CHANNEL1,
        MSP_EXP432P401R_ADCBUF0CHANNEL2,
        MSP_EXP432P401R_ADCBUF0CHANNEL3,
        MSP_EXP432P401R_ADCBUF0CHANNEL4,
        MSP_EXP432P401R_ADCBUF0CHANNELCOUNT
    } MSP_EXP432P401R_ADCBuf0ChannelName;

    The problem is, that i want to select the adc port a1 with my ADCBufChannel 0. But if i am setting the conversion property adcChannel to ADCBufChannel0 it selects the wrong analog port. If i am trying to set adcChannel to ADC14_INCH_1 which would be the right one. It uses the configuration of the ADCBufChannel1 which it is normal for this implemtation. I tried to, fix this problem by my workaround. But this based on how i understood to using the driver. Otherwise can u give me an example where the ADCBufChannel config array is like mine and how to use it right.

    Bests 

    Richard

  • So i try it again, the problem is still present.

    Let's take some code of your driver maybe it will be clear.

    /*
     *  ======== primeConvert ========
     */
    static void primeConvert(ADCBufMSP432_Object *object,
            ADCBufMSP432_HWAttrs const *hwAttrs, ADCBuf_Conversion *conversions,
            uint_fast8_t channelCount)
    {
        uint32_t channelInt;
        uint32_t memory = ADC_MEM0;
        uint_fast8_t i = 0;
    
        /* Store the conversions struct array into object */
        object->conversions = conversions;
        /* Store the channel count into object */
        object->channelCount = channelCount;
    
        /* Config GPIOs for ADC channel analog in*/
        for (i = 0; i < channelCount; i++){
            /* Config GPIO for ADC channel analog input */
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(
             PinConfigPort(hwAttrs->channelSetting[i].adcPin),
             PinConfigPin(hwAttrs->channelSetting[i].adcPin),
             PinConfigModuleFunction(hwAttrs->channelSetting[i].adcPin));
        }
    
        //TODO: For multiple channels sampling, ref source and sampling duration should be same
        /* Set reference voltage for current conversion */
        uint32_t refSource = hwAttrs->channelSetting[conversions[0].adcChannel].refSource;
        uint32_t refVolts = hwAttrs->channelSetting[conversions[0].adcChannel].refVoltage;
        uint16_t refVoltsDef;
        if (refSource == ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS) {
    
            switch(refVolts) {
            case 1200000:
                refVoltsDef = REF_A_VREF1_2V;
                break;
            case 1450000:
                refVoltsDef = REF_A_VREF1_45V;
                break;
            case 2500000:
                refVoltsDef = REF_A_VREF2_5V;
                break;
            default:
                break;
            }
    
            MAP_REF_A_setReferenceVoltage(refVoltsDef);
            MAP_REF_A_enableReferenceVoltage();
        }
    
        /* ADC single channel sampling */
        if (channelCount == 1) {
            if (conversions->samplesRequestedCount > 1) {
                MAP_ADC14_configureSingleSampleMode(ADC_MEM0, true);
            }
            else {
                MAP_ADC14_configureSingleSampleMode(ADC_MEM0, false);
            }
    
            refSource = hwAttrs->channelSetting[conversions->adcChannel].refSource;
    
            MAP_ADC14_configureConversionMemory(ADC_MEM0,
                    refSource,
                    conversions->adcChannel, false);
    
            channelInt = ADC_INT0;
    
            /* Store the samples count into object */
            object->conversionSampleBuf = conversions->sampleBuffer;
            object->conversionSampleCount = conversions->samplesRequestedCount;
            object->conversionSampleIdx = conversions->samplesRequestedCount;
        }
        else { /* ADC multiple channel sampling */
            if (conversions->samplesRequestedCount > 1) {
                MAP_ADC14_configureMultiSequenceMode(memory,
                                                     memory<<(channelCount-1),
                                                     true);
            }
            else {
                MAP_ADC14_configureMultiSequenceMode(memory,
                                                     memory<<(channelCount-1),
                                                     false);
            }
    
            for(i = 0; i < channelCount; i++, memory=memory<<1) {
    
                refSource = hwAttrs->channelSetting[conversions[i].adcChannel].refSource;
    
                MAP_ADC14_configureConversionMemory(memory,
                        refSource,
                        conversions[i].adcChannel, false);
            }
    
            channelInt = 1<<(channelCount-1);
    
            /* Store the samples count into object */
            object->conversionSampleCount = conversions[0].samplesRequestedCount;
            object->conversionSampleIdx = conversions[0].samplesRequestedCount;
        }
    
        /* Configuring Sample Timer */
        MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
        //MAP_ADC14_enableSampleTimer(ADC_MANUAL_ITERATION);
    
        /* Enabling interrupts */
        MAP_ADC14_clearInterruptFlag(channelInt);
        MAP_ADC14_enableInterrupt(channelInt);
    
        /* Enabling Conversion */
        MAP_ADC14_enableConversion();
    
        /* Enabling Interrupts */
        MAP_Interrupt_enableInterrupt(INT_ADC14);
        MAP_Interrupt_enableMaster();
    
        /* Trigger conversion either from Timer PWM */
        MAP_Timer_A_startCounter(object->timerAddr,
                TIMER_A_UP_MODE);
    }

    At the green markt position, it will be configured the right pin which setting are stored to adcpin. 

    This field contains one of this macros:

    /* Port 4 */
    #define ADCBufMSP432_P4_0_A13 ((13 << 10) | 0x0340) /* ch 13, port 4, pin 0 */
    #define ADCBufMSP432_P4_1_A12 ((12 << 10) | 0x0341) /* ch 12, port 4, pin 1 */
    #define ADCBufMSP432_P4_2_A11 ((11 << 10) | 0x0342) /* ch 11, port 4, pin 2 */
    #define ADCBufMSP432_P4_3_A10 ((10 << 10) | 0x0343) /* ch 10, port 4, pin 3 */
    #define ADCBufMSP432_P4_4_A9 ((9 << 10) | 0x0344) /* ch 9, port 4, pin 4 */
    #define ADCBufMSP432_P4_5_A8 ((8 << 10) | 0x0345) /* ch 8, port 4, pin 5 */
    #define ADCBufMSP432_P4_6_A7 ((7 << 10) | 0x0346) /* ch 7, port 4, pin 6 */
    #define ADCBufMSP432_P4_7_A6 ((6 << 10) | 0x0347) /* ch 6, port 4, pin 7 */
    
    /* Port 5 */
    #define ADCBufMSP432_P5_0_A5 ((5 << 10) | 0x0350) /* ch 5, port 5, pin 0 */
    #define ADCBufMSP432_P5_1_A4 ((4 << 10) | 0x0351) /* ch 4, port 5, pin 1 */
    #define ADCBufMSP432_P5_2_A3 ((3 << 10) | 0x0352) /* ch 3, port 5, pin 2 */
    #define ADCBufMSP432_P5_3_A2 ((2 << 10) | 0x0353) /* ch 2, port 5, pin 3 */
    #define ADCBufMSP432_P5_4_A1 ((1 << 10) | 0x0354) /* ch 1, port 5, pin 4 */
    #define ADCBufMSP432_P5_5_A0 ((0 << 10) | 0x0355) /* ch 0, port 5, pin 5 */
    
    /* Port 6 */
    #define ADCBufMSP432_P6_0_A15 ((15 << 10) | 0x0360) /* ch 15, port 6, pin 0 */
    #define ADCBufMSP432_P6_1_A14 ((14 << 10) | 0x0361) /* ch 14, port 6, pin 1 */
    
    /* Port 8 */
    #define ADCBufMSP432_P8_2_A23 ((23 << 10) | 0x0382) /* ch 23, port 8, pin 2 */
    #define ADCBufMSP432_P8_3_A22 ((22 << 10) | 0x0383) /* ch 22, port 8, pin 3 */
    #define ADCBufMSP432_P8_4_A21 ((21 << 10) | 0x0384) /* ch 21, port 8, pin 4 */
    #define ADCBufMSP432_P8_5_A20 ((20 << 10) | 0x0385) /* ch 20, port 8, pin 5 */
    #define ADCBufMSP432_P8_6_A19 ((19 << 10) | 0x0386) /* ch 19, port 8, pin 6 */
    #define ADCBufMSP432_P8_7_A18 ((18 << 10) | 0x0387) /* ch 18, port 8, pin 7 */
    
    /* Port 9 */
    #define ADCBufMSP432_P9_0_A17 ((17 << 10) | 0x0390) /* ch 17, port 9, pin 0 */
    #define ADCBufMSP432_P9_1_A16 ((16 << 10) | 0x0391) /* ch 16, port 9, pin 1 */

    So this macro contains the analog channel + the hardware based port + pin.

    /* Config GPIOs for ADC channel analog in*/
        for (i = 0; i < channelCount; i++){
            /* Config GPIO for ADC channel analog input */
            MAP_GPIO_setAsPeripheralModuleFunctionInputPin(
             PinConfigPort(hwAttrs->channelSetting[i].adcPin),
             PinConfigPin(hwAttrs->channelSetting[i].adcPin),
             PinConfigModuleFunction(hwAttrs->channelSetting[i].adcPin));
        }


    The configuration is applied right at this point.

    But if we go further and go to this block:

            MAP_ADC14_configureConversionMemory(ADC_MEM0,
                    refSource,
                    conversions->adcChannel, false);


    In my opinion it must be:

    uint8_t adcChannel = (hwAttrs->channelSetting[conversions->adcChannel].adcPin >> 10);

    MAP_ADC14_configureConversionMemory(ADC_MEM0,
    refSource,
    adcChannel, false);

    For an example case take my configuration:

    /* ADC objects */
    ADCBufMSP432_Object adcbufMSP432Objects[FWD_BOARD_ADCBUFCOUNT];
    
    ADCBufMSP432_Channels adcBuf0MSP432Channels[FWD_BOARD_ADCBUF0CHANNELCOUNT] = {
    /* FWD_BOARD_ANALOG_10V_AIN */
    {
    .adcPin = ADCBufMSP432_P5_1_A4,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    },
    /* FWD_BOARD_ANALOG_5V0_AIN */
    {
    .adcPin = ADCBufMSP432_P5_2_A3,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    },
    /* FWD_BOARD_ANALOG_2V5_AIN */
    {
    .adcPin = ADCBufMSP432_P5_4_A1,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    },
    /* FWD_BOARD_ANALOG_20MA_AIN */
    {
    .adcPin = ADCBufMSP432_P5_3_A2,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    },
    /* FWD_BOARD_ANALOG_SENSOR_FB_AIN */
    {
    .adcPin = ADCBufMSP432_P5_5_A0,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 1450000
    },
    /* FWD_BOARD_ANALOG_SUPPLY_AIN */
    {
    .adcPin = ADCBufMSP432_P8_3_A22,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    }
    };
    
    /* ADC configuration structure */
    const ADCBufMSP432_HWAttrs adcbufMSP432HWAttrs[FWD_BOARD_ADCBUFCOUNT] = {
    {
    .intPriority = ~0,
    .channelSetting = adcBuf0MSP432Channels,
    .adcTimerTriggerSource = ADCBufMSP432_TIMERA0_CAPTURECOMPARE2
    }
    };
    
    const ADCBuf_Config ADCBuf_config[FWD_BOARD_ADCBUFCOUNT] = {
    {
    .fxnTablePtr = &ADCBufMSP432_fxnTable,
    .object = &adcbufMSP432Objects[FWD_BOARD_ADCBUF0],
    .hwAttrs = &adcbufMSP432HWAttrs[FWD_BOARD_ADCBUF0]
    }
    };
    
    const uint_least8_t ADCBuf_count = FWD_BOARD_ADCBUFCOUNT;

    Take ADCChannel[0] which is :

    {
    .adcPin = ADCBufMSP432_P5_1_A4,
    .refSource = ADCBufMSP432_VREFPOS_INTBUF_VREFNEG_VSS,
    .refVoltage = 2500000
    },

    So now u can read i choose A4 as AnalogInput.

    Now we go to my code: 

    ADCBuf_Conversion conversion = {0};
    
    conversion.adcChannel = 0;
    conversion.sampleBuffer = sampleBuffer;
    conversion.samplesRequestedCount = numRxBytes;
    
    if(ADCBuf_convert(h->ADC_h, &conversion, 1) != ADCBuf_STATUS_SUCCESS) 

    It will call the function primeConvert where i post at begin.

    Now the pin configuration is done at pin 5.1 and is mapped to A4.

    But now at the red marked postion there is adcChannel == 0 but for the function call of:

            MAP_ADC14_configureConversionMemory(ADC_MEM0,
                    refSource,
                    conversions->adcChannel, false);


    It needs to be 4 that the AnalogInput A4 is choosen for the conversion.

    If u need further information let it me know.

    Bests
    Richard

**Attention** This is a public forum