Showing results for 
Search instead for 
Did you mean: 
Registered: ‎09-11-2018

XSpi_Transfer stuck on XSP_INTR_TX_EMPTY_MASK - in Polled mode

(I had this post in this thread here earlier, but I had already accepted the solution to its original question, so I'm moving the new question to this new thread

I have some configuration problem, apparently.

I have taken the Winbond SPI flash driver code example (IRQ based), and also looked at another example for polled mode - because I don't have/want an interrupt for this SPI channel, and tried to change my setup such that I am using polled mode, no interrupt.

Yet, when I am trying to use this SPI, then I am seeing something strange:
The first call to XSpi_Transfer() does return - when I read the status register of the connected flash IC. The result seems wrong, but that could have a lot of causes.
When I later call  XSpi_Transfer() again to send a sector erase command to the flash, XSpi_Transfer() hangs...
And now with debugging enabled for the BSP, I see it hangs here:

do {
	StatusReg = XSpi_IntrGetStatus(InstancePtr);
} while ((StatusReg & XSP_INTR_TX_EMPTY_MASK) == 0);

So it seems it is expecting to be something happening with regards to an interrupt. Althouth this loop is in the code branch which a comment describes as: "Polled mode of operation", and the branch above that, it's called "Interrupt Mode of operation".
Why is it querying interrupt related flags there (at least that's what their names and comments above the defines suggest)?
If I am just misunderstanding this and it has not (necessarily) something to do with interrupt:

What could cause the TX register not becoming empty / how could I investigate that?

Here is my modified winbond flash example init code, with the intent to make it polling mode:

static int read_status()
int ret = transfer(WriteBuffer, ReadBuffer, STATUS_READ_BYTES);
return ret==XST_SUCCESS ? ReadBuffer[1] : -1;

int XspiFlash_Init()
{ ConfigPtr = XSpi_LookupConfig(SPI_DEVICE_ID); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } if ( XST_SUCCESS != XSpi_CfgInitialize(&m_xspi, ConfigPtr, ConfigPtr->BaseAddress) || XST_SUCCESS != XSpi_SetOptions(&m_xspi, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION) || XST_SUCCESS != XSpi_SetSlaveSelect(&m_xspi, SPI_SELECT) ) { return XST_FAILURE; } XSpi_Start(&m_xspi); /* * Disable Global interrupt to use polled mode operation */ XSpi_IntrGlobalDisable(&m_xspi); const int stat = read_status(); // *** NOTE *** This calls XSpi_Transfer, which returns, a value of 0xff (wrong, but anyway)
if (stat < 0)

if (!(stat & quadEnableBit)) // let's only write this NON-VOLATILE bit if need be, to not unnecessarily reduce the lifetime.
{ // [removed for brevity] code to set flash to quad mode - get's never called, as 0xff always has the QE bit set...
} return XST_SUCCESS; }

After that init code, XSpi_Transfer is called once more - to send a command for Sector Erase to the flash, and it hangs on that, waiting for the TX empty, like described above.

Tags (3)
0 Kudos
1 Reply
Registered: ‎09-11-2018

Re: XSpi_Transfer stuck on XSP_INTR_TX_EMPTY_MASK - in Polled mode

Ok folks, I have no idea why it does not work in polled mode.

I configured things for interrupt mode, and it seems to just work. So although it seems kinda unnecessary to use an interrupt in my scenario, since it doesn take away from anything else that might need one, I won't bother investigating this further.


0 Kudos