doceme / py-spidev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[RPi 4] Spurious CS pulse after transfer

eelcogg opened this issue · comments

Hi,

I'm using spidev 3.4 on a raspberry pi 4, python version 3.7.3. I am trying to communicate with an ADNS3080 optical flow sensor.
I am using CE0 (gpio8), MOSI (gpio10), MISO (gpio9), and SCLK (gpio11).
After each transfer on the SPI bus, the chip select line gives a spurious pulse 40us after going high at the end of the transfer. It stays low for roughly 11us. This screws up the timing on the ADNS. I am sending a command to prepare it for clocking out data, but the extra clock pulse arrives before the ADNS is ready to clock out the data (it needs CS high for 75us to do a read)

My issue is similar to this one and this one. Therefor I believe it is unrelated to the slave device I'm using.

I have attached a logic analyzer trace (pulseview, saleae logic analyzer) reading register 0x00 for the device ID (0x17)
cs_bug_pulseview

EDIT: It seems that MOSI gets pulled down in that CS pulse as well and this is causing the real issue with the transfer. That pulse is so short (0.5us) I had to increase my sample rate to see it.
cs_bug_pulseview2
Here's the python code I used to generate this trace:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import spidev
from time import sleep

#register map
ADNS3080_PRODUCT_ID = 0x00

# SPI setup 
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 500000


while True:
    sleep(0.1)
    pid = spi.xfer2([ADNS3080_PRODUCT_ID, 0x00])[-1]
    print(pid)

From the links above, this issue has existed since at least 2014. Right now I am bit-banging the chip select on another gpio as a workaround but have yet to test all scenarios.

I would be very grateful if you could look into this.

Thanks

Hey @eelcogg

See: #113

This is a duplicate issue - Hopefully the solution in that issue helps.

Hi, Thanks for the nice lib!

I'm facing the same issue.
image
Is there a roadmap to address this ?
If lines :

if (self->mode & SPI_CS_HIGH) status = read(self->fd, &rxbuf[0], 0);

if (self->mode & SPI_CS_HIGH) status = read(self->fd, &rxbuf[0], 0);

if (self->mode & SPI_CS_HIGH) status = read(self->fd, &rxbuf[0], 0);

are mandatory for some platforms only, could we make them optional without having to recompile, by adding a parameter, or a new version name?

This extra read is now disabled by default and can be re-enabled by settings the read0 flag. Fixed in version 3.6.