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: Program stuck at the end of uPP Interrupt Service Routine (local_UPPA_ISR) while receiving data

Part Number: TMS320F28379D
Other Parts Discussed in Thread: TMDSCNCD28379D, TMDSHSECDOCK

Tool/software: Code Composer Studio

I have two controlCARDs (TMDSCNCD28379D) with two docks (TMDSHSECDOCK HSEC180). One of the CARDs is configured to transmit data through uPP (Universal Parallel Port) using provided example code (upp_sdr_tx_cpu01.c). I just want to transmit a 32-bit data (4 8-bit data, 4 words, 4 bytes) from this CARD to another receiving CARD and store it in GS0 RAM in the receiving CARD and then wait for the user to press "Run" button again in debugger mode to receive the next 32-bit data. So, I defined LINE_CNT = 1; BYTE_CNT = 4; WIN_CNT = 1 and line_offset as zero in both receiving and transmitting microcontrollers. I first run the code in receiving microcontroller (where it waits for EOWI interrupt) and then run the code in transmitting microcontroller (where the 32-bit data is stored in uPP_TX_MSGRAM_ADDR, transmission is started and the program waits in do while loop with asm("      ESTOP0") command). The receiving microcontroller sees EOWI interrupt and the ISR is executed perfectly and the received data is stored in GS0 RAM (as per the expectation). I then run the code again on receiving microcontroller and then on the transmitting microcontroller and the next 32-bit data is also received. This happens 3-4 times and then the program is receiving microcontroller gets stuck at the end of ISR or maybe in the while loop (not sure) because the value in RdValue is 2. The code for receiving microcontroller is attached below:

__________________________________________________________________

//
// Included Files
//
#include "F28x_Project.h"
#include "F2837xD_Upp_defines.h"

//
// Defines
//
#define TEST_PASS 0xABCDABCD
#define TEST_FAIL 0xDEADDEAD
#define LINE_CNT 1
#define BYTE_CNT 4
#define WIN_CNT 1

//
// Globals
//
volatile long int ErrCount = 0;
volatile long int TEST_STATUS = TEST_FAIL;
volatile long int eow_int_cnt = 0;
volatile long int RdValue = 0;
volatile int CopyRxMsgRam = 0;
volatile long int DstAddr = 0xC000;                        // GS0 RAM

// Function Prototypes

extern void InitUpp1Gpio(void);
extern void SoftResetUpp(void);
interrupt void local_UPPA_ISR(void);


// Main

void main(void)
{

TEST_STATUS = TEST_FAIL;
ErrCount = 0x0;


InitSysCtrl();                                               // Initialize System Control

DINT;

InitPieCtrl();


// Disable CPU interrupts and clear all CPU interrupt flags:

EALLOW;
IER = 0x0000;
IFR = 0x0000;
EDIS;


InitPieVectTable();

EALLOW;
PieVectTable.UPPA_INT = &local_UPPA_ISR;


IER = M_INT8 ;                                            // Enable the Interrupt No 8

PieCtrlRegs.PIEIER8.bit.INTx15=1;            // Enable Interrupt for UPPA Interrupt

EnableInterrupts();                                       // Enable PIE & CPU level Interrupts

MemCfgRegs.GSxINIT.bit.INIT_GS0 = 1;                                                        // Clear the RAM used for storing incoming data packet
while (MemCfgRegs.GSxINITDONE.bit.INITDONE_GS0 == 0){};

SoftResetUpp();

InitUpp1Gpio();

// Configure uPP for RX
UppRegs.IFCFG.bit.ENAA = 1; //Use ENABLE Signal
UppRegs.IFCFG.bit.STARTA = 1; //Use START Signal
UppRegs.CHCTL.bit.MODE = uPP_RX_MODE; // Setup for TX.
UppRegs.CHCTL.bit.DRA = uPP_SDR; // SDR mode

UppRegs.INTENSET.bit.EOWI = 1;                         // Enable EOW interrupt
UppRegs.GINTEN.bit.GINTEN = 1;

UppRegs.PERCTL.bit.PEREN = 1;                         // Enable the uPP module

do{

// Setup DMA channel


UppRegs.CHIDESC0 = 0x7000;
UppRegs.CHIDESC1.bit.LCNT = LINE_CNT;
UppRegs.CHIDESC1.bit.BCNT = BYTE_CNT;
UppRegs.CHIDESC2.all = 0;

RdValue = 0x1234;                                               // To check in expressions window if the program is waiting in while loop

while (UppRegs.ENINTST.bit.EOWI != 0x1);       // Should wait here until the entire window is received

if(!ErrCount)
          TEST_STATUS = TEST_PASS;

RdValue = 0xDEF1;                                             // To check if the program is stopped at ESTOP0

asm(" ESTOP0");

}while(1);


}


// local_UPPA_ISR - UPPA Interrupt Service Routine (ISR)


interrupt void local_UPPA_ISR(void)
{


PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;

if (UppRegs.GINTFLG.all != 0x0)

{

if(UppRegs.ENINTST.bit.EOWI == 0x1)                //Check for EOW Interrupt flag
{

eow_int_cnt++;
CopyRxMsgRam = 1;

UppRegs.ENINTST.all = uPP_INT_EOWI;           //Clear the Status for EOW Interrupt

if (UppRegs.ENINTST.bit.EOWI != 0)
{

ErrCount++;
asm (" ESTOP0");

}

}

}


if(CopyRxMsgRam == 1)
{
          *(Uint32 *)DstAddr = *(Uint32 *)(uPP_RX_MSGRAM_ADDR);
          DstAddr = DstAddr + 2;
          CopyRxMsgRam = 0;
}

UppRegs.CHIDESC0 = 0x7000;

UppRegs.CHIDESC1.bit.LCNT = LINE_CNT;

UppRegs.CHIDESC1.bit.BCNT = BYTE_CNT;

UppRegs.CHIDESC2.all = 0;

// Clear Global Interrupt.


RdValue = UppRegs.ENINTST.all;

UppRegs.GINTCLR.bit.GINTCLR = 1;

if (UppRegs.GINTFLG.all != 0x0)
{
             ErrCount++;
             asm (" ESTOP0");

          }


RdValue = 2;

}

// End of file

  • Hi Chandan,

    One quick observation in this code is that you have while loop to check the EOW interrupt status in main code which creates a race condition with interrupt. While loop is not a single atomic instruction so what if  interrupt happens before the check is done. In that case interrupt will get executed and ISR will clear the status and now when CPU returns to check the while loop, it'll get stuck there. So instead of checking the interrupt status, wait for some global flag (variable) which gets set at the end of ISR.

    Regards,

    Vivek Singh

  • Hi  

    Thank you so much for your quick response. I am a bit new to microcontroller world and didn't know about "race condition". Now all the observations I had make perfect sense to me. I changed the while condition from

    while (UppRegs.ENINTST.bit.EOWI != 0x1);

    to

    while(RdValue != 2);

    and everything works perfectly fine now.

    Thank you again.

    Regards
    Chandan