Lotharyx
Posts: 7
Joined: Thu Aug 29, 2013 5:00 pm

SPI CS0 Stays Low (Asserted) While Idle

Tue Sep 04, 2018 2:22 pm

Hi,

I'm troubleshooting a failed SPI communication between the RasPi 3 and an external UART. The symptom is that the UART is not responding to anything at all (the MISO line stays high, so all data read by the Pi is 0xFF). At this stage I have not ruled out anything yet, but I did notice something strange about the CS0 line while I was doing some tests.

I am using C++ and the linux kernel spidev driver, along with IOCTL messaging to enable full duplex. I've successfully used the same SPI code to communicate with other devices on other Pis, so that isn't in question (and the pins are mostly wiggling the way they're supposed to). However...

It appears that CS0 idles in an "asserted" (low) state, and is only de-asserted for a brief period prior to the start of a transmission. This doesn't seem correct to me; it's my impression that the CS line should only be asserted during the transmission, and idle in a de-asserted (high) state (see the diagram at https://en.wikipedia.org/wiki/Serial_Pe ... agram2.svg). Since the datasheet for the UART is somewhat poor, I can't rule out that it's failing to respond because of CS being asserted when it shouldn't be.

Is there some configuration option for the Pi that will ensure it de-asserts CS in a timely fashion after a transmission? The docs I've read about spidev talk about a guaranteed minimum time before CS is de-asserted, but nothing about the maximum time (which in this case appears to be infinity). I would expect the CS line to be de-asserted shortly after SCLK is stopped.

Thanks!

Lotharyx
Posts: 7
Joined: Thu Aug 29, 2013 5:00 pm

Re: SPI CS0 Stays Low (Asserted) While Idle

Thu Sep 06, 2018 2:01 am

An update:

I've isolated the communication issue to the bad (IMHO) chip select behavior. The external UART requires a high pulse on chip select to separate commands; otherwise it never reloads its output shift register, and sends the same response byte over and over.

I can work around the problem by using the cs_change and delay_usecs fields on struct spi_ioc_message, but that doesn't change the (mis-) behavior of the CS line idling low instead of high. It's my opinion that CS should be de-asserted shortly after the final SCLK tick, to allow the slave device to tri-state its MISO line and avoid bus contention if there are multiple devices sharing the SPI bus.

Anyway, I suppose this isn't necessarily a RasPi-specific issue at this point, but I would still consider it educational to hear from folks that have greater expertise on SPI and the linux kernel, as to whether the idle-low behavior of CS can be modified (without recompiling the kernel, ideally).

User avatar
joan
Posts: 14887
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: SPI CS0 Stays Low (Asserted) While Idle

Thu Sep 06, 2018 7:21 am

There is probably something wrong with your code. If you are using SPI correctly CS will be de-asserted after the transaction. We need to see the code you are using.

Return to “Interfacing (DSI, CSI, I2C, etc.)”