cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Visitor
Visitor
113 Views
Registered: ‎04-13-2020

How to do parallel interruptions with one microblaze

Hi,

I'm using a spartan7 SP07 board and Vitis SDK to read data from 40 sensors  with SPI.

I'm trying to read from two axi_quad_spi simultaneosly to accelerate the acquisition process and number of sensors to use at the same time. So while in polled mode that happens sequentially and take a lot of time, i used the interrupted mode to do that in parralel.

The problem i'm facing is that only one interrupt is executed (the last one i configure).

So, I would like to know if it's possible to run two interuptions at the same time from the same interuptions controller (Axi_intr_controller). (see screenshot 3)

This is my hw setup, my code, and the simulation capture

Thank you,

screenshot 1 :

mb.PNG

screenshot 2 :

Capture.PNG

screenshot 3 :

Capture3.PNG

screenshot 4 : 

As you can see, the two controllers are reading data sequentially (in polled mode ) --> the goal is to make the two spi controllers read in parallel (with interuptions)

IMG_20200629_114713.jpg

 

 

 

 u32 Count=0;

	//xil_printf(" checkpoint 1 !! \r\n");
	XSpi_Config *ConfigPtr1;	/* Pointer to Configuration data */
	XSpi_Config *ConfigPtr2;	/* Pointer to Configuration data */

    ConfigPtr1 = XSpi_LookupConfig(SpiDeviceId_1);
	if (ConfigPtr1 == NULL) { return XST_DEVICE_NOT_FOUND; }
    ConfigPtr2 = XSpi_LookupConfig(SpiDeviceId_2);
	if (ConfigPtr2 == NULL) { return XST_DEVICE_NOT_FOUND; }

	//xil_printf(" checkpoint 2 !! \r\n");
	Status = XSpi_CfgInitialize(&SpiInstancePtr1, ConfigPtr1, ConfigPtr1->BaseAddress);
	if (Status != XST_SUCCESS) { return XST_FAILURE;}
	Status = XSpi_CfgInitialize(&SpiInstancePtr2, ConfigPtr2, ConfigPtr2->BaseAddress);
	if (Status != XST_SUCCESS) { return XST_FAILURE;}


	/*
	 * Connect the Spi device to the interrupt subsystem such that
	 * interrupts can occur. This function is application specific.
	 */
	Status = SpiSetupIntrSystem(&Intc2, &SpiInstancePtr2, SPI_IRPT_INTR_2);
	Status = SpiSetupIntrSystem(&Intc1, &SpiInstancePtr1, SPI_IRPT_INTR_1); // only the last interrupt initialised is working (it stops the first one)

	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	//xil_printf("4 \r\n");
	/*
	 * Setup the handler for the SPI that will be called from the interrupt
	 * context when an SPI status occurs, specify a pointer to the SPI
	 * driver instance as the callback reference so the handler is able to
	 * access the instance data.
	 */
	XSpi_SetStatusHandler(&SpiInstancePtr1, &SpiInstancePtr1,(XSpi_StatusHandler) SpiIntrHandler1);
	XSpi_SetStatusHandler(&SpiInstancePtr2, &SpiInstancePtr2,(XSpi_StatusHandler) SpiIntrHandler2);
	//xil_printf("5 \r\n");


   //xil_printf(" checkpoint 3 !! \r\n");
	Status = XSpi_SetOptions(&SpiInstancePtr1, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION);
	if (Status != XST_SUCCESS) { return XST_FAILURE; }
	Status = XSpi_SetOptions(&SpiInstancePtr2, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION);
	if (Status != XST_SUCCESS) { return XST_FAILURE; }

	//xil_printf(" checkpoint 4 !! \r\n");
	XSpi_Start(&SpiInstancePtr1);
	XSpi_Start(&SpiInstancePtr2);

	//xil_printf(" checkpoint 5 !! \r\n");
	XSpi_IntrGlobalDisable(&SpiInstancePtr1);
	XSpi_IntrGlobalDisable(&SpiInstancePtr2);

/**************************      Acquisition loop      *****************************/

	for(int j=0; j< SLAVES_NUM; j++)
    {
		   u32 StatusReg;
		TransferInProgress1 = TRUE;
		TransferInProgress2 = TRUE;

		        //u32 StatusEvent;

	XSpi_SetSlaveSelect(&SpiInstancePtr1, 0x01);  		
	XSpi_Transfer(&SpiInstancePtr1, WriteBuffer, ReadBuffer,BUFFER_SIZE);

         XSpi_SetSlaveSelect(&SpiInstancePtr2, 0x01);   		
	 XSpi_Transfer(&SpiInstancePtr2, WriteBuffer, ReadBuffer, BUFFER_SIZE);
			    	 	  
	while (TransferInProgress1 && TransferInProgress2 ){}; the code stops here because it takes in consideration only one interrupt (last one)
				
    }// End for

	   	SpiDisableIntrSystem(&Intc1, SPI_IRPT_INTR_1);
	   	SpiDisableIntrSystem(&Intc1, SPI_IRPT_INTR_2);

void SpiIntrHandler1(void *CallBackRef, u32 StatusEvent, u32 ByteCount)
{
	/*
	 * Indicate the transfer on the SPI bus is no longer in progress
	 * regardless of the status event.
	 */
	TransferInProgress1 = FALSE;

	/*
	 * If the event was not transfer done, then track it as an error.
	 */
	if (StatusEvent != XST_SPI_TRANSFER_DONE) {
		Error++;
	}
}

void SpiIntrHandler2(void *CallBackRef, u32 StatusEvent, u32 ByteCount)
{
	/*
	 * Indicate the transfer on the SPI bus is no longer in progress
	 * regardless of the status event.
	 */
	TransferInProgress1 = FALSE;

	/*
	 * If the event was not transfer done, then track it as an error.
	 */
	if (StatusEvent != XST_SPI_TRANSFER_DONE) {
		Error++;
	}

}

static int SpiSetupIntrSystem(INTC *IntcInstancePtr, XSpi *SpiInstancePtr,
u16 SpiIntrId)
{
int Status;

#ifdef XPAR_INTC_0_DEVICE_ID
#ifndef TESTAPP_GEN
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif

/*
* Connect a device driver handler that will be called when an interrupt
* for the device occurs, the device driver handler performs the
* specific interrupt processing for the device.
*/
Status = XIntc_Connect(IntcInstancePtr, SpiIntrId,
(XInterruptHandler) XSpi_InterruptHandler,
(void *)SpiInstancePtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

#ifndef TESTAPP_GEN
/*
* Start the interrupt controller such that interrupts are enabled for
* all devices that cause interrupts, specific real mode so that
* the SPI can cause interrupts through the interrupt controller.
*/
Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
#endif

/*
* Enable the interrupt for the SPI device.
*/
XIntc_Enable(IntcInstancePtr, SpiIntrId);

#endif

#ifndef TESTAPP_GEN



/* Enable interrupts from the hardware */
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)INTC_HANDLER,
(void *)IntcInstancePtr);

Xil_ExceptionEnable();



#endif /* TESTAPP_GEN */

return XST_SUCCESS;
}


static void SpiDisableIntrSystem(INTC *IntcInstancePtr, u16 SpiIntrId)
{

/*
* Disconnect and disable the interrupt for the Spi device.
*/
#ifdef XPAR_INTC_0_DEVICE_ID
/* Disconnect the interrupts for the Master complete and error */
XIntc_Disconnect(IntcInstancePtr, SpiIntrId);
#endif


}   

 

Tags (2)
0 Kudos
1 Reply
Highlighted
Explorer
Explorer
62 Views
Registered: ‎07-14-2014

This is a copy of another thread isn't it?
https://forums.xilinx.com/t5/Embedded-Development-Tools/How-to-do-parallel-interruptions-with-one-microblaze/m-p/1129035#M54403

Any update on my suggestion at the bottom?

Simon
0 Kudos