Showing results for 
Show  only  | Search instead for 
Did you mean: 
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_SetSlaveSelect(&SPI, 0);


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);

 * 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 |
 * 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?




Tags (2)
0 Kudos
0 Replies