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.

Changing sampling rate in c2000 F28027

Other Parts Discussed in Thread: CONTROLSUITE

How to change the sampling frequency in c2000 F28027?

  • Hi Mani,

    If you're using adc_soc sample code which is present here: C:\ti\controlSUITE\device_support\f2802x\v129\DSP2802x_examples_ccsv4\adc_soc
    You can simply change the sampling frequency by changing the 'TBPRD' register of the triggering ePWM .

    Regards,
    Gautam
  • Thanks for replying Gautham,
    Could you please explain me how does the sampling rate changes while changing the ePWM period. Because , ePWM only gives SOC to ADC, how it influences sampling rate of ADC.

    Regards,
    Mani
  • Hi Mani,

    I hope you read the basic of the ePWM triggering in ePWM user guide which explains really well with waveforms.

    You can find the same here:

    Regards,

    Gautam

  • Hi Gautam,

                        Can you tell me how to calculate the value of TBPRD for sampling frequency of 200Khz.

    Regards,

    Mani.

  • Hello Mani,
    It is depend on your setting (for example: clock speed, PWM mode).
    As I know, F28027 is a 60 MHz maximum device. For Up or Down count mode, to give 200 KHz, just divide it so TBPRD= 60M/200K = 300.
    Please Gautam, correct me if I am wrong. Thank you.

    Best regards,
    Maria
  • You're absolutely right, Maria Todorova (3777504) !

    But Mani, please note that this is for UP count or down count mode. For both UP-DOWN count mode refer :

    Regards,

    Gautam

  • Hi Gautam,

                         I don't understand the calculation for TBPRD register in Up mode. In the ePWM reference guide it is given that T(pWM) = (TBPRD +1) * TBCLK.

    But how TBPRD = 60Mhz/200Khz . Can you please elaborate.

  •   I don't understand the calculation for TBPRD register in Up mode. In the ePWM reference guide it is given that T(pWM) = (TBPRD +1) * TBCLK.

    This forumula is very well applicable when T(TBCLK) is scaled ie for example:

     EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;   		// Clock ratio to SYSCLKOUT
        EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2;


    Hence, T(TBCLK) in this case would be 60MHz/(2*2)  = 15MHz

    Now, lets calculate TBPRD for 50Khz PWM frequency:

    2E-5 = (TBPRD + 1) * 6.67e-8

    TBPRD = 299 or 300 if you want to round off.

    Mani Sathasivam said:
    But how TBPRD = 60Mhz/200Khz .

    This will if there are no scaling. For example: 

    EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;   // Clock ratio to SYSCLKOUT
         EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;

    Then,

    TBPRD = 60MHz/75KHz

    TBPRD = 800

    I hope you got this. You can use the first formula for any div_sel.

    Regards,

    Gautam

  • Hi Gautam,
    Can I give value 300 directly to TBPRD register or I have to convert into hex.
    Regards,
    Mani
  • Directly Mani.
  • Gautam in Adc Soc example the ADC ISR is not triggering. Can you suggest me a way.

    Regards,
    Mani
  • HI Gautam,
    In AdcSoc example ISR interrupt is not triggering. Can you provide me a solution.

    Regards,
    Mani.
  • Is it the un-edited example code or did you edit the same?
  • I had tried both(Unedited and edited by me).But in both case the result would be same not triggering interrupt.
  • Is the project building properly ie without any warnings ?
  • No Gautam, it gives 7 warnings during building.

    My code is:


    //#############################################################################
    //
    // File: f2802x_examples_ccsv4/adc_soc/Example_F2802xAdcSoc.c
    //
    // Title: F2802x ADC Start-Of-Conversion (SOC) Example Program.
    //
    // Group: C2000
    // Target Device: TMS320F2802x
    //
    //! \addtogroup example_list
    //! <h1>ADC Start-Of-Conversion (SOC)</h1>
    //!
    //! Interrupts are enabled and the ePWM1 is setup to generate a periodic
    //! ADC SOC - ADCINT1. Two channels are converted, ADCINA4 and ADCINA2.
    //!
    //! Watch Variables:
    //!
    //! - Voltage1[10] - Last 10 ADCRESULT0 values
    //! - Voltage2[10] - Last 10 ADCRESULT1 values
    //! - ConversionCount - Current result number 0-9
    //! - LoopCount - Idle loop counter
    //
    // (C) Copyright 2012, Texas Instruments, Inc.
    //#############################################################################
    // $TI Release: LaunchPad f2802x Support Library v100 $
    // $Release Date: Wed Jul 25 10:45:39 CDT 2012 $
    //#############################################################################

    #include "DSP28x_Project.h" // Device Headerfile and Examples Include File

    #include "f2802x_common/include/adc.h"
    #include "f2802x_common/include/clk.h"
    #include "f2802x_common/include/flash.h"
    #include "f2802x_common/include/gpio.h"
    #include "f2802x_common/include/pie.h"
    #include "f2802x_common/include/pll.h"
    #include "f2802x_common/include/wdog.h"

    // Prototype statements for functions found within this file.
    interrupt void adc_isr(void);
    void Adc_Config(void);

    // Global variables used in this example:
    uint16_t LoopCount;
    uint16_t ConversionCount;
    uint16_t Voltage1[10];
    uint16_t Voltage2[10];

    ADC_Handle myAdc;
    CLK_Handle myClk;
    FLASH_Handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    PWM_Handle myPwm;

    void main(void)
    {

    CPU_Handle myCpu;
    PLL_Handle myPll;
    WDOG_Handle myWDog;

    // Initialize all the handles needed for this application
    myAdc = ADC_init((void *)ADC_BASE_ADDR, sizeof(ADC_Obj));
    myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
    myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
    myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
    myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
    myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
    myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
    myPwm = PWM_init((void *)PWM_ePWM1_BASE_ADDR, sizeof(PWM_Obj));
    myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

    // Perform basic system initialization
    WDOG_disable(myWDog);
    CLK_enableAdcClock(myClk);
    CLK_enableTbClockSync(myClk);
    (*Device_cal)();

    //Select the internal oscillator 1 as the clock source
    CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

    // Setup the PLL for x10 /2 which will yield 50Mhz = 10Mhz * 10 / 2
    PLL_setup(myPll, PLL_Multiplier_10, PLL_DivideSelect_ClkIn_by_2);

    // Disable the PIE and all interrupts
    PIE_disable(myPie);
    PIE_disableAllInts(myPie);
    CPU_disableGlobalInts(myCpu);
    CPU_clearIntFlags(myCpu);

    // If running from flash copy RAM only functions to RAM
    #ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif

    // Setup a debug vector table and enable the PIE
    PIE_setDebugIntVectorTable(myPie);
    PIE_enable(myPie);

    // Register interrupt handlers in the PIE vector table
    PIE_registerPieIntHandler(myPie, PIE_GroupNumber_10, PIE_SubGroupNumber_1, (intVec_t)&adc_isr);



    // Initialize the ADC
    ADC_enableBandGap(myAdc);
    ADC_enableRefBuffers(myAdc);
    ADC_powerUp(myAdc);
    ADC_enable(myAdc);
    ADC_setVoltRefSrc(myAdc, ADC_VoltageRefSrc_Int);

    // Enable ADCINT1 in PIE
    PIE_enableAdcInt(myPie, ADC_IntNumber_1);
    // Enable CPU Interrupt 1
    CPU_enableInt(myCpu, CPU_IntNumber_10);
    // Enable Global interrupt INTM
    CPU_enableGlobalInts(myCpu);
    // Enable Global realtime interrupt DBGM
    CPU_enableDebugInt(myCpu);

    LoopCount = 0;
    ConversionCount = 0;

    // Configure ADC
    //Note: Channel ADCINA4 will be double sampled to workaround the ADC 1st sample issue for rev0 silicon errata
    ADC_setIntPulseGenMode(myAdc, ADC_IntPulseGenMode_Prior); //ADCINT1 trips after AdcResults latch
    ADC_enableInt(myAdc, ADC_IntNumber_1); //Enabled ADCINT1
    ADC_setIntMode(myAdc, ADC_IntNumber_1, ADC_IntMode_ClearFlag); //Disable ADCINT1 Continuous mode
    ADC_setIntSrc(myAdc, ADC_IntNumber_1, ADC_IntSrc_EOC2); //setup EOC2 to trigger ADCINT1 to fire
    ADC_setSocChanNumber (myAdc, ADC_SocNumber_0, ADC_SocChanNumber_A4); //set SOC0 channel select to ADCINA4
    ADC_setSocTrigSrc(myAdc, ADC_SocNumber_0, ADC_SocTrigSrc_EPWM1_ADCSOCA); //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
    ADC_setSocSampleWindow(myAdc, ADC_SocNumber_0, ADC_SocSampleWindow_7_cycles); //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    // Enable PWM clock
    CLK_enablePwmClock(myClk, PWM_Number_1);

    // Setup PWM
    PWM_enableSocAPulse(myPwm); // Enable SOC on A group
    PWM_setSocAPulseSrc(myPwm, PWM_SocPulseSrc_CounterEqualCmpAIncr); // Select SOC from from CPMA on upcount
    PWM_setSocAPeriod(myPwm, PWM_SocPeriod_FirstEvent); // Generate pulse on 1st event
    PWM_setCmpA(myPwm, 0x0080); // Set compare A value
    PWM_setPeriod(myPwm, 300); // Set period for ePWM1
    PWM_setCounterMode(myPwm, PWM_CounterMode_Up); // count up and start

    // Wait for ADC interrupt
    for(;;)
    {
    LoopCount++;
    }

    }


    interrupt void adc_isr(void)
    {

    //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0
    Voltage1[ConversionCount] = ADC_readResult(myAdc, ADC_ResultNumber_1);

    // If 10 conversions have been logged, start over
    if(ConversionCount == 9)
    {
    ConversionCount = 0;
    }
    else ConversionCount++;

    // Clear ADCINT1 flag reinitialize for next SOC
    ADC_clearIntFlag(myAdc, ADC_IntNumber_1);
    // Acknowledge interrupt to PIE
    PIE_clearInt(myPie, PIE_GroupNumber_10);

    return;
    }

    This is the modified version of AdcSoc, it sends adc value to computer through SCI.
  • Sorry this is just the AdcSoc program. I had wrongly said.
    Regards,
    Mani
  • Warnings are:
    1.Build variable 'XDAIS_CG_ROOT' cannot be resolved.
    2.creating output section "csm_rsvd" without a SECTIONS specification
    3.creating output section "csmpasswds" without a SECTIONS specification
    4.entry-point symbol other than "_c_int00" specified: "code_start"
    5.Invalid project path: Duplicate path entries found (/Example_F2802xAdcSoc [Include path] isSystemInclude:true includePath:D:/ti/controlSUITE/development_kits/C2000_LaunchPad), path: [/Example_F2802xAdcSoc].
    6.Invalid project path: Include path not found (\packages\ti\xdais).
    7.Invalid project path: Include path not found (D:\ti\libs\math\IQmath\v15c\include).
  • What is the revision of F28027 folder in ControlSuite that you use? Please use the example from the latest folder.
    For example, mine is rev 222, and compared to your code, your code misses CLK_enableTbClockSync(myClk) line. And this is why the code doesn't work well.

    Please get the latest one from C:\ti\controlSUITE\device_support\f2802x\v222\f2802x_examples_drivers\adc_soc

    Best regards,

    Maria

  • Hi, i've been trying to configure the sample rate of f28027 adc. 


    I set the TPBRD to 500 in order to obtain 100kHz, but i don't know how to verify this configuration. then i tried toggle a led before i read the ADC result, but it gives me 9.61 kHz so I don't know if i'm measuring wrong.

    Regards

    thank you

  • Hi David,

    Usually it is best to create a new post for a new question. The last activity on this thread was almost 2 years ago.

    If you have a scope, you can place a large series resistor on the ADC pin to a DC source (say 50Kohm) and ensure that the capacitance on the pin is low (say less than 100pF) and then observe the ADC pin directly. The charge inside the ADC has to equalize with the external capacitance on each sample, so you can directly observe this glitch on the pin.

    Toggling a GPIO is also a reasonable way to go. My guess is that if you are seeing ~10KHz but expect ~100kHz then something is wrong. You may want to check your clock and pll settings and view XCLOCKOUT on a pin. Additionally, you can configure the ePWM to toggle a pin each period and also observe this on a scope.