Discussion:
[linux-sunxi] SPI in Linux 4.8.0-rc6: Weird dip in SCLK right when slave select goes low
Danny Milosavljevic
2016-09-22 21:52:52 UTC
Permalink
Hello,

when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux 4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning (which also confuses the slave) on the SCLK line right when SSEL goes low - see attachment.

The lines are, starting from the top, SCLK MOSI MISO SSEL.

I'm using spidev.

Did anyone see this problem before?

Regards,
Danny
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Siarhei Siamashka
2016-09-23 01:03:57 UTC
Permalink
On Thu, 22 Sep 2016 23:52:52 +0200
Post by Danny Milosavljevic
Hello,
when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux 4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning (which also confuses the slave) on the SCLK line right when SSEL goes low - see attachment.
The lines are, starting from the top, SCLK MOSI MISO SSEL.
I'm using spidev.
Did anyone see this problem before?
Hi,

I'm not sure, but something like this might be somehow related:
https://patchwork.kernel.org/patch/7960811/

As a random thing to check, I would also advise to verify the
pull-up/pull-down settings for the SCLK pin.

And maybe as another test, change the driver to automatically
drive the SSEL pin instead of doing this manually.

Also try to contact the author of the SPI driver via the
mainline kernel mailing list.
--
Best regards,
Siarhei Siamashka
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Maxime Ripard
2016-09-23 07:48:11 UTC
Permalink
Post by Siarhei Siamashka
On Thu, 22 Sep 2016 23:52:52 +0200
Post by Danny Milosavljevic
Hello,
when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux 4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning (which also confuses the slave) on the SCLK line right when SSEL goes low - see attachment.
The lines are, starting from the top, SCLK MOSI MISO SSEL.
I'm using spidev.
Did anyone see this problem before?
Hi,
https://patchwork.kernel.org/patch/7960811/
As a random thing to check, I would also advise to verify the
pull-up/pull-down settings for the SCLK pin.
And maybe as another test, change the driver to automatically
drive the SSEL pin instead of doing this manually.
We cannot do that, this would break the framework's expectations with
the behaviour you're suposed to have in set_cs (which is why we ended
up using the manual mode), and especially that it's supposed to happen
right away and control the logical level of the CS line.

Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Siarhei Siamashka
2016-09-23 18:12:48 UTC
Permalink
On Fri, 23 Sep 2016 10:48:11 +0300
Post by Maxime Ripard
Post by Siarhei Siamashka
On Thu, 22 Sep 2016 23:52:52 +0200
Post by Danny Milosavljevic
Hello,
when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux 4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning (which also confuses the slave) on the SCLK line right when SSEL goes low - see attachment.
The lines are, starting from the top, SCLK MOSI MISO SSEL.
I'm using spidev.
Did anyone see this problem before?
Hi,
https://patchwork.kernel.org/patch/7960811/
As a random thing to check, I would also advise to verify the
pull-up/pull-down settings for the SCLK pin.
And maybe as another test, change the driver to automatically
drive the SSEL pin instead of doing this manually.
We cannot do that
Well, of course we can do that. At least for the troubleshooting
purposes. And it's somewhat better than giving up and just going
to cry in a corner ;-)
Post by Maxime Ripard
this would break the framework's expectations with
the behaviour you're suposed to have in set_cs (which is why we ended
up using the manual mode), and especially that it's supposed to happen
right away and control the logical level of the CS line.
My understanding is that the framework is probably designed this way
in order to be able to use any *arbitrary* GPIO pin for the chip
select role. But the SPI controller itself can take care of the
*dedicated* chip select pin and assert/deassert it before/after
doing SPI message transfers. Patching the driver (again, only as a
troubleshooting experiment) should be relatively easy: the code
that changes the CS pin state just needs to be commented out and
the manual mode disabled.

My random guess about what might be happening is the following:
The SoC has a weak pull-up for the SCLK pin. And the slave device
has this pin in a high impedance state when the chip select pin
is deasserted. But after the SPI driver manually asserts the chip
select pin, the slave device probably changes the SCLK pin to
a strong pull-down state, overpowering the SoC pull-up for a
while. Then the SPI message transfer gets started by the SPI
driver and the SPI controller starts driving the SCLK pin for
real. Again, this is only a random guess and it definitely needs
to be verified.

Only Danny is lucky enough to have the right tools and a perfectly
reproducible test case. We can think about a proper fix (compatible
with the framework expectations) after we figure out what is actually
going on.
--
Best regards,
Siarhei Siamashka
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Danny Milosavljevic
2016-09-25 08:19:55 UTC
Permalink
On Fri, 23 Sep 2016 04:03:57 +0300
Post by Siarhei Siamashka
https://patchwork.kernel.org/patch/7960811/
As a random thing to check, I would also advise to verify the
pull-up/pull-down settings for the SCLK pin.
Where are they in mainline? The device tree file sun7i-a20.dtsi says SUN4I_PINCTRL_NO_PULL for spi2_pins_a - but do you mean more up-to-date runtime information?
Post by Siarhei Siamashka
And maybe as another test, change the driver to automatically
drive the SSEL pin instead of doing this manually.
What should I change exactly? I see that the patch changed it to manual slave selection - I can try to revert that one.
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Siarhei Siamashka
2016-09-26 00:28:18 UTC
Permalink
On Sun, 25 Sep 2016 10:19:55 +0200
Post by Danny Milosavljevic
On Fri, 23 Sep 2016 04:03:57 +0300
Post by Siarhei Siamashka
https://patchwork.kernel.org/patch/7960811/
As a random thing to check, I would also advise to verify the
pull-up/pull-down settings for the SCLK pin.
Where are they in mainline? The device tree file sun7i-a20.dtsi says
SUN4I_PINCTRL_NO_PULL for spi2_pins_a - but do you mean more
up-to-date runtime information?
Yes, you can check the exact pin settings by reading
hardware registers. Or by using the sunxi-pio tool from
https://github.com/linux-sunxi/sunxi-tools
Post by Danny Milosavljevic
Post by Siarhei Siamashka
And maybe as another test, change the driver to automatically
drive the SSEL pin instead of doing this manually.
What should I change exactly?
"Patching the driver (again, only as a troubleshooting experiment)
should be relatively easy: the code that changes the CS pin state just
needs to be commented out and the manual mode disabled."
Post by Danny Milosavljevic
I see that the patch changed it to manual slave selection -
I can try to revert that one.
Still you can first try to just experiment with the SCLK and SSEL
pins alone via GPIO, even without SPI. Try to assert the SSEL pin
and check what happens to the SCLK pin.

You can also have a look at the schematics of your slave device.
I suspect that there might be a pull-down resistor on the SCLK line.
You mentioned that the polarity settings are somewhat unusual. Maybe
the slave device expects the SCLK line to be initially low?
--
Best regards,
Siarhei Siamashka
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Maxime Ripard
2016-09-23 07:34:04 UTC
Permalink
Hi Danny,
Post by Danny Milosavljevic
Hello,
when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux
4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning
(which also confuses the slave) on the SCLK line right when SSEL
goes low - see attachment.
That's weird indeed. Is it a regression, or is it something you just
noticed?

Thanks,
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Danny Milosavljevic
2016-09-25 08:15:24 UTC
Permalink
Hi Maxime,

On Fri, 23 Sep 2016 10:34:04 +0300
Post by Maxime Ripard
That's weird indeed. Is it a regression, or is it something you just
noticed?
I only just noticed it.

This is also the first device I use ever to have CPOL=1 CPHA=1 (a TSS463AA).

TSS463AA has multiple modi chooseable after reset and this one is used in the Motorola SPI mode (as opposed to SCI, Intel SPI).

I don't understand why the slave would affect the SCLK line - TSS463AA is supposed to be the slave at all times.

I've used SPI on A20 before and it worked.

The next thing I'll do is I'll disconnect SCLK and see whether it still does that.
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Maxime Ripard
2016-09-26 19:24:28 UTC
Permalink
Post by Danny Milosavljevic
Hi Maxime,
On Fri, 23 Sep 2016 10:34:04 +0300
Post by Maxime Ripard
That's weird indeed. Is it a regression, or is it something you just
noticed?
I only just noticed it.
This is also the first device I use ever to have CPOL=1 CPHA=1 (a TSS463AA).
TSS463AA has multiple modi chooseable after reset and this one is
used in the Motorola SPI mode (as opposed to SCI, Intel SPI).
I don't understand why the slave would affect the SCLK line -
TSS463AA is supposed to be the slave at all times.
I've used SPI on A20 before and it worked.
The next thing I'll do is I'll disconnect SCLK and see whether it still does that.
Yes, I guess apart from all the tests Siarhei suggested already,
disconnecting the device entirely and trying to make some transfers
would be a good test.

Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Danny Milosavljevic
2017-05-23 19:52:49 UTC
Permalink
Hi Maxime,
Hi Siarhei,

On Mon, 26 Sep 2016 21:24:28 +0200
Post by Maxime Ripard
Yes, I guess apart from all the tests Siarhei suggested already,
disconnecting the device entirely and trying to make some transfers
would be a good test.
I did that now. I removed the slave (making the entire SPI bus open) and in order
to be able to measure a stable signal I put a resistor on the SPI bus (at SCLK) instead.

Then I sent some stuff via SPI (with 125 kHz).

When I made the resistor pull-up (2.2 kΩ to 3.3 V), it acted the same as it did with the
slave (weird dip at the very beginning of each message, fine otherwise).

When I made the resistor pull-down (2.2 kΩ to 0 V), it worked just fine, without dip.

It's 100% reproducible: Everytime I measure, I get that result (did it 27 times
now).

I've checked the sunxi-tools gpio output: There, for PC20 (SCLK), "pull" is "0"
(whatever that means).

Then I switched the mux of PC20 to GPIO mode and tried driving it myself. Works
just fine, no unexpected dips (though I can't get it faster than 200 μs period
that way and I didn't drive any other signals in parallel - no SSEL either).

The kernel version is 4.11.0-rc1.

The relevant part of the SPI program is:

/* probably sunxi specific */
#define MAX_LLTRANSFER_SIZE 64U

int LLinit(void) {
int fd = open("/dev/spidev32766.0" /* latter is CSIX */, O_RDWR);
if (fd == -1) {
perror("open");
return -1;
}
uint8_t mode = SPI_CPHA | SPI_CPOL; /* 3 */
int ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
if (ret == -1)
perror("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
if (ret == -1)
perror("can't get spi mode");

uint8_t bits_per_word = 0U;
uint32_t max_write_speed = 125000U;
/* FIXME remove this because it's in the DTS file */
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &max_write_speed) == -1) {
perror("ioctl");
return -1;
}
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word) == -1) {
perror("ioctl SPI_IOC_WR_BITS_PER_WORD");
return -1;
}
return fd;
}

/** Sends some block and at the same time receives another block.
@param fd file descriptor for the spidev
@param regno TSS463AA register number
@param controlvalue TSS463AA control value
@param senderbuf buffer to send
@param receiverbuf buffer to receive to AT THE SAME TIME
@param bothbufsz number of Bytes of the buffer to send, and to receive
*/
void LLtransceive(int fd, unsigned char regno, unsigned char controlvalue,
const void* senderbuf, void* receiverbuf, size_t bothbufsz) {
printf("LLtransceive %d\n", (int) bothbufsz);
/* limited to 64 Byte for sun4i */
struct spi_ioc_transfer xfer[MAX_LLTRANSFER_SIZE];
uint8_t acbuf[MAX_LLTRANSFER_SIZE];
uint8_t bcbuf[MAX_LLTRANSFER_SIZE];
int i;
if (bothbufsz > MAX_LLTRANSFER_SIZE - 2)
abort();
acbuf[0] = regno;
acbuf[1] = controlvalue;
if (senderbuf)
memcpy(&acbuf[2], senderbuf, bothbufsz);
else
memset(&acbuf[2], 0xFF, bothbufsz);
memset(xfer, 0, sizeof xfer);
xfer[0].tx_buf = (unsigned long) &acbuf[0];
xfer[0].rx_buf = (unsigned long) &bcbuf[0];
// FIXME add xfer[0].delay_usecs = 16;
xfer[0].len = bothbufsz + 2;
//xfer[1].cs_change = 1;
if (ioctl(fd, SPI_IOC_MESSAGE(1), xfer) == -1)
abort();
if (bcbuf[0] != 0xAAU || bcbuf[1] != 0x55U) {
/* should have been sent by TSS463AA to ensure synchronization */
fprintf(stderr, "bcbuf wrong %X %X\n", (unsigned) bcbuf[0],
(unsigned) bcbuf[1]);
// exit(1);
} else
fprintf(stderr, "bcbuf OK\n");
}

Note: SPI2 pins are: PC19[= CS, gpio83], PC20[SCK, gpio84], PC21, PC22.

Next, I'll try to disable CS manual mode in drivers/spi/spi-sun4i.c and test - still with nothing but the resistor connected. Let's see...
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Patrick Loef
2018-01-30 07:25:40 UTC
Permalink
Hello,

It is a late response, but I had the same thing in the LTS kernel 4.9.x.

After some research I saw that in the function: sun4i_spi_runtime_resume
the following code:

sun4i_spi_write(sspi, SUN4I_CTL_REG,
SUN4I_CTL_ENABLE | SUN4I_CTL_MASTER | SUN4I_CTL_TP);

This will setup the spi in master mode, stop transmit data when RXFifo is
full and enable the spi,
but also the wrong settings for CPOL, CPHA and CS etc.. this is done later
in the driver code and that causes the glitch,
so I enabled the spi later after all the settings are done and that works
just fine.

So I changes this code to:
sun4i_spi_write(sspi, SUN4I_CTL_REG,
SUN4I_CTL_MASTER | SUN4I_CTL_TP);

And in the function sun4i_spi_transfer_one @ 238 i added:

/* Enable here the SPI */
reg |= SUN4I_CTL_ENABLE;

After this I compiled the code and tested it with spi mode 0,1,2,3 and now
all works just fine.

Kind regards
Patrick
Post by Danny Milosavljevic
Hello,
when using SPI on Allwinner A20 with CPOL=1 and CPHA=1 with Linux
4.8.0-rc6 Psychotic Stoned Sheep I see a weird dip in the beginning (which
also confuses the slave) on the SCLK line right when SSEL goes low - see
attachment.
The lines are, starting from the top, SCLK MOSI MISO SSEL.
I'm using spidev.
Did anyone see this problem before?
Regards,
Danny
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...