SPI, more SPI, and even MORE SPI?

I have noticed a lot of fun interesting things have become available for the Raspberry Pi and they could be particularly interesting for robots like the GoPiGo.

Issue:
They all use SPI instead of i2c.

Though SPI has the capability of supporting multiple devices, the primary implementation paradigm has been “one master and one slave”.

Even if the physical hardware supports one or more “select” inputs, the application software usually doesn’t implement a chip-select and the result is a totally schiz robot that can’t tell itself from a can of baked beans.

Or, if it does, it uses the first chip-select pin, alone, just like a dozen other devices.  Result:  A totally schiz robot again.

I verified that a while back when I tried to attach a Velleman touchscreen display to Charlie by plugging it into Charlie’s GPIO header.  The results were NOT pretty and I ended up having to rebuild Charlie’s system image from scratch.

This is annoying.

Based on the GoPiGo’s schematic, one chip-select for SPI is implemented - pin 26.  The second chip-select, (pin 24), is unused and not internally connected.

@cleoqc,
Though pin 26 is connected, can you confirm if it is actually used to address SPI on the red board?

I am assuming that connecting additional SPI devices to the GoPiGo is a bad idea.  Can you confirm or deny this?  Have you tried to connect additional SPI devices to the GoPiGo?

2 Likes

The GoPiGo3 software uses the Python SPIdev module with address 0, device 1 to communicate with the red board, and the “no chip select” option is not set.

Does knowing it does use bus 0 device 1 with only one CS wired allow for interoperability with another SPI device if that device can be set to use both CS as a different bus or device?

2 Likes

. . . Or possibly if it can be set to use

  • The other CS pin
  • Or use !CS to select itself.

I’d prefer the other pin, but a one-of-for decoder, with it’s own “latch” input, would be infinitely better.

The big problem is, assume a device is configured to use both CS pins low, (device 3), it would still select the GoPiGo board at the same time.  There would have to be a huge hardware change to allow a one-of-four decoder to be used - and nobody wants to take the trouble and/or spend the money.

1 Like

Right - can’t use that dev period.

The “only decode the low bit chip select” has been prevalent in the industry forever, but it seems not allowing users to set CS or !CS is also acceptable cost-saving practice.

Why do people even bother to design busses knowing the industry will cheat using them?

2 Likes

Why do cars have gas pedals knowing that people will cheat using them?

Part of it, (IMHO), is that “money talks, B.S. walks!”

You can, literally, make a Raspberry Pi do virtually anything.  Like the guys who went out and bought an entire S-Load of either Nintendo or Sega consoles, (I forget which), and for less than a couple of hundred grand had the fifth most powerful super computer for a while.

You can do anything you want, but the quid you pay for that pro-quo is you own the software and the software doesn’t exist until you write it.

Viz.:
PiFox. Bare-metal video game on Pi-1

Most people, us included, want everyone else to write the code.

Then we want all the features.

It’s annoying, but we want it fast and cheap.

Me, I want to see the firmware source code for the GoPiGo-3!

1 Like

Not me. I’m quite happy treating the red board as a black box with a very well defined API:

  SPI_MESSAGE_TYPE = Enumeration("""
        NONE,
        GET_MANUFACTURER,
        GET_NAME,
        GET_HARDWARE_VERSION,
        GET_FIRMWARE_VERSION,
        GET_ID,
        SET_LED,
        GET_VOLTAGE_5V,
        GET_VOLTAGE_VCC,
        SET_SERVO,
        SET_MOTOR_PWM,
        SET_MOTOR_POSITION,
        SET_MOTOR_POSITION_KP,
        SET_MOTOR_POSITION_KD,
        SET_MOTOR_DPS,
        SET_MOTOR_LIMITS,
        OFFSET_MOTOR_ENCODER,
        GET_MOTOR_ENCODER_LEFT,
        GET_MOTOR_ENCODER_RIGHT,
        GET_MOTOR_STATUS_LEFT,
        GET_MOTOR_STATUS_RIGHT,
        SET_GROVE_TYPE,
        SET_GROVE_MODE,
        SET_GROVE_STATE,
        SET_GROVE_PWM_DUTY,
        SET_GROVE_PWM_FREQUENCY,
        GET_GROVE_VALUE_1,
        GET_GROVE_VALUE_2,
        GET_GROVE_STATE_1_1,
        GET_GROVE_STATE_1_2,
        GET_GROVE_STATE_2_1,
        GET_GROVE_STATE_2_2,
        GET_GROVE_VOLTAGE_1_1,
        GET_GROVE_VOLTAGE_1_2,
        GET_GROVE_VOLTAGE_2_1,
        GET_GROVE_VOLTAGE_2_2,
        GET_GROVE_ANALOG_1_1,
        GET_GROVE_ANALOG_1_2,
        GET_GROVE_ANALOG_2_1,
        GET_GROVE_ANALOG_2_2,
        START_GROVE_I2C_1,
        START_GROVE_I2C_2,
    """)

and increasing my skill at using that functionality. It is true that I might understand more about a few of those functions if I had access to the firmware AND invested to learn about programming controllers, but I need to fight against my desire to understand everything in the universe at the quantum level. I need to keep my focus on immediately usable (for Dave) learning.

2 Likes

Oooh!

I stand corrected.

I thought the method was to get the “battery” voltage.  I was wrong - it IS “get the VCC voltage”.

My bad.

Solution:  Add 0.60 to the battery reading on the control panel.

1 Like

Me?

I’m a nut.

Now that I have a half-tushed 'scope, I want to see if the adjacent, unused, pin on the red board’s microcontroller is the other CS pin.

If it is, some #30 kynar and a couple of resistors later, I have both CS pins active!

Won’t be the first time either.

2 Likes

Yes, the red board SPI function is hardware VCC, but to GoPiGo3 users there are only the two exposed software methods:

gopigo3.GoPiGo3().get_voltage_battery()

def get_voltage_battery(self):
        """
        Get the battery voltage
        Returns touple:
        battery voltage, error
        """
        value = self.spi_read_16(self.SPI_MESSAGE_TYPE.GET_VOLTAGE_VCC)
        return (value / 1000.0)

easygopigo3.EasyGoPiGo3().volt()


    def volt(self):
        """
        This method returns the battery voltage of the `GoPiGo3`_.
        :return: The battery voltage of the `GoPiGo3`_.
        :rtype: float
        """
        voltage = self.get_voltage_battery()
        return voltage

Both of which lie about the battery voltage by 0.6v or so.

2 Likes

Are you sure?

I ran into an issue testing GPGOS awhile back where “SPIdev” was throwing errors all over the place because a startup script asked for it, and it wasn’t installed.

Ultimately the solution was to remove the startup reference to “SPIdev”, since there was a SPI package already installed.

Nicole confirmed that the reference to SPIdev was a development artifact and should not be there.

I will have to research this as I am not on my main machine and I think this was a “support@modrobotics” thing.  (And this is why I despise “back-channel” support, there is ZERO visibility to anyone else.)

1 Like

gopigo3.py:

try:
    import spidev
    import fcntl      # for lockf mutex support
except:
    hardware_connected = False
    print ("Can't import spidev or fcntl")

...
if hardware_connected:
    GPG_SPI = spidev.SpiDev()
    GPG_SPI.open(0, 1)
    GPG_SPI.max_speed_hz = 500000
    GPG_SPI.mode = 0b00
    GPG_SPI.bits_per_word = 8

BTW the SPI address is 8. Supposedly you can have daisy chained SPI devices sharing the same chip select and they suck off packets with their address. I don’t think the red board supports daisy chained SPI even though it does set an address.

2 Likes

Update:

It was in a PM.

Viz.:

Ergo:
SPIdev should NOT exist in GPGOS.

Hold up a second. . .
Are we talking about two different things?

SPI-dev in the kernel and a different SPIdev in Python?

Strange.

1 Like

Yes - the only thing I know about kernel and spi is the param in /boot/config.txt:

dtparam=spi=on

Never heard of spi-dev, but I keep the whole concept of the Linux kernel, and that even more obscure thing the Broadcom firmware, as the other black boxes for other people to worry about.

When I mentioned back dating the kernel to fix the garbled sound, it may have actually been the Broadcom firmware I had to back date - I just don’t remember, but now when I try something and hear garbled text-to-speech, I back out the update and clamp down the system with multiple backups.

2 Likes

Yup.

I’m glad there’s someone around here that knows what’s going on!
:wink:

2 Likes

I like that dream.

“Neurotics build castles in the air. Psychotics move in.”

2 Likes

And here I am looking for another layer of abstraction over that. :slight_smile:
/K

2 Likes

That abstraction layer is called “magic”.
:wink:

2 Likes

Ah yes, ROS - the “Robot Obfuscation System” we are looking to for enlightened robots.

Have you solved how to make bootable hot backups of Finmark?

I can shut down Dave and dd a backup on my Mac, but would like to not have to unplug and reinsert that SDcard.

Carl has this neat program “rpi-clone” that he uses to make bootable hot backups of Raspbian For Robots (or PiOS), but so far I haven’t had success on Dave cloning Ubuntu 20.04.

Update: Looks like the secret is to flash the target backup card first with Ubuntu 20.04, then rpi-clone to the target.

2 Likes

Current Raspberry Pi design allows you to set special “bit flags” on the board to select boot priority and fail-over policy if booting from a particular device fails.

(AFAIK) The default setting is to give boot priority to the SD card and fail-over to USB if a SD card is not there.

I believe you can set it to give boot priority to USB, and fail-over to the SD card.

You can load up a R4R image on a small thumb-drive and insert that when you want to make a backup.

Or, you can place a small partition on the SD card itself and jumper select booting to the “backup” OS the way I do.

I deliberately moved to a larger SSD, USB booting, and the ability to multi-boot different operating systems to avoid just that problem.

. . . . That is, after I split a fifth SD card in half that contained an irreplaceable image of Charlie’s OS while trying to swap SD cards!

Needless to say, it cost me about $70 each for several SSD drives, (not to mention the window next to me after I melted it swearing a blue streak!)

However, I now have a method for making fully restorable images of any OS on the drive and I don’t have to mess with fussy little micro-SD cards!

2 Likes

True enlightenment is not found in complexity, but in elegant simplicity.

Me.
The Tao of GoPiGo

2 Likes