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.

ADC-trigger by epwm (repost)

Hello,

 

a few days ago I asked about a specific problem I have in another thread:

http://e2e.ti.com/support/microcontrollers/c2000/f/171/p/155087/1193290.aspx#1193290

 

As I did not get an answer I was wondering about the reason. Could the thread's status "answered" be the reason?

 

Please delete this thread if you consider this as spam. I do not like pushing threads, I only started to wonder.

 

Regards,

E_

  • Hi E_,

    As I did not get an answer I was wondering about the reason. Could the thread's status "answered" be the reason?

    Yes, that is one part and another is you're not supposed to embed your query in other's thread. You're supposed to create a new one for every query you've. This will give you the power to verify the answers.

    Please post the same query below this post so that you can start receiving responses.

    Regards,

    Gautam

  • Hello Gautam, thank you for your quick answer.

    So here I will post my query:

    I have been trying to setup up my adc to be triggered by epwm, exactly the same way the author of this thread is doing, but I do not get any result when I change voltage on any pin.
    Here are some code-snippets:

    PWM-setup:

    1
    2
    3
    4
    5
    6
    7
    EPwm1Regs.ETSEL.bit.INTSEL =
    ET_CTR_ZERO;     // Select INT on Zero event
    EPwm1Regs.ETSEL.bit.INTEN =1;               // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD =ET_1ST;           // Generate INT on 1st event
    EPwm1Regs.ETSEL.bit.SOCAEN =1;        // Enable SOC on Agroup
    EPwm1Regs.ETSEL.bit.SOCASEL =1;//4;   // modified
    EPwm1Regs.ETPS.bit.SOCAPRD =1;        // Generate pulse on 1st event

    ADC-setup:

    1
    2
    3
    4
    5
    6
    7
    8
    AdcRegs.ADCTRL3.bit.ADCCLKPS =2;
    AdcRegs.ADCTRL1.bit.CPS =1;
    AdcRegs.ADCTRL1.bit.ACQ_PS =4;
    AdcRegs.ADCTRL3.bit.SMODE_SEL =0x1;
    AdcRegs.ADCMAXCONV.all = 0x0033; // 4 double conv's each sequencer (8 total)AdcRegs.ADCTRL1.bit.CONT_RUN =0; // manual reset
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 =0x0;
    //(…) conv 1 to 10...
    AdcRegs.ADCCHSELSEQ3.bit.CONV11 =0x7;

    The interrupt service routine works just fine, the pie-groups are acknowledged on every interrupt as shown in the examples.
    When I call the sequence like this in every ISR

    1
    2
    3
    Value1=AdcRegs.ADCRESULT0;//trying to read
    //(…)
    Value2=AdcRegs.ADCRESULT4;//trying to read

    There is no change of value 1 or 2 in the watch window. As you see, I don't care for the right shift of these bits at this time, I will correct that later on. I know that the adc works, as it does in the in the adcsoc-example, so the problem is - as usual - sitting right in front of the screen in my case :-)

    Can anybody help me out here?
    Looking forward to your answer.

    Regards,

    E_

    [EDIT: I just don't want to forget to mention that maybe I will not be able to try out suggested solutions too soon...]

  • Hi,

    You've not mentioned the device you're working on. Anyways, I'll assume you're using F28335 and have attached an example code of ePWM triggered ADC.

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    // Prototype statements for functions found within this file.
    interrupt void adc_isr(void);
    
    // Global variables used in this example:
    Uint16 LoopCount;
    Uint16 ConversionCount;
    Uint16 Voltage1[10];
    Uint16 Voltage2[10];
    
    
    main()
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();
    
    
       EALLOW;
       #if (CPU_FRQ_150MHZ)     // Default - 150 MHz SYSCLKOUT
         #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3)   = 25.0 MHz
       #endif
       #if (CPU_FRQ_100MHZ)
         #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2)   = 25.0 MHz
       #endif
       EDIS;
    
       // Define ADCCLK clock frequency ( less than or equal to 25 MHz )
       // Assuming InitSysCtrl() has set SYSCLKOUT to 150 MHz
       EALLOW;
       SysCtrlRegs.HISPCP.all = ADC_MODCLK;
       EDIS;
    
    // Step 2. Initialize GPIO:
    // This example function is found in the DSP2833x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example
    
    // 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 DSP2833x_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 DSP2833x_DefaultIsr.c.
    // This function is found in DSP2833x_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 register
       PieVectTable.ADCINT = &adc_isr;
       EDIS;    // This is needed to disable write to EALLOW protected registers
    
    // Step 4. Initialize all the Device Peripherals:
    // This function is found in DSP2833x_InitPeripherals.c
    // InitPeripherals(); // Not required for this example
       InitAdc();  // For this example, init the ADC
    
    // Step 5. User specific code, enable interrupts:
    
    // Enable ADCINT in PIE
       PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
       IER |= M_INT1; // Enable CPU Interrupt 1
       EINT;          // Enable Global interrupt INTM
       ERTM;          // Enable Global realtime interrupt DBGM
    
       LoopCount = 0;
       ConversionCount = 0;
    
    // Configure ADC
       AdcRegs.ADCMAXCONV.all = 0x0001;       // Setup 2 conv's on SEQ1
       AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // Setup ADCINA3 as 1st SEQ1 conv.
       AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
       AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1
       AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)
    
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
       EPwm1Regs.ETSEL.bit.SOCAEN = 1;        // Enable SOC on A group
       EPwm1Regs.ETSEL.bit.SOCASEL = 4;       // Select SOC from from CPMA on upcount
       EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event
       EPwm1Regs.CMPA.half.CMPA = 0x0080;	  // Set compare A value
       EPwm1Regs.TBPRD = 0xFFFF;              // Set period for ePWM1
       EPwm1Regs.TBCTL.bit.CTRMODE = 0;		  // count up and start
    
    // Wait for ADC interrupt
       for(;;)
       {
          LoopCount++;
       }
    
    }
    
    
    interrupt void  adc_isr(void)
    {
    
      Voltage1[ConversionCount] = AdcRegs.ADCRESULT0 >>4;
      Voltage2[ConversionCount] = AdcRegs.ADCRESULT1 >>4;
    
      // If 40 conversions have been logged, start over
      if(ConversionCount == 9)
      {
         ConversionCount = 0;
      }
      else ConversionCount++;
    
      // Reinitialize for next ADC sequence
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;         // Reset SEQ1
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;       // Clear INT SEQ1 bit
      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE
    
      return;
    }
    
    
    
    

    Regards,

    Gautam

  • oh, sorry, yes, it's the 28335. I forgot about that because of the link.

     

    Thank you. Afaic this code example is a modified version of the adc_soc coming with control suite.

    I guess I still have to set the bandgap powerup. What is the delay good for as it is only called once?

  • What is the delay good for as it is only called once?

    Which delay are you talking about? Can you please specify?

  • delay understood, me blind, sry.

    Seems to work now. Thank you!