Hi, All!
I'm implementing the UART driver for TMS320C6424 DSP using IOM + class-driver model.
Driver code was developed using DDK recommendations.
IOM model looks to be working (I use SIO/DIO class-driver for now) - at least all the IOM_Fxns calls are invoked when necessary.
Nevertheless I've got an issue which I cannot resolve using TI's documentation and samples.
Due to documentation if UART's Tx interrupts are enabled, an interrupt should be generated once Tx FIFO or THR is empty (depending on mode used), and the corresponding interrupt ID bit in IIR should be unset only if anything is written to THR.
UART's interrupts are multiplexed to the single hardware interrupt, and the actual interrupt reason should be read from IIR register.
The issue is I have no interrupts, though Tx interrupts are enabled and Tx FIFO is empty.
More than that, sometimes I get interrupt with "interrupt source = None" due to IIR.
Below are the UART registers contents which I've got in my UART interrupt service routine:
regs 0x01C20000 CSL_UartRegsOvly
RBR 0x00000000 unsigned int
IER 0x00000002 unsigned int
IIR 0x000000C1 unsigned int
LCR 0x00000003 unsigned int
MCR 0x00000000 unsigned int
LSR 0x00000060 unsigned int
MSR 0x000000B0 unsigned int
SCR 0x00000000 unsigned int
DLL 0x0000002C unsigned int
DLH 0x00000000 unsigned int
PID1 0x00000103 unsigned int
PID2 0x00000004 unsigned int
PWREMU_MGMT 0x00006003 unsigned int
Here:
bit0 in IIR = 1, which means no pending interrupts (0xC0 bits - FIFO enabled).
bit5 and bit6 in LSR = 1, which means that both THR/FIFO and TSR are empty.
bit1 in IER = 1, which means that TX interrupts are enabled, and interrupt should be generated on empty TX.
My driver enables Tx interrupts (in IER) only when Tx data are ready.
Once data are available, I enable Tx interrupts, and fill THR.
I've tried filling THR with both a single character and a multiple (16 characters - FIFO size).
The result was the same in all cases: there're no Tx interrupts, though LSR shows that Tx is empty.
May anyone kindly advice what's the reason for such a behaviour?
// below is the interrupt service routine source-code.
// uart_handle_rx_/tx_/err_ routines aren't executed for now because of missing pending and reason bit :(
===============================================
static void
uart_isr_(Ptr * devp)
{
t_uart_iom_obj * uart = (t_uart_iom_obj *)devp;
uint32 iir_reg = uart->regs->IIR;
uint32 int_id = iir_reg >> CSL_UART_IIR_INTID_SHIFT;
isr_cnt++;
// process all incoming requests
// IPEND bit is 0 while there're interrupts pending
while (CSL_UART_IIR_IPEND_PEND == (iir_reg & CSL_UART_IIR_IPEND_MASK))
{
// check actual interrupt reason
if (int_id & CSL_UART_IIR_INTID_RLS) // receiver line error
uart_isr_handle_err_ (uart, int_id);
if (int_id & CSL_UART_IIR_INTID_THRE) // Tx Holding Register or Tx FIFO empty
uart_isr_handle_tx_ (uart);
// Rx data ready (either FIFO threshold achieved or RBR is filled)
// or receiver time-out
if (int_id & (CSL_UART_IIR_INTID_RDA | CSL_UART_IIR_INTID_CTI) )
uart_isr_handle_rx_ (uart);
// read register
iir_reg = uart->regs->IIR;
int_id = iir_reg >> CSL_UART_IIR_INTID_SHIFT;
}
}