Skip to content

Instantly share code, notes, and snippets.

@matthijsbos
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthijsbos/49600e747182216ea355 to your computer and use it in GitHub Desktop.
Save matthijsbos/49600e747182216ea355 to your computer and use it in GitHub Desktop.
Microblaze MCS I/O Module Uart Rx Interrupt Example and bug in xiomodule_uart_intr.c
#include <stdio.h>
#include "xiomodule.h"
#include "xiomodule_l.h"
#include "xparameters.h"
void recv_handler(void *CallBackRef, unsigned int ByteCount);
int main()
{
XIOModule io;
microblaze_enable_interrupts();
microblaze_register_handler(XIOModule_DeviceInterruptHandler, XPAR_IOMODULE_0_DEVICE_ID);
XIOModule_Initialize(&io, XPAR_IOMODULE_0_DEVICE_ID);
XIOModule_SetRecvHandler(&io, recv_handler, &io);
XIOModule_Uart_EnableInterrupt(&io);
XIOModule_Connect(&io, XIN_IOMODULE_UART_RX_INTERRUPT_INTR, (XInterruptHandler)XIOModule_Uart_InterruptHandler, &io);
XIOModule_Start(&io);
while (1);
}
void recv_handler(void *CallBackRef, unsigned int ByteCount) {
xil_printf("uart interrupt");
}
...
/**
*
* This function is the interrupt handler for the UART.
* It must be connected to an interrupt system by the user such that it is
* called when an interrupt for any UART lite occurs. This function
* does not save or restore the processor context such that the user must
* ensure this occurs.
*
* @param InstancePtr contains a pointer to the instance of the IOModule
* that the interrupt is for.
*
* @return None.
*
* @note None.
*
******************************************************************************/
void XIOModule_Uart_InterruptHandler(XIOModule *InstancePtr)
{
u32 IsrStatus;
Xil_AssertVoid(InstancePtr != NULL);
/*
* Read the status register to determine which, could be both,
* interrupt is active
*/
/*
* BUG:
*
* In the original code, the I/O Module's Interrupt Pedning Register 0x00000034 was
* read instead of the UART Status Register, causing the handlers never to be called.
*
* IsrStatus = XIOModule_ReadReg(InstancePtr->BaseAddress,
* XIN_IPR_OFFSET);
* The followoing works:
*/
IsrStatus = XIOModule_ReadReg(InstancePtr->BaseAddress,
XUL_STATUS_REG_OFFSET);
if ((IsrStatus & XUL_SR_RX_FIFO_VALID_DATA) != 0) {
ReceiveDataHandler(InstancePtr);
}
if (((IsrStatus & XUL_SR_TX_FIFO_FULL) == XUL_SR_TX_FIFO_FULL) &&
(InstancePtr->SendBuffer.RequestedBytes > 0)) {
SendDataHandler(InstancePtr);
}
}
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment