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.

SCI FIFO TX interrupt flag is set automatically when interrupt is enabled

Other Parts Discussed in Thread: TMS320F28069

Hi,

My configuration is below:


SciaRegs.SCICTL1.bit.SWRESET = 0;

SciaRegs.SCIFFTX.bit.SCIRST = 0;
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 0;

SciaRegs.SCICCR.bit.STOPBITS = 0;
SciaRegs.SCICCR.bit.PARITYENA = 0;
SciaRegs.SCICCR.bit.LOOPBKENA = 0;
SciaRegs.SCICCR.bit.ADDRIDLE_MODE = 0;
SciaRegs.SCICCR.bit.SCICHAR = 0x7;

SciaRegs.SCICTL1.bit.RXERRINTENA = 0;
SciaRegs.SCICTL1.bit.TXWAKE = 0;
SciaRegs.SCICTL1.bit.SLEEP = 0;
SciaRegs.SCICTL1.bit.TXENA = 1;
SciaRegs.SCICTL1.bit.RXENA = 1;

SciaRegs.SCICTL2.bit.TXINTENA = 1;
SciaRegs.SCICTL2.bit.RXBKINTENA = 0;

SciaRegs.SCIFFTX.bit.SCIFFENA = 1;
SciaRegs.SCIFFTX.bit.TXFFIENA = 0;
SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1;
SciaRegs.SCIFFTX.bit.TXFFIL = 0;

SciaRegs.SCIFFCT.all = 0x0;

SciaRegs.SCIHBAUD = 0x00;
SciaRegs.SCILBAUD = 11; // 937,500 bits/s

SciaRegs.SCICTL1.bit.SWRESET = 1;
SciaRegs.SCIFFTX.bit.SCIRST = 1;
SciaRegs.SCIFFTX.bit.TXFIFOXRESET = 1;

What I want to do is to send 8 bytes of information every 20ms, for which I use a timer. I do this in the following steps:

1. Enter timer interrupt.
2. Add 4 bytes of data in TX FIFO.
3. Enable TX FIFO interrupt.
4. Acknowledge timer interrupt and exit.
5. Enter TX FIFO interrupt when the FIFO is empty.
6. Add the last 4 bytes of data in TX FIFO.
7. Disable TX FIFO interrupt.
8. Acknowledge TX FIFO interrupt and exit.
9. Repeat.

However, for some reason the PIE flag for TX FIFO interrupt is set as soon as I enable the interrupt. Which means that the program exits the timer interrupt and IMMEDIATELY enters the TX FIFO interrupt, even though the TX FIFO is not yet empty. This causes me to lose about half of all my messages. Any idea how to fix this? I've tried clearing the TX FIFO interrupt before exiting the timer interrupt etc but it doesn't help.

Regards
Christian

  • Hi Christian,

    What device are you using?

    Can you confirm that the FIFO is not empty when first entering the TXISR by checking SCIFFTX.bit.TXFFST?


    Here is a related thread: e2e.ti.com/.../413943

    sal

  • Hi,

    I'm using the TMS320F28069.

    I've checked SCIFFTX.bit.TXFFST both when I enter the timer interrupt, when I exit the timer interrupt, and when I enter the TX FIFO interrupt. The result is:

    1. When entering the timer interrupt, SCIFFTX.bit.TXFFST == 0.
    2. When exiting the timer interrupt, SCIFFTX.bit.TXFFST == 3.
    3. When entering the TX FIFO interrupt, SCIFFTX.bit.TXFFST == 3.

    It's also worth noting that the interrupt flag in the PIE is set immediately when SCIFFTX.bit.TXFFIENA = 1 is executed. The flag does not clear even if I do a PIEACK of group 9 before exiting the timer interrupt either.

    I skimmed through the link you provided but it doesn't seem like the two of us have the same problem. My messages aren't sent twice.The problem for me is rather:

    1. I fill the FIFO buffer in the timer interrupt.
    2. Enable the TX FIFO interrupt (with the level set to zero - when the FIFO is empty).
    3. Despite point 2, the interrupt occurs before the FIFO is empty.
    4. This causes 3 of the first 4 bytes to get discarded because new information is put into the FIFO buffer in the TX FIFO interrupt, before it has a chance to empty.

    So, instead of 8 bytes being sent I get 5 bytes being sent every 20ms.

    Regards
    Christian

  • Just thought I'd provide my timer and TX FIFO interrupts.

    The timer interrupt:

    interrupt void TxTimer_Isr()
    {
    SciaRegs.SCITXBUF = FirstMessage;
    SciaRegs.SCITXBUF = SecondMessage;

    SciaRegs.SCITXBUF = ThirdMessage;
    SciaRegs.SCITXBUF = FourthMessage;

    SciaRegs.SCIFFTX.bit.TXFFIENA = 1; // enable FIFO interrupts

    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // Try and clear the TX FIFO interrupt that gets flagged...

    PieCtrlRegs.PIEACK.all |= PIEACK_GROUP9; // Try and clear the TX FIFO interrupt that gets flagged...

    PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
    }

    The TX FIFO interrupt:

    interrupt void SciTxFifo_Isr()
    {
    SciaRegs.SCITXBUF = FifthMessage;
    SciaRegs.SCITXBUF = SixthMessage;
    SciaRegs.SCITXBUF = SeventhMessage;
    SciaRegs.SCITXBUF = EighthMessage;

    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // clear TX FIFO interrupts
    SciaRegs.SCIFFTX.bit.TXFFIENA = 0; // disable FIFO interrupts

    PieCtrlRegs.PIEACK.all |= PIEACK_GROUP9;
    }

    Regards
    Christian

  • Hello,
    Can you try with SciaRegs.SCIFFTX.bit.TXFFIL = 4; ?

    Best regards,
    Maria
  • Also, maybe this thread is useful e2e.ti.com/.../316603

    Best regards,
    Maria
  • Hi,

    I've tried setting SciaRegs.SCIFFTX.bit.TXFFIL = 4 before. I read the thread you linked to earlier and tried it. I get the exact same result however.

    Isn't the TX FIFO interrupt supposed to occur when TXFFST <= TXFFIL though? I can sort of understand the result I'm getting when TXFFIL == 4, but it eludes me why the interrupt flag is set when TXFFIL == 0.

    Something interesting to note btw is that it seems to be impossible to clear the interrupt either in the PIE or by setting SCIFFTX.bit.TXFFINTCLR = 1. They won't clear until I enter the TX FIFO interrupt for some reason.

    Regards,

    Christian

  • Hi Christian,

    Please try this for your interrupts. Let me know if this works.

    interrupt void TxTimer_Isr()
    {
    SciaRegs.SCITXBUF = FirstMessage;
    SciaRegs.SCITXBUF = SecondMessage;

    SciaRegs.SCITXBUF = ThirdMessage;
    SciaRegs.SCITXBUF = FourthMessage;

    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // Try and clear the TX FIFO interrupt that gets flagged...

    SciaRegs.SCIFFTX.bit.TXFFIENA = 1; // enable FIFO interrupts

    PieCtrlRegs.PIEACK.all |= PIEACK_GROUP1;
    }

    The TX FIFO interrupt:

    interrupt void SciTxFifo_Isr()
    {
    SciaRegs.SCITXBUF = FifthMessage;
    SciaRegs.SCITXBUF = SixthMessage;
    SciaRegs.SCITXBUF = SeventhMessage;
    SciaRegs.SCITXBUF = EighthMessage;

    SciaRegs.SCIFFTX.bit.TXFFIENA = 0; // disable FIFO interrupts
    SciaRegs.SCIFFTX.bit.TXFFINTCLR = 1; // clear TX FIFO interrupts

    PieCtrlRegs.PIEACK.all |= PIEACK_GROUP9;
    }

    sal
  • Works beautifully!

    I don't understand quite why this works though. Is it because the interrupt flag in the TXFFXT registers are cleared before the PIE flag is set? Or what exactly happens when I reverse the order of int enable and int clear?

    Regards,
    Christian

  • Hi Christian,

    Generally, when enabling an interrupt it is best practice to 1) clear the flag then 2) enable the interrupt. When disabling the interrupt it is best practice to 1) disable the interrupt then 2) clear the flag.

    Both of these help to prevent unnecessary or unintended interrupts from occurring when the interrupt gets re-enabled.

    Best Regards,
    sal
  • Hi,

    Thanks for the advice. I will be sure to keep it in mind in the future. And thanks for the help!

    Regards,
    Christian