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.

TMS320F280025C: TMS320F280025C

Part Number: TMS320F280025C
Other Parts Discussed in Thread: SYSCONFIG

Dear Team,

I have designed customize board using F280025C microcontroller.

My problem:

I used the ADC example code - SoC continues mode ( from F28002x code - C2000)

But when debug the code I didn't see any change in the ADC variable (in watch expression - set continuous refresh mode)

it always remains same - applied potentiometer to all used ADC pin but result is same!

please guide what steps I missing?

Also i want to know,

- how to select SOC and interrupt(1,2,3,4) for particular ADC pin

- how to trigger ADC when conversation is complete - self trigger

Best and regards,

Shivam

  • Hi Shivam,

    The ADC SOC Continuous example will convert on a single channel or a single ADC, so you'll want to make sure that you've configured it to use a channel that has the stimulus applied.

    Otherwise, some things to check on your custom board:

    • What is the VDDA voltage?  Is it within tolerance of 3.3V?
    • What is the VREFHI voltage?  Is this supplied externally or internally?  Do your reference configuration settings in the SW match the method used to supply VREFHI? (It looks like the example you mentioned uses 3.3V internal reference mode, which would be expected to output 1.65V onto the VREFHI pin)
    • Are VREFLO pins connected to 0V / ground?
    • Are the ADC pins connected as expected?  One possibility would be to try using the AIO digital inputs as a sanity check to ensure pin continuity (using the CMPSS comparator inputs could also work). 
    • What are you using to clock the device? If an external clock is supplied, are the logic levels and frequency as expected?  For either internal or external clock, if you enable the system clock output on XCLKOUT, is the CPU frequency as expected?
    • Are all ADC inputs, even those that are unused, being driven by a voltage within the range of VSSA to VDDA (floating is OK too)? 
    • Were any ADC inputs damaged by ESD or EOS?  You can check this by applying some voltages to the pins and ensuring that the leakage current is very small (see the device datasheet for exact pin leakage specification; i believe it should be well under 1uA).

    You can also try a simpler example like software forced ADC conversions.  

    Does this occur on multiple boards, or just one board?

  • Hi Devine,

    Thanks for response!

    I used the adc_ex1_soc_software.c example code and I have used analog A3 pin of F280025C and and applied 3.3VDC to A3 pin.

    As I see in the watch expression I am getting only value in  myADC1Result0 and myADC1Result1 [ ADC values are quite fluctuating i.e. 2000 to 4095 ].

    Data is not available in myADC0Result0 and myADC0Result1 why?

    - how to get stable value ADC values in myADC1Result0  and myADC1Result1 ?

    - why myADC0Result0  and myADC0Result1 shows zero? 

    please note: 

    I have given 3.3VDC from LDO and which is quite stable I measured in oscilloscope.

    Best and regards,

    Shivam

  • Hi Shivam,

    Is the 3.3V provided to VDDA, VREFHI, or both? Are you using internal or external reference mode?

    Does the adc_ex1 make it to the SW breakpoint (ESTOP0) or does it get stuck in one of the loops in the code?

    Can you look at the ADC result registers directly in the expressions window? Do these have some value? e.g. AdcaResultRegs.ADCRESULT0 

    Are SOC0 and SOC1 on ADC-A both pointing to A3 (this is configured in sysconfig)?  These would correspond to ADC0 - Result0 and ADC0 - Result1.  (ADC1 - Result0 and ADC1 - Result1 come from ADC-C)

  • Hi Devin,

    Here is the my code [adc_ex13_soc_oversampling] ADC values are fluctuating please let me know  [ I have provided 3.3VDC to VDDA pin ]

    //#############################################################################
    //
    // FILE: adc_ex13_soc_oversampling.c
    //
    // TITLE: ADC Oversampling Using Multiple SOCs
    //
    //! \addtogroup driver_example_list
    //! <h1>ADC SOC Oversampling </h1>
    //!
    //! This example sets up ePWM1 to periodically trigger a set of conversions on
    //! ADCA including multiple SOCs that all convert A2 to achieve oversampling on
    //! A2.
    //!
    //! ADCA Interrupt ISRs are used to read results of ADCA.
    //!
    //! \b External \b Connections \n
    //! - A0, A1, A2 should be connected to signals to be converted.
    //!
    //! \b Watch \b Variables \n
    //! - \b adcAResult0 - Digital representation of the voltage on pin A0
    //! - \b adcAResult1 - Digital representation of the voltage on pin A1
    //! - \b adcAResult2 - Digital representation of the voltage on pin A2
    //!
    //
    //#############################################################################
    //
    //
    // $Copyright:
    // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/
    //
    // 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.
    // $
    //#############################################################################
    //

    //
    // Included Files
    //
    #include "driverlib.h"
    #include "device.h"
    #include "board.h"

    //
    // Globals
    //
    uint16_t adcAResult0;
    uint16_t adcAResult1;
    uint16_t adcAResult2;

    //
    // Function Prototypes
    //
    void initEPWM();
    __interrupt void adcA1ISR(void);

    //
    // Main
    //

    void My_ADC_init();
    void main(void)
    {
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Set up ADCs:
    // Signal Mode : single-ended
    // Conversion Resolution : 12-bit;
    //
    // Configure SOC0-1 in round robin mode to sample A0 and A1 channel
    // respectively and SOC2-SOC5 oversamples channel A2 on EPWM1SOCA
    // trigger.
    //
    // Register and enable the interrupts:
    // SOC0 and SOC1 results are read after each PWM trigger for
    // channel 0 and 1 outputs while SOC2-SOC5 results will be
    // averaged together for oversampled channel A2 result
    //
    // Board_init();
    My_ADC_init();
    //
    // Initialize PWM
    //
    initEPWM();

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Start ePWM1, enabling SOCA and putting the counter in up-count mode
    //
    EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);

    //
    // Take conversions indefinitely in loop
    //
    do
    {
    //
    // Wait while ePWM causes ADC conversions.
    // ADCA1 ISR processes each new set of conversions.
    //
    }
    while(1);
    }

    //
    // Function to configure ePWM1 to generate the SOC.
    //
    void initEPWM(void)
    {
    //
    // Disable SOCA
    //
    EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);

    //
    // Configure the SOC to occur on the first up-count event
    //
    EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
    EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);

    //
    // Set the compare A value to 1000 and the period to 1999
    // Assuming ePWM clock is 100MHz, this would give 50kHz sampling
    // 50MHz ePWM clock would give 25kHz sampling, etc.
    // The sample rate can also be modulated by changing the ePWM period
    // directly (ensure that the compare A value is less than the period).
    //
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000);
    EPWM_setTimeBasePeriod(EPWM1_BASE, 1999);

    //
    // Set the local ePWM module clock divider to /1
    //
    EPWM_setClockPrescaler(EPWM1_BASE,
    EPWM_CLOCK_DIVIDER_1,
    EPWM_HSCLOCK_DIVIDER_1);

    //
    // Freeze the counter
    //
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
    }

    //
    // adcA1ISR - ADC A Interrupt 1 ISR
    //
    __interrupt void adcA1ISR(void)
    {
    //
    // Store results for A0 and A1
    //
    adcAResult0 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
    // adcAResult1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
    //
    // //
    // // Average the 4 oversampled A2 results together
    // //
    // adcAResult2 =
    // (ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2) +
    // ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3) +
    // ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER4) +
    // ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER5)) >> 2;

    //
    // Clear the interrupt flag
    //
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

    //
    // Check if overflow has occurred
    //
    if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
    {
    ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    }

    //
    // Acknowledge the interrupt
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }

    //
    // End of file
    //


    void My_ADC_init()
    {

    // Analog PinMux for A0/C15
    GPIO_setPinConfig(GPIO_231_GPIO231);
    // AIO -> Analog mode selected
    GPIO_setAnalogMode(231, GPIO_ANALOG_ENABLED);

    //myADC0 initialization

    // ADC Initialization: Write ADC configurations and power up the ADC
    // Configures the ADC module's offset trim
    ADC_setOffsetTrimAll(ADC_REFERENCE_INTERNAL,ADC_REFERENCE_3_3V);
    // Configures the analog-to-digital converter module prescaler.
    ADC_setPrescaler(myADC0_BASE, ADC_CLK_DIV_2_0);
    // Sets the timing of the end-of-conversion pulse
    ADC_setInterruptPulseMode(myADC0_BASE, ADC_PULSE_END_OF_CONV);
    // Powers up the analog-to-digital converter core.
    ADC_enableConverter(myADC0_BASE);
    // Delay for 1ms to allow ADC time to power up
    DEVICE_DELAY_US(5000);

    // SOC Configuration: Setup ADC EPWM channel and trigger settings
    // Disables SOC burst mode.
    ADC_disableBurstMode(myADC0_BASE);
    // Sets the priority mode of the SOCs.
    ADC_setSOCPriority(myADC0_BASE, ADC_PRI_ALL_ROUND_ROBIN);
    // Start of Conversion 0 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 0
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN0
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN0, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER0, ADC_INT_SOC_TRIGGER_NONE);
    // Start of Conversion 1 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 1
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN1
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN1, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER1, ADC_INT_SOC_TRIGGER_NONE);
    // Start of Conversion 2 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 2
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN2
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN2, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER2, ADC_INT_SOC_TRIGGER_NONE);
    // Start of Conversion 3 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 3
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN2
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN2, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER3, ADC_INT_SOC_TRIGGER_NONE);
    // Start of Conversion 4 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 4
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN2
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER4, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN2, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER4, ADC_INT_SOC_TRIGGER_NONE);
    // Start of Conversion 5 Configuration
    // Configures a start-of-conversion (SOC) in the ADC and its interrupt SOC trigger.
    // SOC number : 5
    // Trigger : ADC_TRIGGER_EPWM1_SOCA
    // Channel : ADC_CH_ADCIN2
    // Sample Window : 8 SYSCLK cycles
    // Interrupt Trigger: ADC_INT_SOC_TRIGGER_NONE
    ADC_setupSOC(myADC0_BASE, ADC_SOC_NUMBER5, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN2, 8U);
    ADC_setInterruptSOCTrigger(myADC0_BASE, ADC_SOC_NUMBER5, ADC_INT_SOC_TRIGGER_NONE);
    // ADC Interrupt 1 Configuration
    // SOC/EOC number : 5
    // Interrupt Source: enabled
    // Continuous Mode : disabled
    ADC_setInterruptSource(myADC0_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER5);
    ADC_enableInterrupt(myADC0_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(myADC0_BASE, ADC_INT_NUMBER1);
    ADC_disableContinuousMode(myADC0_BASE, ADC_INT_NUMBER1);


    // asysctl initialization
    // Disables the temperature sensor output to the ADC.
    ASysCtl_disableTemperatureSensor();
    // Set the analog voltage reference selection to internal.
    ASysCtl_setAnalogReferenceInternal( ASYSCTL_VREFHIA | ASYSCTL_VREFHIC );
    // Set the internal analog voltage reference selection to 1.65V.
    ASysCtl_setAnalogReference1P65( ASYSCTL_VREFHIA | ASYSCTL_VREFHIC );

    // Interrupt Setings for INT_myADC0_1
    Interrupt_register(INT_myADC0_1, &adcA1ISR);
    Interrupt_enable(INT_myADC0_1);

    }

  • Hi Devin,

    I solved the problem! 

    I have used internal reference and internal reference is not connected any where [ but as per my experience we can use internal reference for ADC and it should work ] 

    I have set the below value for internal reference and I got fluctuated value in ADC output [ I am still confused why it's not work! ]

    ASysCtl_setAnalogReferenceInternal( ASYSCTL_VREFHIA | ASYSCTL_VREFHIC );

     ASysCtl_setAnalogReference1P65( ASYSCTL_VREFHIA | ASYSCTL_VREFHIC );

    My Solution: 

    I have set below value and applied 3.3VDC and GND to VREFHI and VREFLO.

     ASysCtl_setAnalogReferenceExternal(ASYSCTL_VREFHIA | ASYSCTL_VREFHIC); 

     .

    By doing this I got the output successfully!

    1)Please explain me why internal reference voltage is not working? 

    2)Please guide me how to trigger ADC using ePWMx?

    -  I changed epwm1  base value to  epwm5  in adc_ex3_temp_sensor  but it is not working why?

    Best and regards,

    -Shivam

  • Hi Shivam,

    Can you try connecting VREFLO to ground on the rest of your board (H5 pin 1 to ground) and then try internal reference again?  I think this should be connected to the same ground that the ADC inputs are using.  

    For the ePWM triggering, you should just need two things:

    • The source ePWM needs to be running and generating an SOCA or SOCB trigger output
    • The SOCs in the ADC that you want to convert should have their trigger setting configured to use the correct ePWM and SOCA or SOCB as appropriate (if you use burst mode then instead you would configure the burst trigger)
  • Hi Devin,

    Thank you!

    As per your suggestion my problem is solved I have set the PWM trigger source in ADC initialization [ADC_TRIGGER_EPWM1_SOCA and  EPWM1_BASE to epwm7]

    also I have connected VREFLO to  GND and i got the ADC result [ but values are fluctuating - OVERALL Acceptable ADC values!]

    Best and Regards,

    Shivam

  • Hi Devin,

    Thank you!

    As per your suggestion my problem is solved I have set the PWM trigger source in ADC initialization [ADC_TRIGGER_EPWM1_SOCA and  EPWM1_BASE to epwm7]

    also I have connected VREFLO to  GND and i got the ADC result [ but values are fluctuating - OVERALL Acceptable ADC values!]

    Best and Regards,

    Shivam