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/TMS320F28379D: External interrupt

Part Number: TMS320F28379D


Tool/software: Code Composer Studio

Hello all,

               This is Sainath. I am very new to the family of c2000 microcontrollers. I am working on ADC triggering using PWM module which has been done successfully. I have normalized the ADC result buffer values in my code. I am trying to trigger the normalization code only using an external interrupt (from a comparator).

Can it be done by connecting the comparator output to the external interrupt pin???    

Please find my code attached below.

#include "F28x_Project.h"

//
// Function Prototypes
//
void ConfigureADC(void);

void ConfigureEPWM(void);

void SetupADCEpwm(Uint16 channel);

interrupt void adca1_isr(void);

float Corr();

//
// Defines
//

#define RESULTS_BUFFER_SIZE 256

//
// Globals
//

Uint16 AdcaResults[RESULTS_BUFFER_SIZE];

Uint16 resultsIndex;

volatile Uint16 bufferFull;

int bufferIndex = 0;

float normalized_array[RESULTS_BUFFER_SIZE] = {0};

float filter[400] = {0.0163,-0.0069,0.0103,0.0088,0.0109,0.0165 ,0.0224,-0.0091,0.0094,-0.0081,0.0114,0.0060,0};

float result[256] = {0};

float Corr()

{

float out = 0;

int i = 0;

int index = 0;

for (i = 0; i < 256; i++)

{
    index = ((i + resultsIndex + 1) % 256);

    out = out + (normalized_array[index-1] * filter[i]);

}

return out;

}



void main(void)

{
//
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the F2837xD_SysCtrl.c file.
//

    InitSysCtrl();

//
// Step 2. Initialize GPIO:
// This example function is found in the F2837xD_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 F2837xD_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 F2837xD_DefaultIsr.c.
// This function is found in F2837xD_PieVect.c.
//

    InitPieVectTable();

//
// Map ISR functions
//

    EALLOW;

    PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1

    EDIS;

//
// Configure the ADC and power it up
//
    ConfigureADC();

//
// Configure the ePWM
//

    ConfigureEPWM();

//
// Setup the ADC for ePWM triggered conversions on channel 0
//

    SetupADCEpwm(0);

//
// Enable global Interrupts and higher priority real-time debug events:
//
    IER |= M_INT1; //Enable group 1 interrupts

    EINT;  // Enable Global interrupt INTM

    ERTM;  // Enable Global realtime interrupt DBGM

//
// Initialize results buffer
//
    for(resultsIndex = 0; resultsIndex < RESULTS_BUFFER_SIZE; resultsIndex++)

    {

        AdcaResults[resultsIndex] = 0;

    }

    resultsIndex = 0;

    bufferIndex = 0;

    bufferFull = 0;

//
// enable PIE interrupt
//
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;

//
// sync ePWM
//

    EALLOW;

    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

//
//take conversions indefinitely in loop
//
    do

    {
        //
        //start ePWM
        //

        EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA

        EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode

        //
        //wait while ePWM causes ADC conversions, which then cause interrupts,
        //which fill the results buffer, eventually setting the bufferFull
        //flag
        //

        while(!bufferFull);

        bufferFull = 0; //clear the buffer full flag

        //
        //stop ePWM

        //

        EPwm1Regs.ETSEL.bit.SOCAEN = 0;  //disable SOCA

        EPwm1Regs.TBCTL.bit.CTRMODE = 3; //freeze counter

        //
        //at this point, AdcaResults[] contains a sequence of conversions
        //from the selected channel
        //

        //
        //software breakpoint, hit run again to get updated conversions
        //
          asm("   ESTOP0");

    }while(1);

}

//
// ConfigureADC - Write ADC configurations and power up the ADC for both
//                ADC A and ADC B
//

void ConfigureADC(void)

{

    EALLOW;

    //
    //write configurations
    //

    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4

    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);

    //
    //Set pulse positions to late
    //

    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;

    //
    //power up the ADC
    //

    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    //
    //delay for 1ms to allow ADC time to power up
    //

    DELAY_US(1000);

    EDIS;
}

//
// ConfigureEPWM - Configure EPWM SOC and compare values
//

void ConfigureEPWM(void)

{
    EALLOW;

    // Assumes ePWM clock is already enabled

    EPwm1Regs.ETSEL.bit.SOCAEN = 0;    // Disable SOC on A group

    EPwm1Regs.ETSEL.bit.SOCASEL = 4;   // Select SOC on up-count

    EPwm1Regs.ETPS.bit.SOCAPRD = 1;       // Generate pulse on 1st event

    EPwm1Regs.CMPA.bit.CMPA = 142;     // Set compare A value to 2048 counts

    EPwm1Regs.TBPRD = 248;             // Set period to 4096 counts

    EPwm1Regs.TBCTL.bit.CTRMODE = 3;      // freeze counter

    EDIS;

}

//
// SetupADCEpwm - Setup ADC EPWM acquisition window
//

void SetupADCEpwm(Uint16 channel)

{
    Uint16 acqps;

    //
    //determine minimum acquisition window (in SYSCLKS) based on resolution
    //

    if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)

    {

        acqps = 14; //75ns

    }

    else //resolution is 16-bit

    {

        acqps = 63; //320ns

    }

    //
    //Select the channels to convert and end of conversion flag
    //

    EALLOW;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel;  //SOC0 will convert pin A0

    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles

    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C

    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag

    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared

    EDIS;

}

//
// adca1_isr - Read ADC Buffer in ISR
//

interrupt void adca1_isr(void)

{
    AdcaResults[resultsIndex] = AdcaResultRegs.ADCRESULT0;

    normalized_array[resultsIndex] = ((2.0*AdcaResults[resultsIndex])/4095.0) - 1.0;    // I want to trigger this code only when there is an external interrupt

    result[resultsIndex] = Corr();

    resultsIndex++;

    bufferIndex++;

    if(RESULTS_BUFFER_SIZE <= resultsIndex && bufferIndex <= RESULTS_BUFFER_SIZE)

    {
        resultsIndex = 0;

        bufferFull = 1;

        bufferIndex = 0;

    }

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

It would be really helpful if someone can give me some suggestions on how to approach it.

Thank you.

Best Regards,

Sainath.
  • Sainath,

    The F28379D has 5 external interrupt signals: XINT1, XINT2, XINT3, XINT4 and XINT5. Each can be mapped to any of GPIO pins via the Input X-Bar architecture. Your external signal can then be connected to the assigned GPIO pin and when triggered will run the ISR. See chapters 7 and 8 in the F28379D TRM (spruhm8g.pdf) for more information on the GPIO pins and X-BARs. Also, the following workshop might be helpful to you:

    processors.wiki.ti.com/.../C2000_Multi-Day_Workshop

    Module 5 has information on the Input X-BAR, and you will also find the lab exercises that use an ePWM to trigger the ADC.

    I hope this helps. If this answers your question, please click the green "Verified Answer" button. Thanks.

    - Ken
  • Hello Ken,

    Thank you ken for your immediate response. Your suggestions helped me a lot. Actually, I am continuously storing the ADC values into a buffer and I am trigger my normalization instruction only when there is an external interrupt. Whenever an interrupt occurs, then I want continue the normalization instruction for 9milliseconds more. Can you suggest me on how to approach it.

    Thank you so much.

    Best Regards,

    Sainath Reddy.
  • Sainath,

    Note that "enabled" interrupts are serviced immediately (with a delay to get in to the ISR). I am note fully sure about the question you are asking. Do you want to have the normalization instruction run for 9 ms in the ISR? If so, run the normalization instruction in a loop with a delay function.

    I hope this helps. If this answers your question, please click the green "Verified Answer" button. Thanks.

    - Ken