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.

TMS320C5515: How should I interpret a UART interrupt with IPEND 1 and INTID 0?

Part Number: TMS320C5515

According to the DSP UART User's Guide, if ETBEI is enabled in the UART IER, then I should get an interrupt when the THR (transmit register) is empty. But I'd like to know whether this applies when first enabling the interrupt. While I was trying to investigate this, I ended up with my DSP in a strange state.

Basically, what I'm seeing is that as soon as I enable the ETBEI, the UART interrupt flag in the CPU IFR0 (NOT in the UART IIR!) is set. BUT the corresponding registers in the UART module show:

  • IPEND == 1 (ie. no interrupt pending)
  • INTID == 0 (documented as "reserved")

So naturally, my UART ISR is entered, but since the INTID isn't "1", the ISR doesn't do anything with it.

Note that I'm using the UART in FIFO mode with hardware flow control in both directions. I'm watching my RTS/CTS lines on an oscilloscope and they are definitely doing the right thing. I can only trigger this problem when profiling, which suggests that it's related to the slower speed when running a profiler. However, with hardware flow control active it should only slow things down, not actually alter how the interrupts are triggered.

could write my ISR to handle this case, but it seems like a bad idea, since it's not a state of the CPU defined by the documentation. So I have two questions:

  1. What does it mean for there to be a UART interrupt via CPU IFR0, but no IPEND/IIR in the UART registers? Should I handle this situation in my ISR?
  2. Can I expect to get a THREINT interrupt if (a) I clear the transmit FIFO and (b) enable the ETBEI interrupt?

Here's a quick sketch of how I'm configuring the UART and starting the transmit. It's not all of the config code (eg. I left out the CPU config etc), but let me know if there's something UART related that's missing:

// Enable UART. Assume it's configured for 8-N-1 at 128k baud.
CSL_FINST(CSL_SYSCTRL_REGS->PCGCR1, SYS_PCGCR1_UARTCG, ACTIVE);
CSL_FINST(CSL_UART_REGS->PWREMU_MGMT, UART_PWREMU_MGMT_UTRST, RESET);
CSL_FINST(CSL_UART_REGS->PWREMU_MGMT, UART_PWREMU_MGMT_UTRST, ENABLE);

// Configure FIFO operation.
CSL_FINST(CSL_UART_REGS->FCR, UART_FCR_RXFIFTL, CHAR8);
CSL_FINST(CSL_UART_REGS->FCR, UART_FCR_TXCLR, CLR);
CSL_FINST(CSL_UART_REGS->FCR, UART_FCR_RXCLR, CLR);
CSL_FINST(CSL_UART_REGS->FCR, UART_FCR_FIFOEN, ENABLE);
CSL_FINST(CSL_UART_REGS->MCR, UART_MCR_AFE, ENABLE);
CSL_FINST(CSL_UART_REGS->MCR, UART_MCR_RTS, CTSRTSEN);

// Enable UART interrupt in CPU.
CSL_FINST(CSL_CPU_REGS->IER0, CPU_IER0_UART, ENABLE);

// Start transmit: clear FIFOs, enable transmit interrupt.
// Data is written from global buffer in ISR.
CSL_FINST(CSL_UART_REGS->FCR, UART_FCR_TXCLR, CLR);
CSL_FINST(CSL_UART_REGS->IER, UART_IER_ETBEI, ENABLE);

/* ***QUESTION*** - Should there be a THREINT interrupt here,
 * immediately after enabling ETBEI?
 *
 * ***NOTE*** - in debugger, as soon as I step past this line, I see:
 *
 * CPU IFR0 UART is 1
 * IPEND is 1 (none)
 * INTID is 0 (reserved)
 */

  • I should point out that it's not just profiling that affects it, if I break a non-profiling run a few instructions before enabling the interrupt and step through, I see the same thing.

    I've also tried writing a single character to the transmit register before enabling the interrupt, but see the same thing (CPU IFR0 UART interrupt, IPEND = 1).
  • Hello,
    about your question "Should there be a THREINT interrupt here, immediately after enabling ETBEI?" Yes, if your FIFO is empty you should get into this interrupt. There can be another thing that prevents you to identify the interrupt correctly. It was found that the IIR register is impacted by emulation reads, so if you had a memory window open in CCS in the UART MMR space, a refresh/breakpoint could cause an emulation read, clearing the IIR register.
    For the Interrupt type: Transmit Holding Register Empty, event that clears the interrupt is "a character written to the THR" as well as this interrupt condition can also get cleared on a read issued to the IIR register.

    BR
    Michail
  • Michail Georgiev said:
    There can be another thing that prevents you to identify the interrupt correctly. It was found that the IIR register is impacted by emulation reads, so if you had a memory window open in CCS in the UART MMR space, a refresh/breakpoint could cause an emulation read, clearing the IIR register.

    Good to know, thanks. Just some more detailed questions from this:

    • If the "registers" window is open, even if the UART/CPU sections aren't unfolded - will this still trigger the IIR clearing? Should I close that pane altogether to avoid it?
    • Do you know if profiling will also trigger the emulation-related IIR clear?

  • Hello,

    1. Since IIR is a special peripheral register (as many others) it has different behaviour according to regular CPU regs. At some point when using CCS debugging features altering of this reg is possible, though I can not say the exact CCS actions used during debug. To be sure what is contained in such HW registers you can simply copy their content in a safe regular memory location and after interrupt servicing ends to check/print/output in some way these contents to check what really happened.

    2. Profiling should not alter any registers whether they are peripheral related or not.

    BR
    Michail
  • I took your advice and recorded the INTID and IPEND values (just on the stack in the ISR), and set a breakpoint based on the stack values (not the registers themselves) and it looks like they're fine if I'm not inspecting them via the debugger.

    However, I am still seeing issues when profiling. After a certain point, either the THRE interrupt doesn't fire or the CPU does not wake up from IDLE after the ISR finishes (I can't tell which). This doesn't happen when not profiling. But that is a separate topic I suppose.

  • Hello,
    you can open another thread about this issue if you wish. Note that profiling uses additional code added to your program and depending on where it is placed there is a chance for malfunction in main code.
    BR
    Michail