Peak of Chip-Select during SPI Transfer + "High" signal between words

Hi,

For this example, I’ve using SPI 1 - Chip-Select 0 (or /dev/spidev1.0), configured to work at 10 MHz, 16-bit per word, Most Significant Bit First, CPOL=0 e CPHA=0. In the end of this question is the configuration of this node in device-tree.

In the images showed below, please observe of this sequence of the signals, from top to bottom:

  • Chip-Select
  • Clock
  • MOSI

I’m facing a problem here, which is a “peak” of the Chip-Select signal during a SPI transfer.
See below:
[upload|B+nctXVDVTTm9vJ7oroUCeksPCY=]

What could be causing that? It is not occurring all the time, but can mess with the functioning of the other peripheral I’ll be using in the other side.

Plus, another problem is a persistent “High” signal between words in a SPI Transfer.
In a transfer that the Chip-Select behave “normally”, I’ve got this result:

[upload|+52jZyL0qjCEzvlFLvNlBUUlZEU=]

Please, observe the “High” signal between words of 0x0000.

I’m using the linux-toradex 4.4-next branch.
According to @gafernandes, I’ve configured the spidev1.0 like this way in device-tree, hoping to fix the “clock” issue between two consecutive words.

&dspi1 {
	status = "okay";

	/* This will create /dev/spidev1.0 */
	spidev10: spidev1@0 {
		compatible = "toradex,evalspi";
		reg = <0>;
		spi-max-frequency = <10000000>;
		fsl,spi-cs-sck-delay = <100>;
		fsl,spi-sck-cs-delay = <50>;
		status = "okay";
	};

What could be causing the peak of chip-select?

Is it normal to have this “high” signal between words?

Is there any way to fix this issues?

Thanks for your attention,
Andre Curvello

Can you share the struct spi_ioc_transfer you use when testing for the above two cases?

Of course!

Taking in consideration that I’m using this set of information:

  • uint16_t tx;
  • uint16_t rx;
  • static uint8_t bits = 16;
  • static uint32_t speed = 10000000;
  • static uint16_t delay = 50;

(I’ve inserted this delay to see if it would fix the annoying clock behavior between words)

Here it is:

	struct spi_ioc_transfer tr = {
		.tx_buf = (unsigned long)tx,
		.rx_buf = (unsigned long)rx,
		.len = len,
		.delay_usecs = delay,
		.speed_hz = speed,
		.bits_per_word = bits,
	};

I’ve tried here with the delay_usecs set to 0, and yet the “peak” of chip-select still keeps occurring.

Is the peak always at the same spot? How does your wiring look like? Does decreasing the speed help to alleviate the problem?

Hi @stefan.tx,

The peak occurs most of the time when I start with a frame like “0x8000”.

I’ve tried with other speeds, like 5 MHz, 12 MHz, and even with those speeds this peak keeps occurring.

I’m using a wiring with 10cm cables between the EVM and a Saleae Logic Analyzer.
You think that this wiring could be the cause?

And… About the “high” signal between words, what could it be?

I am not a hardware specialist, but this peaks at random positions look somewhat suspicious to me. It could be a ground loop or similar which lifts the chip-select signal just above the threshold.

Maybe a closer look on the signals reviles more, do you have access to an oscilloscope?

Regarding MISO signal: I guess in a CPOL=0 setting it is “ok” to have the MISO in a undefined state when the clock is on its falling edge. I agree, it looks suspicious though. Maybe the SoC just does not drive the pin anymore at that point. If your device is sensitive to that, maybe using a pull-down instead of a pull-up for the data line might help (0x33c2):

	pinctrl_dspi1: dspi1grp {
		fsl,pins = <
			VF610_PAD_PTD5__DSPI1_CS0		0x33e2
			VF610_PAD_PTD6__DSPI1_SIN		0x33e1
			VF610_PAD_PTD7__DSPI1_SOUT		0x33c2
			VF610_PAD_PTD8__DSPI1_SCK		0x33e2
		>;
	};

Thanks for this suggestion.

Unfortunately, configuring the pull-down for SOUT did not solve the “High” signal between words.

And about the peak at chip-select, it occurs in SPI transmissions when I send a “write” bit at MSB of the first SPI word.

What do yo mean by write bit at MSB? I am not aware of a write bit in standard SPI protocol, is this maybe a device specific protocol?

Yeah your first capture above shows that too. That is what led me to believe that it could be a interference issue.

In my project I get the same problem of SOUT high between words. I didn’t find any way to set it LOW using the pull-down of the pin.
This is the reason why I opened this topic on NXP community; no answers up to now, unfortunately.

@stefan.tx, we use an approach here in which we send a SPI data constructed with address+data_payload. The first bit of the address (MSB) is the bit who says if this transmission is a read or write.

We are managing to get rid of that peak, I think that it is really signal noise.

But, as @vix is seeing too, we are facing the “high” signal between words in a SPI transmission.

The “High” signal between words

I can observe that here too, and found not a way to change that behavior. Looking at the timing diagram in the Vybrid Reference Manual (Chapter 12.4.4.4.1 Classic SPI Transfer Format) shows that the behavior is expected. I hooked up an oscilloscope, and it shows that the transition is well after the rising edge. Given that we sample on rising edge (CPOL=0, CPHA=0), this behavior should really not be a problem (see also this timing diagram, the MOSI signal level is undefined in this phase).

[upload|OcXtRyo4ub05aBF+BPnjMZenx2k=]

[upload|tI34sTmha6RMcO5naZbdi8keXx4=]

Peak in the Chip-Select signal

I tried to reproduce that behavior here, without success. My test setup consisted of a user space application continuously sending 3 x 0x8000 in a Linux SPI transfer using /dev/spidev1.0. Using SPI_IOC_WR_BITS_PER_WORD to request 16 bits, and SPI_IOC_WR_MAX_SPEED_HZ requesting 10MHz. I also added the delays in the device tree. To capture a peak, I used a PWM trigger on the CS signal, triggering to any signal which is low for shorter than 3.5us (which is well below one transfer length). I let that run for about 5 minutes, so thousands of transfers must have passed, the Oscilloscope never caught anything.
[upload|tEhMa+MEz9x0/1HqxsQb8FosfiI=]

It seems to me that your Logic Analyzer is really capturing something erratic, maybe a reflection or something similar. What you can try is using less drive strength and configure the pad to 50MHz:

            pinctrl_dspi1: dspi1grp {
                    fsl,pins = <
                           VF610_PAD_PTD5__DSPI1_CS0               0x02e2
                           VF610_PAD_PTD6__DSPI1_SIN               0x02e1
                           VF610_PAD_PTD7__DSPI1_SOUT              0x02e2
                           VF610_PAD_PTD8__DSPI1_SCK               0x02e2
                    >;
            };

Oh, I saw this too late. Regarding “high” signal, see below.