Jump to content
  • 0

SPI not working after JTAG flash


gueste

Question

Hello everyone,

I'm currently facing some strange behavior of an SPI interface on my Eclypse Z7:
Everything works perfectly fine as long as the board is programmed through QSPI for debugging - the self-test is good, with no errors, and I can use the device as expected.
However, once I try to program it via JTAG (or from SD card), the SPI self-test fails with error #14, indicating an unexpected register value in the configuration register:

#define XST_REGISTER_ERROR              14L	/*!< A register did not contain the expected value */

Also, when trying to send some data after the failed test, the code gets stuck in the sending / receiving process.

We're using SPI #1 as an output to control an external DAC through EMIO. The signal is routed through the PL to one of the PMOD connectors, as shown in the attached screenshot.
(SPI #0 is also used as an input to read from an external ADC but works without any problems in both cases, even after programming the device via JTAG. )
So only SPI #1 is affected by the problem.

Both SPI devices are initialized by the same code (shown below). The only difference is their usage in the PL.

int setupSPI(XSpiPs *spiPtr, u16 deviceID, u8 SlaveSelectAddr, bool clkPhaseOne, u8 clkPrescaler) {
	xil_printf("Setting up SPI instance...\r\n");
	int Status;
	XSpiPs_Config *Config;

	/*
	 * Initialize the SPI driver so that it's ready to use
	 * Look up the configuration in the config table, then initialize it.
	 */
	Config = XSpiPs_LookupConfig(deviceID);
	if (NULL == Config) {
		xil_printf("ERROR: SPI setup failed on configuration lookup.\r\n");
		return XST_FAILURE;
	}

	Status = XSpiPs_CfgInitialize(spiPtr, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		xil_printf("ERROR: SPI setup failed during config initialization.\r\n");
		return XST_FAILURE;
	}

	/*
	 * Perform a self-test.
	 */
	sleep(1);
	Status = XSpiPs_SelfTest(spiPtr);
	if (Status != XST_SUCCESS) {
		xil_printf("WARNING: SPI self-test error #%d\r\n", Status);
		//return XST_FAILURE;
	}

	/*
	 * Set the SPI device as a master with manual start and manual
	 * chip select mode options
	 */
	if (clkPhaseOne) {
		XSpiPs_SetOptions(spiPtr, XSPIPS_MANUAL_START_OPTION | \
				XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION | XSPIPS_CLK_PHASE_1_OPTION);
	} else {
		XSpiPs_SetOptions(spiPtr, XSPIPS_MANUAL_START_OPTION | \
				XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION);
	}

	/*
	 * Set the SPI device pre-scaler to divide e.g. by 8, resulting in a clk rate of ~20,833 MHz (ADC maximum: 63 MHz / DAC maximum: 20 MHz)
	 */
	XSpiPs_SetClkPrescaler(spiPtr, clkPrescaler);

	// Set Slave select output.
	Status = XSpiPs_SetSlaveSelect(spiPtr, SlaveSelectAddr);
	if (Status != XST_SUCCESS) {
		xil_printf("ERROR: SPI failed setting Slave Select.\r\n");
		return XST_FAILURE;
	}

	xil_printf("--> SPI setup successful.\r\n");
	return XST_SUCCESS;
}//setupSPI

Both, XSpiPs_LookupConfig and XSpiPs_CfgInitialize don't return any errors, no matter how the Eclypse Z7 is programmed.

 

I'm glad for any advice, thanks in advance.

PL routing of SPI 1 (and SPI 0).PNG

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

Hi,

it seems that we finally solved the problem.

Since we've been running out of ideas, I began removing other HW components in the design and checking the outcome.
There has also been a Zmod ADC IP block in the HW design.
After removing the Zmod and all the related IP blocks, we've been able to flash the device successfully.

I don't know why the Zmod caused the problem, but it works now.

Thanks again for your support,
gueste

Edited by gueste
Link to comment
Share on other sites

  • 0

Hi @gueste,

We're taking a look into this; I'm not sure at the moment what the source of the problem might be; none of the SPI pins (QSPI flash, SPI0, or SPI1) should be sharing pin resources with each other so they should not be interacting with each other, and the self-test should be program source agnostic.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Hi @gueste,

The other engineer more familiar with the Eclypse hardware (and Zynq hardware in general) has gotten the Vivado project created, but hasn't gotten the opportunity to do debugging as of yet (they were out of office most of last week).

I will let you know if I hear any updates.

Regarding the switch from EMIO to AXI based SPI, I do not think it would resolve the issue, but I do not think it would hurt to attempt.

Thanks,
JColvin

Link to comment
Share on other sites

  • 0

Hi @gueste,

I've been looking into it and haven't been able to reproduce the error. I've attached the Vivado/Vitis 2021.1 projects I've been using to try things out. It has some differences, but nothing that should be showstopping: primarily I made the entire SPI interfaces, as opposed to individual pins, external and constrained them to Pmod ports, including all of the _ss pins. I also disabled the Manual Start option in software.

This project is functioning reasonably well on a board with the SPI pins hooked up to a logic analyzer and a loopback jumper installed from MOSI to MISO on SPI1. I've only tried JTAG debugging, which is working; I'm not getting the error you are seeing.

I'm fairly confused as to where issues could be coming from.

Looking through the selftest function, which claims to be "destructive", it looks like it should not be causing problems at the point in the code where it is being run, as the SPI hardware is reset both at the end of the selftest and at the end of CfgInitialize.

What arguments are you passing to setupSPI?

How are you initiating transfers, or are you not getting to that point with SPI1? 

Thanks,

Arthur

vitis_export_archive.ide.zip project_16.xpr.zip

Link to comment
Share on other sites

  • 0

Hi Arthur,

thanks for having a look at my problem.
I tried to set up my SPI interfaces according to your example but didn't have any success. The error still persists.

When programming the device via JTAG, I'm not even getting to the point of initiating transfers. The faulty configuration is recognized during the self-test procedure, right after initialization, but doesn't seem to be caused by it. It's possible to ignore the error thrown by the self-test, but then the program gets stuck when trying to send data.
Everything works fine when programming the device through QSPI, including data transfer.

The following arguments are passed to the two SPI instances:

SPI #1:
setupSPI(&SPI_0_PCI, SPI_0_DEVICE_ID, SPI_0_SLAVE_SELECT, SPI_0_PHASE_ONE, SPI_0_PRESCALER);

XSpiPs SPI_0_PCI;
#define SPI_0_DEVICE_ID				XPAR_XSPIPS_0_DEVICE_ID		// = XPAR_PS7_SPI_0_DEVICE_ID
#define SPI_0_SLAVE_SELECT			0x00
#define SPI_0_PHASE_ONE				TRUE
#define SPI_0_PRESCALER				XSPIPS_CLK_PRESCALE_8
------------------------------------------------------------------------
SPI #2:
setupSPI(&SPI_1_PCO, SPI_1_DEVICE_ID, SPI_1_SLAVE_SELECT, SPI_1_PHASE_ONE, SPI_1_PRESCALER);

XSpiPs SPI_1_PCO;
#define SPI_1_DEVICE_ID				XPAR_XSPIPS_1_DEVICE_ID		// = XPAR_PS7_SPI_1_DEVICE_ID
#define SPI_1_SLAVE_SELECT			0x00
#define SPI_1_PHASE_ONE				TRUE
#define SPI_1_PRESCALER				XSPIPS_CLK_PRESCALE_16

I'm currently working with Vivado/Vitis 2020.1. Might that be part of the problem?

Thanks,

gueste

Link to comment
Share on other sites

  • 0

Good to hear that it's working. It's still strange that the Zmod ADC IP might have been causing it. It might be possible that a hardcoded buffer address range in the software overlapped with the SPI driver.

The version difference between 2020.1 and 2021.1 shouldn't be causing the issue. I haven't tried EMIO SPI with 2020.1, so *maybe* there's a critical difference in the xspips driver, but it's unlikely.

Thanks for sharing your fix.

-Arthur

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...