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.
I 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:
- 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?
- 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) */