cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
carlomundsen
Observer
Observer
1,611 Views
Registered: ‎05-12-2017

Zynq 7020 PS SPI to EMIO hang in polledTransfer

I have the PS SPI0 port enabled through the EMIO interface on a Zynq 7020. The PL pins are all on bank 35 at 3V3. A block diagram connection snippet is attached (note all the SPI traces just go straight to external ports). I am using vivado 2016.2

 

SPI.PNG

 

With a FreeRTOS bsp, I am using the spips_v3_0 library and its polled transfer method to write to 2 slaves. They are both write only devices (so essentially a 3 wire interface, MISO is redundant).

 

It works about 50% of the time, while the remaining 50% of attempts to write end up hanging in XSpiPs_PolledTransfer() where it is spinning waiting for the TX fifo status to report empty (line 561):

 

			/*
			 * Wait for the transfer to finish by polling Tx fifo status.
			 */
	        CheckTransfer = (u32)0U;
	        while (CheckTransfer == 0U){
			StatusReg = XSpiPs_ReadReg(
					        InstancePtr->Config.BaseAddress,
						        XSPIPS_SR_OFFSET);
				if ( (StatusReg & XSPIPS_IXR_MODF_MASK) != 0U) {
					/*
					 * Clear the mode fail bit
					 */
					XSpiPs_WriteReg(
						InstancePtr->Config.BaseAddress,
						XSPIPS_SR_OFFSET,
						XSPIPS_IXR_MODF_MASK);
					return (s32)XST_SEND_ERROR;
				}
		        CheckTransfer = (StatusReg &
							XSPIPS_IXR_TXOW_MASK);
		    }

 

Has anyone else experienced this bug? I see older references to something similar but they all seem to have resolved the issue on a library update or similar. Code snippets for setup and write functions are below:

 

bool tx_configure_spi( void )
{
	int Status;
	XSpiPs_Config *SpiConfig;

	
	//Initialize the SPI driver so that it's ready to use
	SpiConfig = XSpiPs_LookupConfig(TX_SPI_DEVICE_ID);
	if (NULL == SpiConfig) {
		return false;
	}

	Status = XSpiPs_CfgInitialize(&SpiInstance, SpiConfig, SpiConfig->BaseAddress);
	if (Status != XST_SUCCESS) {
		return false;
	}

	Status = XSpiPs_SelfTest(&SpiInstance);
	if (Status != XST_SUCCESS) {
		return false;
	}

	//Set the Spi device as a master with manual CS.
	XSpiPs_SetOptions(&SpiInstance, XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION);

	//todo: will  want to adjust the pclk (currently set to 20MHz)
	XSpiPs_SetClkPrescaler(&SpiInstance, XSPIPS_CLK_PRESCALE_64);


	return true;
}


bool tx_spi_write(xTXspiWriteBuffer* spibuf)
{
	XSpiPs_SetSlaveSelect(&SpiInstance, spibuf->cs);
	XSpiPs_PolledTransfer(&SpiInstance, spibuf->data, NULL, spibuf->length);
	XSpiPs_SetSlaveSelect(&SpiInstance, 0x0F);  //force deselect of CS

	return true;
}

The only other thing to note is I am using tx_spi_write() before the RTOS task scheduler starts (and interrupts etc are enabled), but I figure this should not matter for polled transfer. Is it perhaps something incorrectly wired up in the bd? Or is there something else I am missing?

 

Thanks in advance, all ideas/suggestions welcome!

 

0 Kudos
2 Replies
dchang3etagen
Observer
Observer
1,248 Views
Registered: ‎07-03-2018

@carlomundsen

Did you ever resolve this issue?  I am having a similar issue on the Zynq Ultrascale+ MPSoC with SPI routed through EMIO.

0 Kudos
pitchaya
Newbie
Newbie
942 Views
Registered: ‎10-12-2018

Hi,

      I had a similar problem and solved it on my design.  For me, I had to pull  SS_I  high when it is not being used.

0 Kudos