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.

TMS320F280049: Problem with external interrupts and SCI interrupts

Part Number: TMS320F280049
Other Parts Discussed in Thread: C2000WARE

Hello,

I have a problem with the interrupts on the F280049.

I tried to configure all interrupts, relating to the technichal reference manual, example codes and some threads on this forum.

But I'm still not able to trigger an interrupt and get into the ISR.

The only interrupt tha is working, is the ADC interrupt .

This is my code:

it is supposed to control a half bridge converter and transfer some data by SCI. On GPIO 13 is a switch and on GPIO 2 and 3 there are some LEDs.

#include "F28x_Project.h"
#include "SFO_V8.h"
#include <stdio.h>
#include "basics.h"


//
// Defines
//
#define RESULTS_BUFFER_SIZE     100
#define DEVICE_GPIO_PIN_LED1    6
#define DEVICE_GPIO_PIN_LED2    7
#define DEVICE_GPIO_PIN_OUT1    28
#define DEVICE_GPIO_PIN_OUT2    29

#define KI 229 // 429
#define KP 2.73
#define TA 0.0002
//
// Globals
//

uint16_t index;                              // Index into result buffer
volatile uint16_t bufferFull;                // Flag to indicate buffer is full
Uint16 period = 2500;                        // TBPRD
char *msg;                          // contains SCI message
char *num;
float actVoltage;                              // measured DC voltage in V
float actCurrent = 0;                          // measured current in A
char buffer [50];
int actCurrentADC;


int esum;                                    // summed up error for PI Controller
int setpointCurrent = 20;                         // setpoint current
float dutyCycle;                          // duty Cycle
float firCurrent;                              //setpointcurrent after PT1
float lastI;                                   // y(k-1) for PT1
float tFIR = 0.0002 * 1000;
// tFIR = dT/ (T+dT) for PT1



int sw = 0;


//
// Function Prototypes
//
void initADC(void);
void initEPWM(void);
void initADCSOC(void);
__interrupt void adcA1ISR(void);
__interrupt void sciRXISR(void);
__interrupt void switchISR(void);
void initHRPWM1GPIO(void);
void configHRPWM(uint16_t period);
void error(void);
void initPeriph(void);
void transmitSCIAChar(uint16_t a);
void transmitSCIAMessage(char * msg);
void initSCIAFIFO(void);
void initSCIA(void);





/**
 * main.c
 */
int main(void)
{



    InitSysCtrl();

	    //
	    // Initialize GPIO
	    //
	    InitGpio();
	    initHRPWM1GPIO();

	    //
	    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
	    //
	    DINT;
	    InitPieCtrl();
	    IER = 0x0000;
	    IFR = 0x0000;

	    //
	    // Initialize the PIE vector table with pointers to the shell Interrupt
	    // Service Routines (ISR).
	    //
	    InitPieVectTable();

	    EINT;
	    ERTM;

	    //
	    // Map ISR functions
	    //
	    EALLOW;
	    PieVectTable.ADCA1_INT = &adcA1ISR;     // Function for ADCA interrupt 1
	    PieVectTable.SCIA_RX_INT = &sciRXISR;  //Function for SCIA Interrupt
	    PieVectTable.XINT1_INT = &switchISR; //Function for GPIO Interrupt
	    EDIS;

	    //DELAY_US(9000000);

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

	    //
	    // Configure the ePWM
	    //
	    initEPWM();

	    //
	    // Configure LED Output
	    //
	    initPeriph();

	    initSCIAFIFO();                         // Initialize the SCI FIFO
	    initSCIA();                             // Initialize SCI
	    //
	    // Setup the ADC for ePWM triggered conversions on channel 1
	    //
	    initADCSOC();

	    //
	    // 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


	    index = 0;
	    bufferFull = 0;

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

	    //
	    // Sync ePWM
	    //
	    EALLOW;
	    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;


	    //---actual main routine---

	    //msg = "\r\n\n\nHello World!\0";
	    //transmitSCIAMessage(msg);

	    //
	    // Take conversions indefinitely in loop
	    //


        EPwm1Regs.ETSEL.bit.SOCAEN = 1;    // Enable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;   // Unfreeze, and enter up- down count mode
        GPIO_WritePin(DEVICE_GPIO_PIN_LED1, 0);
        GPIO_WritePin(DEVICE_GPIO_PIN_LED2, 1);



        //MAIN ROUTINE
        while(1)
	    {
	        msg = "\r\n Strom: \0";
	        float2char(actCurrent, num);
            transmitSCIAMessage(msg);
            transmitSCIAMessage(num);

            msg = "\r\n Spannung: \0";
            float2char(actVoltage, num);
            transmitSCIAMessage(msg);
            transmitSCIAMessage(num);

            msg = "\r\n DutyCycle: \0";
            float2char(dutyCycle, num);
            transmitSCIAMessage(msg);
            transmitSCIAMessage(num);

	        DELAY_US(3000000);

	    }

	    return 0;
}


void initEPWM(void)
{
    EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;  // set shadow load - new values will be loaded in registers when counter = 0
    EPwm1Regs.TBPRD = period-1;             // PWM frequency = 1 / period
    EPwm1Regs.CMPA.bit.CMPA = period / 25;   // set duty 50% initially
    EPwm1Regs.CMPA.bit.CMPAHR = (1 << 8);   // initialize HRPWM extension
    EPwm1Regs.CMPB.bit.CMPB = period / 25;   // set duty 50% initially
    EPwm1Regs.CMPB.all |= (1 << 8);         // initialize HRPWM extension
    EPwm1Regs.TBPHS.all = 0;
    EPwm1Regs.TBCTR = 0;

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE;
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x1; // /2
    EPwm1Regs.TBCTL.bit.CLKDIV = 0x2; // /4 => Overall divider = 8 => TBCLK = 12.5 MHz
    EPwm1Regs.TBCTL.bit.FREE_SOFT = 11;

    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;

    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;      // PWM toggle high/low
    EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;
    EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
    EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;

    EPwm1Regs.DBCTL.bit.POLSEL = DBB_ENABLE;
    EPwm1Regs.DBCTL.bit.OUT_MODE = 0x3;
    EPwm1Regs.DBFED.all = 125; // equals 10us
    EPwm1Regs.DBRED.all = 125;

    EALLOW;
    EPwm1Regs.HRCNFG.all = 0x0;
    EPwm1Regs.HRCNFG.bit.EDGMODE = HR_FEP;  // MEP control on falling edge
    EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP;
    EPwm1Regs.HRCNFG.bit.HRLOAD  = HR_CTR_ZERO;
    EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_FEP; // MEP control on falling edge
    EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP;
    EPwm1Regs.HRCNFG.bit.HRLOADB  = HR_CTR_ZERO;

    EPwm1Regs.HRPCTL.bit.HRPE = 0; // Turn off high-resolution period
                                    // control.


    EPwm1Regs.ETSEL.bit.SOCAEN = 0;     // Disable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 3;    // Select SOC on ZERO and PRD
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;     // Generate pulse on 1st event


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

    EDIS;
}

void initADC(void)
{
    //
    // Setup VREF as internal
    //
    SetVREF(ADC_ADCA, ADC_EXTERNAL, ADC_VREF3P3);
    SetVREF(ADC_ADCB, ADC_EXTERNAL, ADC_VREF3P3);

    EALLOW;

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

    //
    // Set pulse positions to late
    //
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    //
    // Power up the ADC and then delay for 1 ms
    //
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;

    EDIS;

    DELAY_US(1000);
}

// Sets the GPIO Mux for the peripherals and IOs.
void initPeriph(void)
{
    //LED Config
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED1, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED1, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_LED2, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_LED2, GPIO_OUTPUT, GPIO_PUSHPULL);

    //SCI Config
    GPIO_SetupPinMux(3, GPIO_MUX_CPU1, 9);
    GPIO_SetupPinOptions(3, GPIO_INPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(2, GPIO_MUX_CPU1, 9);
    GPIO_SetupPinOptions(2, GPIO_OUTPUT, GPIO_ASYNC);

    //24V IO Config
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_OUT1, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_OUT1, GPIO_OUTPUT, GPIO_PUSHPULL);
    GPIO_SetupPinMux(DEVICE_GPIO_PIN_OUT2, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(DEVICE_GPIO_PIN_OUT2, GPIO_OUTPUT, GPIO_PUSHPULL);


     // Make GPIO13 the input source for XINT1
     //


    GPIO_SetupPinMux(13, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(13, GPIO_INPUT, GPIO_PULLUP);
    GPIO_SetupXINT1Gpio(13);              // XINT1 connected to GPIO13
    EALLOW;
    XintRegs.XINT1CR.bit.POLARITY = 0;
    XintRegs.XINT1CR.bit.ENABLE = 1;
    EDIS;
}

void initADCSOC(void)
{
    //
    // Select the channels to convert and the end of conversion flag
    //
    EALLOW;

    AdcaRegs.ADCSOC0CTL.bit.CHSEL = 1;     // SOC0 will convert pin A1
                                           // 0:A0  1:A1  2:A2  3:A3
                                           // 4:A4   5:A5   6:A6   7:A7
                                           // 8:A8   9:A9   A:A10  B:A11
                                           // C:A12  D:A13  E:A14  F:A15
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = 19;    // Sample window is 20 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;   // Trigger on ePWM1 SOCA

    AdcbRegs.ADCSOC0CTL.bit.CHSEL = 3;     // Set ADCB simultaneous to ADCA
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = 19;
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 5;

    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;
}

void initHRPWM1GPIO(void)
{
    EALLOW;

    //
    // Disable internal pull-up for the selected output pins
    // for reduced power consumption
    // Pull-ups can be enabled or disabled by the user.
    //
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1;    // Disable pull-up on GPIO0 (EPWM1A)
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1;    // Disable pull-up on GPIO1 (EPWM1B)

    //
    // Configure EPWM-1 pins using GPIO regs
    // This specifies which of the possible GPIO pins will be EPWM1 functional
    // pins.
    //
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;   // Configure GPIO0 as EPWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;   // Configure GPIO1 as EPWM1B

    EDIS;
}


//Interrupt when SCIRX FIFO received a word
__interrupt void sciRXISR(void){

    //GPIO_WritePin(DEVICE_GPIO_PIN_LED2, 0);
    //GPIO_WritePin(DEVICE_GPIO_PIN_LED1, 0);
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}


//Interrupt when switch is triggered
__interrupt void switchISR(void){

    if (sw == 0){
        sw = 1;
        GPIO_WritePin(DEVICE_GPIO_PIN_LED2, 0);
        GPIO_WritePin(DEVICE_GPIO_PIN_LED1, 0);
    }
    else{
        sw = 0;
        GPIO_WritePin(DEVICE_GPIO_PIN_LED2, 1);
        GPIO_WritePin(DEVICE_GPIO_PIN_LED1, 1);
    }
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//
// adcA1ISR - ADC A Interrupt 1 ISR
//
__interrupt void adcA1ISR(void)
{

    //PTI Filter
    lastI = firCurrent;
    firCurrent = lastI + (setpointCurrent - lastI) * tFIR;


    actVoltage = AdcbResultRegs.ADCRESULT0 * 0.0537109375;   // 1unit = 0,0537109375V
    int temp = AdcaResultRegs.ADCRESULT0;
    actCurrent = (temp - 1862) * 0.057139; // calculate actual current: 500A = 3V ,1862unit =  1.5V = 0V (offset) => 1unit = 0,26853A
    //actCurrentADC = AdcaResultRegs.ADCRESULT0;
    float y = 0;

    // PI-Controller
    float e = 0; // error
    e = firCurrent- actCurrent;
    esum = esum + e;
    y = KP * e + KI * TA * esum;
    dutyCycle = (y / actVoltage);

    if (dutyCycle <= 0) {
        dutyCycle = 0;
    }
    else if (dutyCycle >= 0.99) {
        dutyCycle = 0.99;
    }

    int newperiod = dutyCycle * period;
    EPwm1Regs.CMPA.bit.CMPA = newperiod;
    EPwm1Regs.CMPB.bit.CMPB = newperiod;





    //
    // Clear the interrupt flag and issue ACK
    //
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void initSCIA(void)
{
    //
    // Note: Clocks were turned on to the SCIA peripheral
    // in the InitSysCtrl() function
    //
    SciaRegs.SCICCR.all = 0x0007;           // 1 stop bit,  No loopback
                                            // No parity, 8 char bits,
                                            // async mode, idle-line protocol
    SciaRegs.SCICTL1.all = 0x0003;          // enable TX, RX, internal SCICLK,
                                            // Disable RX ERR, SLEEP, TXWAKE
    SciaRegs.SCICTL2.all = 0x0003;
    SciaRegs.SCICTL2.bit.TXINTENA = 1;
    SciaRegs.SCICTL2.bit.RXBKINTENA = 1;

    //
    // SCIA at 9600 baud
    // @LSPCLK = 25 MHz (100 MHz SYSCLK) HBAUD = 0x01  and LBAUD = 0x44.
    //
    SciaRegs.SCIHBAUD.all = 0x0001;
    SciaRegs.SCILBAUD.all = 0x0044;

    SciaRegs.SCICTL1.all = 0x0023;          // Relinquish SCI from Reset
}

//
// transmitSCIAChar - Transmit a character from the SCI
//
void transmitSCIAChar(uint16_t a)
{
    while (SciaRegs.SCIFFTX.bit.TXFFST != 0)
    {

    }
    SciaRegs.SCITXBUF.all = a;
}

//
// transmitSCIAMessage - Transmit message via SCIA
//
void transmitSCIAMessage(char * msg)
{
    int i;
    i = 0;
    while(msg[i] != '\0')
    {
        transmitSCIAChar(msg[i]);
        i++;
    }
}

//
// initSCIAFIFO - Initialize the SCI FIFO
//
void initSCIAFIFO(void)
{
    SciaRegs.SCIFFTX.all = 0xE040;
    SciaRegs.SCIFFRX.all = 0x2044;
    SciaRegs.SCIFFCT.all = 0x0;
}

Thank you for your help

Sebastian

  • Sebastian,

    You only enabled the PIE interrupt for the ADC (1.1) and not the other interrupts. This should explain why you are not receiving the other interrupts.

    Please let me know if you have any further questions. Also, please click the green "Verified Answer" button if you are satisfied with the support that I provided. Thank you again.

    - Ken
  • Hello,
    Thanks for the fast answere.
    I changed the following lines:

    IER |= M_INT1; // Enable group 1 interrupts
    IER |= M_INT9;
    
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    
    //
    // Initialize results buffer
    //
    
    
    //
    // Enable PIE interrupt
    //
    PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx4 = 1;
    PieCtrlRegs.PIEIER9.bit.INTx1 = 1;
    


    The XINT1 is working now!
    But the SCI interrupt is still not working.

  • Sebastian,

    The SCI code you are using is the Echoback example. With this example, you send a character and then receive the character back. Is this what you want to do? You need to debug your code using breakpoints, etc.

    In general, we do not review or debug user code, but we will provide assistance to you with specific issues relating to our devices and development tools. This includes clarifying the behavior of any bit, register, or features when designing with our devices. Please note that all peripherals have example code in C2000Ware. We suggest comparing your code to the example code to determine where the problem may exist. It is recommended to follow standard and logical debugging techniques. Please continue to debug your code and feel free to use this forum to ask specific questions. The more specific the question, the better we can assist you.

    - Ken
  • Hello Ken,

    is there any code example for the f280049 using the SCI interrupt?
    Echoback is not using the interrupt, if I see that correctly.

    Sebastian
  • Sebastian,

    You can either use the F28004x SCI Driver Library examples found at:

    C:\ti\c2000\C2000Ware_<version>\driverlib\f28004x\examples\sci

    or modify (i.e. use as a guide) the F2807x header file bit field examples found at:

    C:\ti\c2000\C2000Ware_<version>\device_support\f2807x\examples\cpu1\

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

    - Ken