cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
tom21091
Visitor
Visitor
608 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
0 Replies