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: 
Highlighted
Visitor tom21091
Visitor
232 Views
Registered: ‎08-03-2016

AXI_QUAD_SPI hangs during polled transfer

Hi guys,

 

I'm having a problem getting the AXI_QUAD_SPI v3.2 rev 18 core to complete a polled transfer. This is using a Zynq-Z7020. The core is set up in standard mode and uses a 100MHz AXI clock with a 4MHz ext_spi_clk and frequency ratio set to 16. Master mode is enabled and it has a FIFO depth of 16.

My init sequence is 

 

spiconfig = XSpi_LookupConfig(XPAR_AXI_QUAD_SPI_0_DEVICE_ID);
XSpi_CfgInitialize(&SPI, spiconfig, XPAR_AXI_QUAD_SPI_0_BASEADDR);
Status = XSpi_SelfTest(&SPI);
XSpi_SetOptions(&SPI, XSP_MASTER_OPTION);

XSpi_SetSlaveSelect(&SPI, 0);
XSpi_Start(&SPI);
XSpi_IntrGlobalDisable(&SPI);

 

Sometimes the program gets stuck in the LoopbackTest function inside of XSpi_SelfTest(). This is in the same do while loop as below. More on that in a bit.

Later, in another function, I call XSpi_Transfer to send/receive 4 bytes:

 

status = XSpi_Transfer(spidev, tx, rx, 4);

But when I do I get stuck in the do while loop in xspi.c:

 

 

...
while(ByteCount > 0) {
/*
 * Wait for the transfer to be done by polling the
 * Transmit empty status bit
 */
do {
	StatusReg = XSpi_IntrGetStatus(InstancePtr); //Stuck here
} while ((StatusReg & XSP_INTR_TX_EMPTY_MASK) == 0);
XSpi_IntrClear(InstancePtr,XSP_INTR_TX_EMPTY_MASK);

/*
 * A transmit has just completed. Process received data
 * and check for more data to transmit. Always inhibit
 * the transmitter while the transmit register/FIFO is
 * being filled, or make sure it is stopped if we're
 * done.
 */
ControlReg = XSpi_GetControlReg(InstancePtr);
XSpi_SetControlReg(InstancePtr, ControlReg |
			XSP_CR_TRANS_INHIBIT_MASK);
/*
 * First get the data received as a result of the
 * transmit that just completed. We get all the data
 * available by reading the status register to determine
 * when the Receive register/FIFO is empty. Always get
 * the received data, but only fill the receive
 * buffer if it points to something (the upper layer
 * software may not care to receive data).
 */
StatusReg = XSpi_GetStatusReg(InstancePtr);
while ((StatusReg & XSP_SR_RX_EMPTY_MASK) == 0) {
...

 

Pausing the debugger after hanging for a while, I see the Status reg= 0x25, control reg = 0x106, interrupt status=0x00. ByteCount = 1. This means that the processor made it past this point at least once. Unfortunately it only got 3 of the 4 bytes before the Status register RX_EMPTY bit was set to 1 for some reason.

When I set a break point after the TRANS_INHIBIT bit is cleared, I see the Status register change from:

0x21 (TX not empty, RX empty) to:

0x24 (TX empty, RX not empty, what I expect after the transfer has completed) to:

0x25 (TX empty, RX Empty) each time I step.

I assume this is caused by the debugger accessing the registers? So that means it's very hard to debug. Does anybody have any advice?

 

Thanks,

Tommy

Tags (2)
0 Kudos