CCS/LAUNCHXL-F28377S: ADC_SAMPLING_FREQ

Part Number: LAUNCHXL-F28377S

Tool/software: Code Composer Studio

Hi,

I have a question about “2837x_rfft_adc_rt”:

I need to increase my sample rate analog to digital from 100ksps to  500 Ksps,

changing the following parameter in the "example_setup.h" is enough?

#define ADC_SAMPLING_FREQ    100000.0L

or other changes in the project is necessary.

Thank you for your help.

Best regards,

Amin

  • In reply to Whitney Dewey:

    I see 99.174KHz with oscilloscope.
  • In reply to amin:

    Okay, that is what I would expect given the code you showed me. So if you wanted to trigger an ADC conversion at a rate of 500kHz, you would just need to change 100k to 500k in the #defines for the period, right?

    #define EPWM1_PERIOD EPWM_CLK/(2*8*500000UL)

    Or am I misunderstanding what you're trying to do?

    Whitney
  • In reply to Whitney Dewey:

    When I change this line:
    #define EPWM1_PERIOD EPWM_CLK/(2*8*500000UL)
    ADC sampling freq=500ksps and it works good.
    but for pwm generator, when
    #define EPWM2_PERIOD EPWM_CLK/(2*8*200UL)
    , signal generator not works(200Hz signal)
  • In reply to amin:

    I have a voltage control oscillator with single input (connect to pwm(200Hz) of launchpad-f28377s), and single output(connect to ADC pin A0 with 500ksps). I need to start pwm and ADC from start point to end point of each pulse.
  • In reply to amin:

    200 Hz pulse production was created.
    Operates correctly.
    My question is how to set start and stop of each pulse wit ADC(start and stop of sampling)?
    Amin
  • In reply to Whitney Dewey:

    following code: result(500ksps ADC and 200Hz pwm)

    #define CPU_FRQ_200MHZ 1
    #define ADC_SAMPLING_FREQ 500000.0L
    #define EPWM_CLK 100000000UL // EPWM_CLK starts off SYSCLK/2
    #define EPWM_CLKDIV 1 // TBCLK = SYSCLK/(2*2)
    #define EPWM_HSPCLKDIV 4 // = SYSCLK/(2*2*8) or EPWM_CLK/(2*8)
    // desired freq 100KHz
    #define EPWM1_PERIOD       EPWM_CLK/(2*8*500000UL)
    #define EPWM1_DUTY_CYCLE   EPWM1_PERIOD/2UL
    // desired freq 10KHz
    #define EPWM2_PERIOD      (EPWM_CLK)/(2*8*200UL)
    #define EPWM2_DUTY_CYCLE   EPWM2_PERIOD/2UL



    Amin

  • In reply to amin:

    The original 2837x_rfft_adc_rt example has configured the ADC's SOC0 to be triggered by ePWM1 SOCA (ADCSOC0CTL.TRIGSEL = 5). It also configured the ePWM to generate the SOCA signal when TBCTR = CMPA (ETSEL.SOCASEL = 4). That basically means the conversion starts on the rising edge of the ePWM1A signal.

    I'm not sure what you mean by "stop of sampling." Once the conversion is started, the sample and hold time is determined by ADCSOC0CTL.ACQPS which the example code has configured to 15 SYSCLK cycles. I believe this is the minimum required sampling time for a 12-bit conversion on the F28377S. It then takes a number of cycles to for the result to be latched into the result registers and for the ADC interrupt to be generated. You can look at the ADC Timings section of the TRM if you want the details:

    www.ti.com/.../spruhm8

    The end of the actual sampling window isn't determined by the ePWM. Perhaps I'm not fully understanding what you're trying to do...?

    Whitney
  • In reply to Whitney Dewey:

    Whitney,

    Thank you very much for your help.

    My goal is ADC sampling at the rising edge to rising edge of the next pulse.

    Because I need to have the samples(ADC pin) corresponding to each pulse(generated by PWM),

    As it is seen in Fig., Sampling begins at the beginning of each pulse to the beginning of the next pulse(this will not be done for all pulses), and then split the samples on the falling edge of the pulse.

    I'm not saying stop function(said before post "the end point"), my goal is just find the location of the rising edge of each pulses.

    Thanks and Best regards,

    Amin

  • In reply to amin:

    Okay, I think I understand. You could configure ePWM2 to trigger an interrupt on the a CMPA event (which is the rising edge in your configuration). The epwm_up_aq example in controlSUITE demonstrates how to configure a PWM interrupt if you need an example. Will that do what you need?

    Whitney

  • In reply to Whitney Dewey:

    Hi Whitney,

    In this project we have a change in pulse duty cycle, but I do not need this change. I was reduced the code to a pulse generator(ePWM2).

    //###########################################################################
    //
    // FILE:   epwm_up_aq_cpu01.c
    //
    // TITLE:  Action Qualifier Module - Using up count.
    //
    //! \addtogroup cpu01_example_list
    //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1>
    //!
    //! This example configures ePWM1, ePWM2, ePWM3 to produce an
    //! waveform with independent modulation on EPWMxA and
    //! EPWMxB.
    //!
    //! The compare values CMPA and CMPB are modified within the ePWM's ISR.
    //!
    //! The TB counter is in up count mode for this example.
    //!
    //! View the EPWM1A/B(PA0_GPIO0 & PA1_GPIO1), EPWM2A/B(PA2_GPIO2 & PA3_GPIO3)
    //! and EPWM3A/B(PA4_GPIO4 & PA5_GPIO5) waveforms via an oscilloscope.
    //!
    //
    //###########################################################################
    // $TI Release: F2837xS Support Library v210 $
    // $Release Date: Tue Nov  1 15:35:23 CDT 2016 $
    // $Copyright: Copyright (C) 2014-2016 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    //
    // Included Files
    //
    #include "F28x_Project.h"
    
    //
    // Defines
    //
    
    #define EPWM2_TIMER_TBPRD  2000  // Period register ////////////2000
    #define EPWM2_MAX_CMPA     1950 //1950
    #define EPWM2_MIN_CMPA       50
    #define EPWM2_MAX_CMPB     1950 //1950
    #define EPWM2_MIN_CMPB       50
    
    
    #define EPWM_CMP_UP           1
    #define EPWM_CMP_DOWN         0
    
    //
    // Globals
    //
    typedef struct
    {
        volatile struct EPWM_REGS *EPwmRegHandle;
        Uint16 EPwm_CMPA_Direction;
        Uint16 EPwm_CMPB_Direction;
        Uint16 EPwmTimerIntCount;
        Uint16 EPwmMaxCMPA;
        Uint16 EPwmMinCMPA;
        Uint16 EPwmMaxCMPB;
        Uint16 EPwmMinCMPB;
    }EPWM_INFO;
    
    EPWM_INFO epwm2_info;
    
    
    //
    //  Function Prototypes
    //
    
    void InitEPwm2Example(void);
    
    __interrupt void epwm2_isr(void);
    
    void update_compare(EPWM_INFO*);
    
    //
    // Main
    //
    void main(void)
    {
    //
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2837xS_SysCtrl.c file.
    //
        InitSysCtrl();
    
    //
    // Step 2. Initialize GPIO:
    // This example function is found in the F2837xS_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    //
    //    InitGpio();
    
    //
    // Enable PWM2
    //
    
        CpuSysRegs.PCLKCR2.bit.EPWM2=1;
    //
    // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
    // These functions are in the F2837xS_EPwm.c file
    //
        InitEPwm2Gpio();
    
    //
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
    //
        DINT;
    
    //
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2837xS_PieCtrl.c file.
    //
        InitPieCtrl();
    
    //
    // Disable CPU interrupts and clear all CPU interrupt flags:
    //
        IER = 0x0000;
        IFR = 0x0000;
    
    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2837xS_DefaultIsr.c.
    // This function is found in F2837xS_PieVect.c.
    //
        InitPieVectTable();
    
    //
    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    //
        EALLOW; // This is needed to write to EALLOW protected registers
        PieVectTable.EPWM2_INT = &epwm2_isr;
        EDIS;   // This is needed to disable write to EALLOW protected registers
    
    //
    // For this example, only initialize the ePWM
    //
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
        EDIS;
    
        InitEPwm2Example();
    
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
        EDIS;
    
    //
    // Step 4. User specific code, enable interrupts:
    //
    // Enable CPU INT3 which is connected to EPWM1-3 INT:
    //
        IER |= M_INT3;
    
    //
    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-3
    //
        PieCtrlRegs.PIEIER3.bit.INTx2 = 1;
    
    //
    // Enable global Interrupts and higher priority real-time debug events:
    //
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
    //
    // Step 5. IDLE loop. Just sit and loop forever (optional):
    //
        for(;;)
        {
            asm ("  NOP");
        }
    }
    
    
    //
    // epwm2_isr - EPWM2 ISR to update compare values
    //
    __interrupt void epwm2_isr(void)
    {
        //
        // Update the CMPA and CMPB values
        //
        update_compare(&epwm2_info);
    
        //
        // Clear INT flag for this timer
        //
        EPwm2Regs.ETCLR.bit.INT = 1;
    
        //
        // Acknowledge this interrupt to receive more interrupts from group 3
        //
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    
    //
    // InitEPwm2Example - Initialize EPWM2 values
    //
    void InitEPwm2Example()
    {
       //
       // Setup TBCLK
       //
       EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD;       // Set timer period
       EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;    // Disable phase loading
       EPwm2Regs.TBPHS.bit.TBPHS = 0x0000;        // Phase is 0
       EPwm2Regs.TBCTR = 0x0000;                  // Clear counter
       EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV2;   // Clock ratio to SYSCLKOUT
       EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV2;
    
       //
       // Setup shadow register load on ZERO
       //
       EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
       EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
       EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    
       //
       // Set Compare values
       //
       EPwm2Regs.CMPA.bit.CMPA = EPWM2_MIN_CMPA;      // Set compare A value
       EPwm2Regs.CMPB.bit.CMPB = EPWM2_MAX_CMPB;      // Set Compare B value
    
       //
       // Set actions
       //
       EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;            // Clear PWM2A on Period
       EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;              // Set PWM2A on event A,
                                                       // up count
    
       EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR;            // Clear PWM2B on Period
       EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;              // Set PWM2B on event B,
                                                       // up count
    
       //
       // Interrupt where we will change the Compare Values
       //
       EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;       // Select INT on Zero event
       EPwm2Regs.ETSEL.bit.INTEN = 1;                  // Enable INT
       EPwm2Regs.ETPS.bit.INTPRD = ET_3RD;             // Generate INT on 3rd event
    
       //
       // Information this example uses to keep track
       // of the direction the CMPA/CMPB values are
       // moving, the min and max allowed values and
       // a pointer to the correct ePWM registers
       //
       epwm2_info.EPwm_CMPA_Direction = EPWM_CMP_UP;   // Start by increasing CMPA
       epwm2_info.EPwm_CMPB_Direction = EPWM_CMP_DOWN; // and decreasing CMPB
       epwm2_info.EPwmTimerIntCount = 0;               // Zero the interrupt
                                                       // counter
       epwm2_info.EPwmRegHandle = &EPwm2Regs;          // Set the pointer to the
                                                       // ePWM module
       epwm2_info.EPwmMaxCMPA = EPWM2_MAX_CMPA;        // Setup min/max
                                                       // CMPA/CMPB values
       epwm2_info.EPwmMinCMPA = EPWM2_MIN_CMPA;
       epwm2_info.EPwmMaxCMPB = EPWM2_MAX_CMPB;
       epwm2_info.EPwmMinCMPB = EPWM2_MIN_CMPB;
    }
    
    
    //
    // update_compare - Update the compare values for the specified EPWM
    //
    void update_compare(EPWM_INFO *epwm_info)
    {
       //
       // Every 10'th interrupt, change the CMPA/CMPB values
       //
       if(epwm_info->EPwmTimerIntCount == 1)  ///////////////////////10
       {
           epwm_info->EPwmTimerIntCount = 0;
    
           //
           // If we were increasing CMPA, check to see if
           // we reached the max value.  If not, increase CMPA
           // else, change directions and decrease CMPA
           //
           if(epwm_info->EPwm_CMPA_Direction == EPWM_CMP_UP)
           {
               if(epwm_info->EPwmRegHandle->CMPA.bit.CMPA < epwm_info->EPwmMaxCMPA)
               {
                  epwm_info->EPwmRegHandle->CMPA.bit.CMPA++;
               }
               else
               {
                  epwm_info->EPwm_CMPA_Direction = EPWM_CMP_DOWN;
                  epwm_info->EPwmRegHandle->CMPA.bit.CMPA--;
               }
           }
    
           //
           // If we were decreasing CMPA, check to see if
           // we reached the min value.  If not, decrease CMPA
           // else, change directions and increase CMPA
           //
           else
           {
               if(epwm_info->EPwmRegHandle->CMPA.bit.CMPA == epwm_info->EPwmMinCMPA)
               {
                  epwm_info->EPwm_CMPA_Direction = EPWM_CMP_UP;
                  epwm_info->EPwmRegHandle->CMPA.bit.CMPA++;
               }
               else
               {
                  epwm_info->EPwmRegHandle->CMPA.bit.CMPA--;
               }
           }
    
           //
           // If we were increasing CMPB, check to see if
           // we reached the max value.  If not, increase CMPB
           // else, change directions and decrease CMPB
           //
           if(epwm_info->EPwm_CMPB_Direction == EPWM_CMP_UP)
           {
               if(epwm_info->EPwmRegHandle->CMPB.bit.CMPB < epwm_info->EPwmMaxCMPB)
               {
                  epwm_info->EPwmRegHandle->CMPB.bit.CMPB++;
               }
               else
               {
                  epwm_info->EPwm_CMPB_Direction = EPWM_CMP_DOWN;
                  epwm_info->EPwmRegHandle->CMPB.bit.CMPB--;
               }
           }
    
           //
           // If we were decreasing CMPB, check to see if
           // we reached the min value.  If not, decrease CMPB
           // else, change directions and increase CMPB
           //
           else
           {
               if(epwm_info->EPwmRegHandle->CMPB.bit.CMPB ==
                  epwm_info->EPwmMinCMPB)
               {
                  epwm_info->EPwm_CMPB_Direction = EPWM_CMP_UP;
                  epwm_info->EPwmRegHandle->CMPB.bit.CMPB++;
               }
               else
               {
                  epwm_info->EPwmRegHandle->CMPB.bit.CMPB--;
               }
           }
       }
       else
       {
          epwm_info->EPwmTimerIntCount++;
       }
    
       return;
    }
    
    //
    // End of file
    //
    

    Thank you.

    Regards,

    Amin