UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Participant perencia-wc
Participant
1,146 Views
Registered: ‎10-03-2017

AXI Quad SPI (3.2) Loopback Error

I have the following design (Vivado 2016.3)

Screenshot from 2017-11-14 16-25-24.png

 

I export it to SDK and create a test peripheral application, which tests the AXI Quad SPI IP by using its loopback mode. If I run the this test from SDK, launching it to program the PL fabric and to Powerup it, everythink works as expected.

The problem comes when I try to load the bitstream, not from the SDK but from the petalinux bootloader. In that case, the loopback test fails. 

 

I would understand that something is wrong with the bootloader process if i couldn't access the IP at all, or if the GPIO that is on the same design, wouldn't work, but that's not the case. The GPIO works as expected, so the FPGA is programmed and responds. Moreover, the SPI IP seems to work, but nothing is received. The values on the registers after reset are correct as per the PG153 document. I debugged the LoopbackTest function itself and the registers reflect the diferent stages of the program, i.e as I send bytes to the FIFO, the Receive FIFO Occupancy register changes accordingly. But nothing is received, the RX fifo is always empty.

 

I've even monitored the SPI status register both when it works (programming the FPGA with the SDK) and when not (using the bootloader) and its value is the same on the same points of execution. 

 

And, as I said, this is all about the loopback test, which I understand is very basic. Could it be that some port of the IP (TX) works while the other not (RX) ? In loopback they are both connected, as the document states.

 

This is the LoopbackTest function, just for reference (the code is the one generated by the SDK itself when creating a peripheral test application)

 

Any help is greatly appreciated :)

 

static int LoopbackTest(XSpi *InstancePtr)
{
	u32 StatusReg;
	u32 ControlReg;
	u32 Index;
	u32 Data;
	u32 RxData;
	u32 NumSent = 0;
	u32 NumRecvd = 0;
	u8  DataWidth;

	/*
	 * Cannot run as a slave-only because we need to be master in order to
	 * initiate a transfer. Still return success, though.
	 */
	if (InstancePtr->SlaveOnly) {
		return XST_SUCCESS;
	}

	/*
	 * Setup the control register to enable master mode and the loopback so
	 * that data can be sent and received.
	 */
	ControlReg = XSpi_GetControlReg(InstancePtr);
	XSpi_SetControlReg(InstancePtr, ControlReg |
			    XSP_CR_LOOPBACK_MASK | XSP_CR_MASTER_MODE_MASK);
	/*
	 * We do not need interrupts for this loopback test.
	 */
	XSpi_IntrGlobalDisable(InstancePtr);

	DataWidth = InstancePtr->DataWidth;
	/*
	 * Send data up to the maximum size of the transmit register, which is
	 * one byte without FIFOs.  We send data 4 times just to exercise the
	 * device through more than one iteration.
	 */
	for (Index = 0; Index < 4; Index++) {
		Data = 0;

		/*
		 * Fill the transmit register.
		 */
		StatusReg = XSpi_GetStatusReg(InstancePtr);
		while ((StatusReg & XSP_SR_TX_FULL_MASK) == 0) {
			if (DataWidth == XSP_DATAWIDTH_BYTE) {
				/*
				 * Data Transfer Width is Byte (8 bit).
				 */
				Data = 0;
			} else if (DataWidth == XSP_DATAWIDTH_HALF_WORD) {
				/*
				 * Data Transfer Width is Half Word (16 bit).
				 */
				Data = XSP_HALF_WORD_TESTBYTE;
			} else if (DataWidth == XSP_DATAWIDTH_WORD){
				/*
				 * Data Transfer Width is Word (32 bit).
				 */
				Data = XSP_WORD_TESTBYTE;
			}

			XSpi_WriteReg(InstancePtr->BaseAddr, XSP_DTR_OFFSET,
					Data + Index);
			NumSent += (DataWidth >> 3);
			StatusReg = XSpi_GetStatusReg(InstancePtr);
		}

		/*
		 * Start the transfer by not inhibiting the transmitter and
		 * enabling the device.
		 */
		ControlReg = XSpi_GetControlReg(InstancePtr) &
						 (~XSP_CR_TRANS_INHIBIT_MASK);
		XSpi_SetControlReg(InstancePtr, ControlReg |
				    XSP_CR_ENABLE_MASK);

		/*
		 * Wait for the transfer to be done by polling the transmit
		 * empty status bit.
		 */
		do {
			StatusReg = XSpi_IntrGetStatus(InstancePtr);
		} while ((StatusReg & XSP_INTR_TX_EMPTY_MASK) == 0);

		XSpi_IntrClear(InstancePtr, XSP_INTR_TX_EMPTY_MASK);

		/*
		 * Receive and verify the data just transmitted.
		 */
		StatusReg = XSpi_GetStatusReg(InstancePtr);
		while ((StatusReg & XSP_SR_RX_EMPTY_MASK) == 0) {

			RxData = XSpi_ReadReg(InstancePtr->BaseAddr,
						XSP_DRR_OFFSET);

			if (DataWidth == XSP_DATAWIDTH_BYTE) {
				if((u8)RxData != Index) {
					return XST_LOOPBACK_ERROR;
				}
			} else if (DataWidth ==
					XSP_DATAWIDTH_HALF_WORD) {
				if((u16)RxData != (u16)(Index +
						   XSP_HALF_WORD_TESTBYTE)) {
					return XST_LOOPBACK_ERROR;
				}
			} else if (DataWidth == XSP_DATAWIDTH_WORD) {
				if(RxData != (u32)(Index + XSP_WORD_TESTBYTE)) {
					return XST_LOOPBACK_ERROR;
				}
			}

			NumRecvd += (DataWidth >> 3);
			StatusReg = XSpi_GetStatusReg(InstancePtr);
		}

		/*
		 * Stop the transfer (hold off automatic sending) by inhibiting
		 * the transmitter and disabling the device.
		 */
		ControlReg |= XSP_CR_TRANS_INHIBIT_MASK;
		XSpi_SetControlReg(InstancePtr ,
				    ControlReg & ~ XSP_CR_ENABLE_MASK);
	}

	/*
	 * One final check to make sure the total number of bytes sent equals
	 * the total number of bytes received.
	 */
	if (NumSent != NumRecvd) {
		return XST_LOOPBACK_ERROR;
	}

	return XST_SUCCESS;
}

 

 

 

 

 

0 Kudos
3 Replies
Visitor soccerno16
Visitor
1,051 Views
Registered: ‎03-22-2018

Re: AXI Quad SPI (3.2) Loopback Error

I'm using Vivado 2017.2 and SEx 2017.2 with AXI Quad SPI (3.2).

 

When I import the example xpsi_selftest_example and run it it fails the Loopback test.  I've configured my spi as follows with 256 FIFO.

            FIRST ATTACHMENT

When I run the loopback test it fails because the NumSent != Num Recevied in xspi_selftest.c

xspi_selftest.c

	/*
	 * One final check to make sure the total number of bytes sent equals
	 * the total number of bytes received.
	 */
	if (NumSent != NumRecvd) {
		return XST_LOOPBACK_ERROR;
	}

	return XST_SUCCESS;

It varies but NumSent might equal 1070 and NumRecvd1024.

 

2nd run NumSent = 1064, NumRecvd = 1024.

3nd run NumSent = 1065, NumRecvd = 1024.

4th run NumSent = 1068, NumRecvd = 1024.

5th run NumSent = 1078, NumRecvd = 1024.

 

If I run it without breakpoints it seems to settle on a consistently wrong number, if I break at the comparison line ~357 in xspi_selftest.c the NumSent seems to change.  See below NumSent=1160 is when breakpoints are skipped.

             SECOND ATTACHMENT

This is a stock example.  I've confirmed with an o-scope that I can execute the xspi_polled_example and transmit as master.  I had to remove the selttest in this example. 

 

Ultimately I am trying to get a xspi device to received as a slave.  I have two xspi devices setup and hooked up my interrupts so that the slave RX is interrupt driven and the master is polled but for the life of me I cannot get it to work.  I've reverted back to simple examples trying to find out what the underlying problem is.

quadspi.jpg
quadspiout.jpg
0 Kudos
Visitor soccerno16
Visitor
1,037 Views
Registered: ‎03-22-2018

Re: AXI Quad SPI (3.2) Loopback Error

I made a little progress on my own problem.

I believe though this a canned example.  That the Zynq AXI bus is actually racing faster than the s_axi_aclk (100Mhz) can update the register in the fpga fabric.  In the LoopbackTest function xpsi_selftest.c, I added a (VERY CRUDE) delay while filling the tx register so that the xspi status register had a chance to get updated in the fabric and things seem to work.  Can anyone suggest a better way to confirm this?  I would have expected more from the example...?

 

/*
		 * Fill the transmit register.
		 */
		StatusReg = XSpi_GetStatusReg(InstancePtr);
		while ((StatusReg & XSP_SR_TX_FULL_MASK) == 0) {
			usleep(10);
			if (DataWidth == XSP_DATAWIDTH_BYTE) {
				/*
				 * Data Transfer Width is Byte (8 bit).
				 */
				Data = 0;
			} else if (DataWidth == XSP_DATAWIDTH_HALF_WORD) {

 

0 Kudos
Newbie warmonkey
Newbie
753 Views
Registered: ‎12-25-2017

Re: AXI Quad SPI (3.2) Loopback Error

there is a problem that axi quad spi does not show error when frequency ratio is wrong. in legacy mode standard (single) spi,ratio must >=4。 you should not use ratio 2
0 Kudos