Hello,
I am working on a communication protocol with the LM4F112C4QC. I am using raw serial (no FIFO, no uDMA). This application uses the SIR feature to condition the signals for use with an IRDA transceiver. The issue I am having is that I cannot get the interrupt to fire consistently when sending data.
The UART & Interrupt are being configured as shown below:
/* *********************************************** */
/* ******* UART Initialization function ********** */
/* *********************************************** */
void common_uartdr_portInit_void(_uart_ports port)
{
MAP_SysCtlPeripheralEnable(uart[port].peripheral); /*Initialize the UART peripheral */
MAP_GPIOPinConfigure(uart[port].RX); /*Set muxed RX pin to use UART */
MAP_GPIOPinConfigure(uart[port].TX); /*Set muxed TX pin to use UART */
MAP_GPIOPinTypeUART(uart[port].RXPort,uart[port].RXPin); /*Configure pin for UART RX */
MAP_GPIOPinTypeUART(uart[port].TXPort,uart[port].TXPin); /*Configure pin for UART TX */
MAP_UARTClockSourceSet(uart[port].baseAddress, UART_CLOCK_PIOSC); /*Set PIOSC as the UART clock source */
/*(Needed for using UART interrupts to */
/* wake from deep sleep mode since the */ /* system clock will be disabled*/
UARTEnableSIR( uart[port].baseAddress, false); /* enable the IRDA Mod/DeMod */
MAP_UARTConfigSetExpClk(uart[port].baseAddress, /*Configure the UART baud to the */
16000000, /* specified rate, set for 8 bits, */
uart[port].baud, /* no parity, no stop bit */
(UART_CONFIG_WLEN_8 |
UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE ));
MAP_UARTFIFOLevelSet( uart[port].baseAddress, /*Set interrupt to trigger when just */
UART_FIFO_TX1_8, /* one byte is sent/received */
UART_FIFO_RX1_8);
MAP_UARTTxIntModeSet( uart[port].baseAddress, /*Set interrupt to trigger on */
UART_TXINT_MODE_EOT); /* End-Of-Transmit */
MAP_UARTIntClear(uart[port].baseAddress, /*Make sure UART interrupts are clear */
(UART_INT_RX | UART_INT_RT |
UART_INT_TX | UART_INT_OE |
UART_INT_BE | UART_INT_PE |
UART_INT_FE));
MAP_UARTEnable(uart[port].baseAddress); /*Enable the UART */
UARTFIFODisable(uart[port].baseAddress); /*Disable the UART */
MAP_uDMAChannelAttributeDisable(uart[port].udmaTXChannel, UART_DMA_TX); /* disable uDMA TX Channel */
MAP_uDMAChannelAttributeDisable(uart[port].udmaRXChannel, UART_DMA_RX); /* disable uDMA TX Channel */
UARTIntRegister(uart[port].baseAddress, common_uartdr_uart1Int_uchar); /* Int Func common_uartdr_uart1Int_uchar*/
MAP_UARTIntEnable(uart[port].baseAddress, UART_INT_TX | UART_INT_RX);
}
The Interrupt Function common_uartdr_uart1Int_uchar() is defined as shown below:
/* *********************************************** */
/* ******* UART Interrupt function *************** */
/* *********************************************** */
void common_uartdr_uart1Int_uchar()
{
unsigned long ulIntStatus;
uchar ucMe, ucRxd;
ucMe = 0;
ulIntStatus = UARTIntStatus(uart[1].baseAddress, true); /* obtain UART Interrupt Status */
UARTIntClear(uart[1].baseAddress, ulIntStatus); /* and RESET set UART Int status */
if (ulIntStatus == UART_INT_RX) /* if a Receive Int has occurred */
{
ucMe |= 0x04;
while (UARTCharsAvail(uart[1].baseAddress)) /* loop while there are chars */
{
ucRxd = UARTCharGetNonBlocking(uart[1].baseAddress); /* read and discard for now */
}
ucCharsToSend = 2;
UARTCharPut(uart[1].baseAddress, ucMe);
}
if (ulIntStatus == UART_INT_TX) /* if a Transmit Int has occurred */
{
ucMe |= 0x02;
if (ucCharsToSend > 0) /* send "X" more characters */
{
ucCharsToSend--;
UARTCharPut(uart[1].baseAddress, ucMe);
}
}
}
I attempt to send a series of characters, initiated by calling this function every 1 second:
/* *********************************************** */
/* ******* Send first byte function ************** */
/* *********************************************** */
void common_uartdr_UARTcharPut(uchar ucChar)
{
UARTCharPut(uart[1].baseAddress, ucChar); /* send first byte to the IR port */
}
The results I am getting do not seem to make sense. For some reason, when I start the program, the Receiver Interrupt fires. When this occurs, the
transmit intterupt will continually fire, sending bytes until the "ucChartToSend" indicates to stop (or indefinately if I pull this limiting variable out).
This is the operation I would expect.
In my application, my intent is to call function common_uartdr_UARTcharPut() to send out the first byte in a packet, and then let the Tx Interrupts
fire (in response to the Tx Buffer being empty) to send out the rest of the packet. However, when I call this function, it does send out its byte, but the TxInterrupts NEVER fire to send the rest of the packet.
I tried removing the ucCharsToSend limit on the TX Interrupt, so that it sends bytes indefinately (that is working). But if I then call
the common_uartdr_UARTcharPut() function, that function will send its one byte, and then the Tx Interrupts which had been firing will stop firing and sending the successive bytes (as it had been prior to the function call).
I have verified that the EOT, TXE, and RXE bit are set in the UART1CTL register in all cases. RXIM and TXIM are set in the UART1IM register.
Also, TXRIS is being set after the byte is sent in the common_uartdr_UARTcharPut() function. After a call to common_uartdr_UARTcharPut(), it will
stay set indefinately, since the Tx Int never fires. I've even tried clearing it manually between calls to common_uartdr_UARTcharPut, but that has no effect.
Also, besides the first firing of the RX Interrupt, I do not see that fire again either in response to an incoming byte (but I have not investigated that yet).
I have come to the point where I'm out of ideas regarding what to try next. Any thoughts you have would be greatly appreciated !!!