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.

CCS/TMS320F28069M: [Problem] ADC SOC

Part Number: TMS320F28069M


Tool/software: Code Composer Studio

Hi all,

I am trying to realize an Peak Current Mode controller and want to create an ADC interrupt on the EPWM1B falling edge.

See:

When I run the code below, The GPIO triggers 1uS later than the rising edge of EPWM1B.

And I want to run it on the falling edge, any idea why this problem occurs?

void InitEPwm1()
{
//
// Enable TZ1 and TZ2 as one shot trip sources
//
EALLOW;

//EPwm1Regs.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBPRD = 449;// Period = 300 TBCLK counts // (200 KHz @ 60MHz clock)
EPwm1Regs.CMPA.half.CMPA = 449;
EPwm1Regs.CMPB = 228; // Compare B = 400 TBCLK counts
EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Phase loading disabled
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;

EPwm1Regs.TBCTR = 0; // clear TB counter
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on TBCTR = Zero
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on TBCTR = Zero

EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // Set PWM1A on Zero
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;

EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR;

// Define an event (DCA

EDIS;
}

void ADC_INIT(void)
{
/* ADC with interrupt on ePWM1B */
EALLOW;

AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG
AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG


AdcRegs.ADCCTL2.bit.ADCNONOVERLAP = 1; // Enable non-overlap mode / CLA
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; // Enable non-overlap mode / CLA
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; // Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; // Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 1; // setup EOC1 to trigger ADCINT1 to fire

AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 6;
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 6;
AdcRegs.ADCSOC0CTL.bit.CHSEL = 9; // Vout B1
AdcRegs.ADCSOC1CTL.bit.CHSEL = 10; // Vout B2

EPwm1Regs.ETSEL.bit.SOCBEN = 1;
EPwm1Regs.ETSEL.bit.SOCBSEL = 6; // 6
EPwm1Regs.ETPS.bit.SOCBPRD = 1;

EDIS;
}

void GPIO_INIT(void)
{
EALLOW;
// General purpose input/output
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 0;
GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;

// GPIO as output
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;
GpioCtrlRegs.GPBDIR.bit.GPIO39 = 1;
GpioCtrlRegs.GPADIR.bit.GPIO19 = 1;

// GPIO Turn off/on (1 = off, 0 is on)
GpioDataRegs.GPBSET.bit.GPIO34 = 1;
GpioDataRegs.GPBSET.bit.GPIO39 = 0;
//GpioDataRegs.GPASET.bit.GPIO19 = 1;
EDIS;
}

  • Klaas,

    Are you monitoring GPIO12? When you say "The GPIO triggers," which edge direction do you mean (rising / falling)? When do you see the complementary GPIO edge? Did you compile with optimization?

    -Tommy
  • No I was monitoring GPIO19. I mean the falling edge direction.

    I did compile it using the normal way, so I don't think I did it with optimalisation.

    Anyway, I got it working.. The 'problem' was that I was't executing it from ram, now I do and it's much faster.

    Except it takes around 1uS to go in the ADC interrupt after the Adc conversion, why is this so long and is it possible to make this delay shorter?

  • Klaas,

    I do not see GPIO19 configured in the reference code associated with the appnote so I cannot comment on what that signal is doing in your system.

    How are you determining when the ADC interrupt begins? The reference code uses GPIO12 for external profiling. A more precise way of measuring the latency would be to read the EPWM TBCTR value from within the ISR. Since you know that the ADC was triggered by CMPB up, you can compare the present TCBTR value against CMPB to know how many EPWM ticks elapsed.

    The interrupt latency consists of the ADC conversion time (determined by ADC settings) and the inherent ISR context switch time that is typically in the range of 14 cycles under optimal conditions.

    -Tommy

  • Well, you are right.. I didn't add the code of the ISR.

    When I set CMPB Value to 100, it will go in my interrupt on around 203 (@200khz, 90Mhz clock, TBPRD = 450).

    This is a huge delay, any idea why so much clock cycle are needed?

    Thanks!

  • Are you saving the TBCTR value in the ISR to a variable for observation? Reading TBCTR directly through an expressions window will not be accurate.

    The ADCINT1 signal is not asserted until the conversions are complete so with your current ADC configuration of 2 conversions in non-overlap mode and CLKDIV2, you have: 2 conversions x 20 cycles x 2 SYSCLK = ~80 ticks for the ADC conversions.

    If you assume ~20 ticks for the ISR to respond, that leaves ~100 ticks remaining.

    Do you have any blocking events in the system like other interrupts or atomic operations?
  • Thanks for answering, this makes everything more clear for me! I expected to be much faster than 444ns per channel/sample.