1

I am using the pigpio Python module's SPI functionality as a master (communicating with an external SPI slave). In the same Python script I'm also using my own bit-banged SPI driver on the same pins (Broadcom 8, 10, and 11) with RPi.GPIO, but not at the same time of course.

Most of the time, my Python script runs fine and I see the expected SPI signals on the scope. However sometimes on a consecutive run of my script I see that pigpio's SPI method spi_write() doesn't generate a chip-select on CE0 (Broadcom 8) any longer.

My main Python script runs a bunch of unittest test cases against my SPI slave, and sometimes the tests do fail because the slave is not behaving correctly - this is expected. I suspect that one of these failures is leaving pigpio in a state where it can no longer control the CE0 pin on the next run. I can't quite nail down what the failure is. (I am doing a pi.spi_close(handle) in my tearDown() method.)

The behaviour I expect is this:

import pigpio
pi = pigpio.pi()
handle = pi.spi_open(0, 32000, 0)

After this, I expect gpio readall to show that CE0 is ALT0. And normally it is ALT0. However when things have gone awry (CE0 isn't toggling on the scope anymore when I run my test cases) `gpio readall' shows that CE0 is OUT. When I execute the 3 lines of Python shown above in an interactive session, CE0 doesn't change to ALT0 after the open like it did before.

Is there some type of cleanup or close operation that I'm missing here? Is there some state that RPi.GPIO can leave the GPIO pins in if it's not cleaned up properly during a tearDown(), one that prevents pigpio from working again?

1

The following is what is intended to happen. If it doesn't it indicates a bug.

When you first call spi_open() the modes of CE0, CE1, MISO, MOSI, and SCLK are saved. MISO, MOSI, and SCLK are then set to mode ALT_0. Unless you have opted to control CE0/CE1 yourself (by setting bits in spi_flags) they are also set to mode ALT_0.

The modes are unchanged during any subsequent spi_read(), spi_write(), or spi_xfer() calls.

When you call spi_close() for the last nested SPI open the GPIO are restored to their saved modes. The next spi_open() is then treated as the first again.

pigpio will not notice if you have changed the mode after it has set them in the spi_open().

The above description was for the main SPI device. The auxiliary SPI device is handled in the same way.

  • That makes sense, and is what I normally see. I will try to get a simplified version of my script that reproduces the issue, and will post it here. – Rich Dec 13 '16 at 14:52
  • Some more information, in case it's helpful: When things stop working, I can get my script to successfully run by first manually setting the modes to ALT0 using pigs. Then my script will run once, but not a second time. I can repeat this. Also, when things have stopped working, I can get it going again by killing and restarting pigpiod. When I do this, my script will run over and over successfully. – Rich Dec 13 '16 at 15:18
  • That does sound wrong. If you can find a small script which reproduces the behaviour I will be grateful. – joan Dec 13 '16 at 16:18
  • I've been trying all morning to create a small script that reproduces the issue, but I'm not having any luck so far. What I can say is that interrupting my script with Ctrl-C does cause the problem to happen. Unfortunately it's not repeatable and only happens about 1 in 20 tries. I discovered that I'm not calling pi.stop() in my tearDown() method, which I realise is wrong. I will fix that later (unless of course you tell me Aha! that's the problem). – Rich Dec 13 '16 at 18:42
  • Missing pi.stop() shouldn't cause a problem. Not doing spi_close() would mean that you'd run out of handles and a subsequent spi_open() would fail, but that would normally give a fatal error unless you have switched off error handling. – joan Dec 13 '16 at 19:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.