# Microblaze AXI SPI interrupt issue with FreeRtos

**URL:** <https://forums.freertos.org/t/microblaze-axi-spi-interrupt-issue-with-freertos/21071>\
**Category:** Xilinx\
**Created:** [July 31, 2024, 8:06am UTC](https://forums.freertos.org/t/microblaze-axi-spi-interrupt-issue-with-freertos/21071 "2024-07-31T08:06:40Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dabrzn](https://avatars.discourse-cdn.com/v4/letter/d/5f9b8f/32.png) [@Dabrzn](https://forums.freertos.org/u/Dabrzn)\
**Post date:** [July 31, 2024, 8:06am UTC](https://forums.freertos.org/t/microblaze-axi-spi-interrupt-issue-with-freertos/21071/1 "2024-07-31T08:06:40Z")

</div>

Hello!

I try to implement an SPI-interface with FreeRtos on a Microblaze system (with Wiznet W6100). The interrupt handler gets triggered only once and then the code stops at “while (Spi\_Wiznet\_TransferInProgress);”  
I have used almost the same code without rtos and it is working. That means the hardware is ok. I have used for the non-FreeRtos application the AXI-SPI with FIFO. For the FreeRtos application i deactivated the FIFO after some tries as I have changed the interrupt-configuration to the port-functions from FreeRtos and activated the XSP\_INTR\_RX\_FULL\_MASK - interrupt.  
The SPI interface runs with 25 MHz and the Microblaze with 100 MHz.

I post only the (in my opinion) relevant part of my code. If needed, I can upload the whole main.c.

I use the following code for configuration of the SPI-interface:

```auto
	XSpi_Config *ConfigPtr_Spi_Wiznet;
	ConfigPtr_Spi_Wiznet=XSpi_LookupConfig(DeviceID_SPI_Wiznet);
    XSpi_CfgInitialize(&Spi_Wiznet, ConfigPtr_Spi_Wiznet, ConfigPtr_Spi_Wiznet->BaseAddress);
    //	SetupInterruptSystem(); //not used, for FreeRtos I have to use the ported functions
    //
    //	XSpi_SetStatusHandler(&Spi_Wiznet, &Spi_Wiznet, (XSpi_StatusHandler) Spi_Wiznet_Handler); //not used, for FreeRtos I have to use the ported functions
    XSpi_SetOptions(&Spi_Wiznet, XSP_MASTER_OPTION );// | XSP_MANUAL_SSELECT_OPTION );
	XSpi_SetSlaveSelect(&Spi_Wiznet, cs_wiznet);
    XSpi_Start(&Spi_Wiznet);

```

code for interrupt configuration - at the beginning of a task (not in the while loop)

```auto
static void tf_init_wiznet(void* parameters){

    const TickType_t x10second = pdMS_TO_TICKS( DELAY_10_SECONDS );
    
	xil_printf( "Enable Interrupts\r\n" );
	int xStatus;
	xStatus=xPortInstallInterruptHandler(XPAR_CONTROLLER_MICROBLAZE_0_AXI_INTC_WIZNET_AXI_SPI_WIZNET_IP2INTC_IRPT_INTR, (XInterruptHandler) Spi_Wiznet_Handler, &Spi_Wiznet);
	vPortEnableInterrupt(XPAR_CONTROLLER_MICROBLAZE_0_AXI_INTC_WIZNET_AXI_SPI_WIZNET_IP2INTC_IRPT_INTR);
	XSpi_IntrEnable(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK); //use without FIFO!! 
	XSpi_IntrGlobalEnable(&Spi_Wiznet);
	xil_printf( "Interrupt enabled\r\n" );
    xil_printf( "Start Init W6100\r\n" );

```

functions for SPI transmit/receive

```auto
uint8_t my_wizchip_read(void){
	uint8_t rx_data[1]={0};
	uint8_t tx_data[1]={0xFF};
	Spi_Wiznet_TransferInProgress=TRUE;
	XSpi_Transfer(&Spi_Wiznet, tx_data, rx_data, 1);
	while (Spi_Wiznet_TransferInProgress);
	return rx_data[0];
}

void my_wizchip_write(uint8_t wb){

	uint8_t rx_data[1]={0};
	uint8_t tx_data[1]={wb};
	Spi_Wiznet_TransferInProgress=TRUE;
	XSpi_Transfer(&Spi_Wiznet, tx_data, rx_data, 1);
	while (Spi_Wiznet_TransferInProgress);
	return;
}

```

function for SPI Interrupt handler

```auto
void Spi_Wiznet_Handler(void *CallBackRef)
{
	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	xil_printf( "SPI Int started\r\n" );
	portENTER_CRITICAL(); //tried with and without portEnter- and portEXIT_CRITICAL
	Spi_Wiznet_TransferInProgress=FALSE;
	/* //code that i have used in the non-RTOS application with (void *CallBackRef, u32 StatusEvent, u32 ByteCount)
	if (StatusEvent == 0x4) //XST_SPI_TRANSFER_DONE)
		Spi_Wiznet_TransferInProgress=FALSE;
	else
		Spi_Wiznet_ErrorCount++;
    */
	XSpi_IntrClear(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK);
	XSpi_IntrEnable(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK);
	xil_printf( "SPI Int endedr\n");

	portEXIT_CRITICAL(); //tried with and without portEnter- and portEXIT_CRITICAL

	portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

}

```

My questions:  
Has anybody an idea why my interrupt doesn’t get triggered a second time?  
Has anybody a working example with AXI-SPI interrupt and FreeRtos?  
I made some tests with GPIO-interrupts…they worked well.

best regards  
Dabrzn

---

<div class="post-metadata">

**Author:** ![karahulx](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/karahulx/32/4893_2.png) [@karahulx](https://forums.freertos.org/u/karahulx)\
**Post date:** [July 31, 2024, 11:25am UTC](https://forums.freertos.org/t/microblaze-axi-spi-interrupt-issue-with-freertos/21071/2 "2024-07-31T11:25:31Z")

</div>

You can take a look at how to install the handlers on the [page that describes how to use FreeRTOS on Cortex-A processors](http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html)?Also, the [Zynq demo in the FreeRTOS download](http://www.freertos.org/RTOS-Xilinx-Zynq.html) and the [FreeRTOS+TCP](https://support.xilinx.com/s/) examples can be used as a reference.

This [link](https://support.xilinx.com/s/question/0D52E00006hpMwCSAU/axi-interrupt-controller-under-freertos?language=en_US) provides a reference on AXI interrupt on FreeRTOS using a Xilinx board.  
Please see if these links are helpful.  
Thanks.
