cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
jawbone_101
Adventurer
Adventurer
7,266 Views
Registered: ‎05-07-2008

Zynq PS SPI1 MOSI/CLK "pluse"

Jump to solution

Hello,

 

I am using spidev driver to communicate with an external SPI slave. I am using the test program(s) with spidev to further debug my own userland SPI program. I wish to run in SPI mode 0.

 

All SPI transactions seems to be ok. I read/write values I expect from/to SPI. However, when looking at the bus I see a pulse on both MOSI and CLK before the transfer starts. They are both the same width.

 

If I were only doing a single transfer while chip-select is low then I would not be overly concerned. However, I will need to do several transfers while chip-select is low.

 

Right before the next transfer, there is another pluse. Hopefully that is visible in the picture below.

screenshot.png

 

First thoughts were SPI_CPOL and SPI_CPHA are setting up the controller for SPI mode 3 for a short time. I tried to force these to both be zero (maybe I missed it somewhere).

 

Anyway, it is not obvious to be why this is happening.

 

Another hint, maybe.

Any ioctl that writes causes this same behavior. Like, from spidev_test.c

 

    ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);

 

Any pointers or help is apprciated.

 

Regards,

Steve

 

 

Setup:

Custon board with a 7030 device

Running Ubuntu 13.10 on the Zynq device

 

uname -a
Linux zynq 3.12.0-xilinx-dirty #28 SMP PREEMPT Mon Mar 31 11:40:29 CDT 2014 armv7l armv7l armv7l GNU/Linux

 

 

0 Kudos
1 Solution

Accepted Solutions
jawbone_101
Adventurer
Adventurer
9,263 Views
Registered: ‎05-07-2008

Well...not sure what to make of this yet, but here's the latest for anyone interested.

In function, xspips_setup_transfer you will find:

<snip>

    spin_lock_irqsave(&xspi->ctrl_reg_lock, flags);
    xspips_write(xspi->regs + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
    ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
</snip>

The SPI control register is read AFTER the controller is disabled and then modified per the requirements for the next transfer.

Well, for me at least, this is what's causing the trouble. If I read the control register BEFORE the controller is disabled then all seems to work fine.


Then I decided to try to simply remove the line that disables the SPI1 controller. I get the same positive effect as moving the read before the disable.



ALSO:

I am using the zynqhf toolchain from Linaro:

 

(gcc version 4.8.2 20131014 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.10 - Linaro GCC 2013.10) ) #72 SMP PREEMPT Wed Apr 2 16:09:33 CDT 2014

 

 

View solution in original post

0 Kudos
7 Replies
jawbone_101
Adventurer
Adventurer
7,263 Views
Registered: ‎05-07-2008

I should have added that before I switched to Linux, I had a bare-metal code version of my app and this problem did not show up.

So I do not believe it is a Zynq or board problem. It's some sort of driver issue I'm pretty sure.

 

Thanks again

0 Kudos
rfs613
Scholar
Scholar
7,241 Views
Registered: ‎05-28-2013

Check the cs_change field in spi_ioc_transfer, this controls whether CS is de-asserted after the transfer. In theory you should be able to control it from the structures your user-space code passes to ioctl().

 

I can't say it actually works, because when I worked on it, I didn't know about about cs_change. My "solution" was to pack all my bytes into a single buffer (including dummy writes where I actually want to read). This got me talking to a device that insisted CS remain asserted through the entire cycle.

0 Kudos
jawbone_101
Adventurer
Adventurer
7,237 Views
Registered: ‎05-07-2008
Thanks. cs_change is working as expected. It stays de-asserted between transfers when set to 1. The problem is the pulse on mosi and clk before the xfer starts. Like the setup before the xfer does something to the lines.
0 Kudos
rfs613
Scholar
Scholar
7,216 Views
Registered: ‎05-28-2013
Hmm, I don't recall having that issue when I scoped my signals - unfortunately I did not keep them after I got things working, so I can't check. Sorry.
0 Kudos
jawbone_101
Adventurer
Adventurer
7,205 Views
Registered: ‎05-07-2008

Investigation is ongoing, but it is something in function xspips_setup_transfer (in file spi-zynq.c) that is causing the issue I'm seeing.

 

0 Kudos
rfs613
Scholar
Scholar
7,202 Views
Registered: ‎05-28-2013
Incidentally, I am running 3.9 kernel on mine. Haven't had time to try 3.12 yet. It's possible the behaviour changed, the SPI drivers did undergo some renaming.
0 Kudos
jawbone_101
Adventurer
Adventurer
9,264 Views
Registered: ‎05-07-2008

Well...not sure what to make of this yet, but here's the latest for anyone interested.

In function, xspips_setup_transfer you will find:

<snip>

    spin_lock_irqsave(&xspi->ctrl_reg_lock, flags);
    xspips_write(xspi->regs + XSPIPS_ER_OFFSET, ~XSPIPS_ER_ENABLE_MASK);
    ctrl_reg = xspips_read(xspi->regs + XSPIPS_CR_OFFSET);
</snip>

The SPI control register is read AFTER the controller is disabled and then modified per the requirements for the next transfer.

Well, for me at least, this is what's causing the trouble. If I read the control register BEFORE the controller is disabled then all seems to work fine.


Then I decided to try to simply remove the line that disables the SPI1 controller. I get the same positive effect as moving the read before the disable.



ALSO:

I am using the zynqhf toolchain from Linaro:

 

(gcc version 4.8.2 20131014 (prerelease) (crosstool-NG linaro-1.13.1-4.8-2013.10 - Linaro GCC 2013.10) ) #72 SMP PREEMPT Wed Apr 2 16:09:33 CDT 2014

 

 

View solution in original post

0 Kudos