I need a Waveshare e-Paper/GoPiGo O/S SPI mutex?

I’ve noticed a pesky issue with the GoPiGo-3 robot and the Waveshare e-Paper displays when running GoPiGo O/S:  After updating the display, the robot goes brain-dead and won’t respond to commands or do anything.

Noted facts based on viewing schematics and monitoring pins with an oscilloscope:

  1. The Waveshare devices use SPI device 1, (CS_0 pulled low), and is currently configured for “4-wire” SPI, (i.e. it uses the CS pin to communicate).

  2. When the Waveshare demo is running and it’s updating the display, the SPI CS_0 is being asserted cyclically almost continuously for about a minute or two while the display is updated to show a number of different display modes and features.

  3. The GoPiGo robot uses SPI device 2, (CS_1 pulled low), and also appears to be configured for “4-wire” SPI too.

  4. The GoPiGo’s raspberry pi communicates with the controller board in one of two specific situations:

    • If a command is issued for the robot to do something.  This is noted because any time I do something, there’s a short CS blip on the GoPiGo’s chip select line.

    • Once every few seconds if nothing else is happening.  This command is a relatively long command-string requiring multiple SPI cycles (chip select assertions), that last for a as much as half a second.

  5. Because they use separate SPI channels, there shouldn’t be any conflict between them because they’re responding to different chip-select lines.

Viewing this with one of my el-cheapo 'scopes, I think I have found the problem:

It appears that the two signals are not mutually exclusive, being implemented by plain-vanilla GPIO pins being controlled independently by different programs that don’t communicate with each other - and there is no hardware arbitration.  In other words, it is possible, (and perhaps even likely), that the two communication sessions can overlap since it appears that neither the GoPiGo, nor the Waveshare display, check to see if anyone else is using the SPI buss.

  • At least I know the Waveshare device doesn’t check as there is no logic for reading the state of the second chip-select pin when signalling.

What I suspect is happening is that, while the Waveshare display driver is communicating with the e-Paper display, the GoPiGo attempts to use the SPI buss too - and gets corrupted data causing it to go brain-dead - requiring a power-cycle to reset it.

This is going to require further exploration and a non-trivial amount of programming to research.  Solving the problem will also require a non-trivial amount of programming so that the two devices can monitor each other’s state.  Or, just maybe, I can ask the GoPiGo libraries to assert, (pull low), the Waveshare device’s “Paper Busy” pin and see if that solves the problem?

Then again, I can simply punt and use one of the two Adafruit Raspberry Pi display modules that use i2c communication on what appears to be an unused address.


I was not aware that the GoPiGo3 does the proper “both pins” SPI chip select.

Pin24:GPIO 8 (SPI_CE0) shows not connected on the GoPiGo3 v3.2.0 schematic.

So you would have to modify the GoPiGo3 API and the other peripheral API with your “spi_mutex”. GoPiGo3 I2C_tools allows creating a custom mutex with the “with spi_mutex” and release taken care for you, but I don’t recall the GoPiGo3 API using an SPI mutex, only the EasyGoPiGo3 I2C access is mutex protected if my memory is not fried by RF yet.

(BTW, the radio build works…no magic smoke, 4-5W on all bands transmit. One band I have poor received image rejection that needs debugging, all other bands -36 to -46db down. Only one cold solder joint - on a push button so it was real easy to find.)


That is exactly correct.

The BIG issue is that the SPI interface as envisioned by Motorola back in the 70’s and used by Motorola’s 68000 processor family, was - in essence - yet another point-to-point serial protocol between two or more devices.  I don’t remember if the original SPI spec even implemented the chip-select feature.

The original design deliberately left the details of the actual communication protocol up to the designer instead of being explicitly specified as was done in other inter-chip protocols of the day.

More modern SPI devices have, (somewhat), standardized the communication protocol, but it still leaves much up to the designer’s interpretation and implementation.

“Modern” SPI can exist in one of two forms:

  • “3-wire” SPI which has a TX, RX, and clock line - and primarily assumes that there is only one listening device.
  • “4-wire” SPI which is the same as 3-wire SPI except that it includes an “enable”, (chip-select), line where the device only listens if “enabled”, (CS is pulled low)

The big problem is there is no provision for monitoring other enable/chip-select lines - again assuming that there is only one device on the SPI buss at one time unless explicitly programmed differently.

It should be noted that the existing SPI protocol could, theoretically, use an address-based communication protocol, but doesn’t.


The second big problem is that there is no central SPI handler - all SPI communication is “bit-banged” by the associated libraries.

In other words, there’s nothing that prevents library “A” from initiating communication and pulling its associated CS line low if library “B” is already using the SPI buss for itself.


The biggest problem is that the various devices and vendors, (including Dexter Industries/Modular Robotics), make the assumption that their device is, and will always be, the single and only SPI device that can possibly exist in the entire universe.

Not only that, but the most restrictive configuration, (4-wire SPI), doesn’t consider the state of any other SPI chip-select pins that might be available and since an address-based protocol isn’t used, the chances of multiple device collisions are very high if multiple SPI devices are used.

IMHO, this represents “sloppiness” at its finest.  Especially since NOBODY ever states formally that the device reserves the SPI buss for its own exclusive use.

There are two possible solutions:

  1. Implement a separate “SPI” interface routine that everyone must use that’s responsible for ensuring atomic communication.

  2. Programmatically force each individual API to monitor the other chip-select lines and/or, (somehow or other), implement a mutex of sorts.  AFAIK, the simplest way to implement a mutex would be to take a leaf from the APT/DPKG book and implement a lock-file, perhaps somewhere in the user’s home directory or somewhere else common that’s world-writable.

Actually, the correct solution would be to modify the SPI master specification to be more polite. :wink:

What say ye?


Is this a hardware or software radio implementation?


It is an impressive hardware augmented software radio. Six individual band pass and corresponding low pass circuits with transmit signal shaping, and software controlled synthesized transmit VFOs. Even the switching power supplies are variable frequency under software control (to never be a harmonic of the current receive frequency).

The design is absolutely amazingly detailed by a mega-brilliant guy named Hans Summers, who now lives in Turkey.

The QRP-Labs QMX 5-band CW and Digital Modes 5 watt radio
The (pdf) Schematic for my radio

1 Like