Simulation of the UART shows that the transmit interrupt will be generated, as expected, even with a single byte transfer (the transmit FIFO becoming empty).
Here's some example code for you to get the idea. As you can see, I'm using a Xilinx microblaze system. There are three ports - A, B, and C. A is a uartlite hyperterm console for outputting printf's. I can provide this code as an attachment if desired. Mostly it's just to show how it's being used to produce the problem...
#include "main.h" #include "xio.h"
XUartNs550 UART_Port_C_16550_struct; XUartNs550 UART_Port_B_16550_struct; XUartNs550Format format;
XIntc InterruptController;
/ Variable Creation / Xuint8 uart_buffer16; Xuint16 options;
void PortC_Handler (void CallBackRef, Xuint32 Event, unsigned int EventData) { Xuint8 Errors; XUartNs550 UartNs550Ptr = (XUartNs550 )CallBackRef; char dummy; int asdf; //xil_printf("Entered Port C Interrupt Handler\r\n"); if (Event == XUN_EVENT_SENT_DATA) { / placeholder to allow breaking to occur here / asdf = 42; xil_printf("Entered Port C Send Interrupt Handler\r\n"); } else if (Event == XUN_EVENT_RECV_DATA) { / don't care what happens to the Rx'd byte / XUartNs550_Recv (UartNs550Ptr, &dummy, 1); xil_printf("Entered Port C RECV Interrupt Handler\r\n"); } else { / placeholder to allow breaking to occur here */ asdf = 999; xil_printf("Entered Port C Some other Interrupt Handler\r\n"); } }
void PortB_Handler (void CallBackRef, Xuint32 Event, unsigned int EventData) { Xuint8 Errors; XUartNs550 UartNs550Ptr = (XUartNs550 )CallBackRef; char dummy; int asdf; //xil_printf("Entered Port B Interrupt Handler\r\n"); if (Event == XUN_EVENT_SENT_DATA) { / placeholder to allow breaking to occur here / asdf = 42; xil_printf("Entered Port B Send Interrupt Handler\r\n"); } else if (Event == XUN_EVENT_RECV_DATA) { / don't care what happens to the Rx'd byte / XUartNs550_Recv (UartNs550Ptr, &dummy, 1); xil_printf("Entered Port B RECV Interrupt Handler\r\n"); } else { / placeholder to allow breaking to occur here */ asdf = 999; xil_printf("Entered Port B Some other Interrupt Handler\r\n"); } }
int main() { Xuint16 Options; XStatus Status;
microblaze_enable_interrupts();
//Setup Interrupt System:
Status = XIntc_Initialize(&InterruptController, XPAR_INTERRUPT_CONTROLLER_DEVICE_ID);
/* Start the Interrupt Controller with interrupts enabled. */
Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
/* Initialize */
XUartNs550_Initialize(&UART_Port_C_16550_struct, XPAR_PORTC_WISHBONE_BRIDGE_DEVICE_ID);
XUartNs550_Initialize(&UART_Port_B_16550_struct, XPAR_PORTB_WISHBONE_BRIDGE_DEVICE_ID);
Options = XUN_OPTION_DATA_INTR | XUN_OPTION_FIFOS_ENABLE |
XUN_OPTION_RESET_TX_FIFO | XUN_OPTION_RESET_RX_FIFO;
XUartNs550_SetOptions(&UART_Port_C_16550_struct, Options);
XUartNs550_SetOptions(&UART_Port_B_16550_struct, Options);
//Set defaults for UART Port B, C
format.BaudRate = BAUD_RATE;
format.DataBits = XUN_FORMAT_8_BITS;
format.Parity = XUN_FORMAT_NO_PARITY;
format.StopBits = XUN_FORMAT_1_STOP_BIT;
XUartNs550_SetDataFormat(&UART_Port_C_16550_struct, &format);
XUartNs550_SetDataFormat(&UART_Port_B_16550_struct, &format);
//Connect device driver handlers:
//PortC
Status = XIntc_Connect(&InterruptController, SERC_UART_INTERRUPT_ID,
(XInterruptHandler)XUartNs550_InterruptHandler,
(void *)&UART_Port_C_16550_struct);
XIntc_Enable(&InterruptController, SERC_UART_INTERRUPT_ID); //PortC
//PortB
Status = XIntc_Connect(&InterruptController, SERB_UART_INTERRUPT_ID,
(XInterruptHandler)XUartNs550_InterruptHandler,
(void *)&UART_Port_B_16550_struct);
XIntc_Enable(&InterruptController, SERB_UART_INTERRUPT_ID); //PortB
/* Setup the interrupt handlers for the devices */
XUartNs550_SetHandler(&UART_Port_C_16550_struct, PortC_Handler, &UART_Port_C_16550_struct);
XUartNs550_SetHandler(&UART_Port_B_16550_struct, PortB_Handler, &UART_Port_B_16550_struct);
unsigned int i;
xil_printf("Starting Test\r\n");
for (i = 0; i < 100000000; i++) {}
char *test2String = "!!";
char *test1String = "!";
/* send exactly 2 bytes, wait, then send 1 byte.
* use GDB to confirm that the send interrupt is generated for the former
* send, but not for the latter */
XUartNs550_Send (&UART_Port_C_16550_struct, test2String, 2);
XUartNs550_Send (&UART_Port_B_16550_struct, test2String, 2);
for (i = 0; i < 100000000; i++) {}
XUartNs550_Send (&UART_Port_C_16550_struct, test1String, 1);
XUartNs550_Send (&UART_Port_B_16550_struct, test1String, 1);
while (1) {}
//end printing Main Menu while loop
}//end main()
/ End of File /
Just to clear this one up on my end also -- we were able to figure it out -- the directory was not using the most up-to-date UART release. We were using the old (circa august) release of the UART.
I apologize for the mix-up...
And I forgot to add -- Thanks for the great core!
And on top of that -- thank you for the rapid response! Regards,
-Ben