Skip to content

Problems with SPI when migrating from Pi4j 1.4 to Pi4j 2.8 #751

Description

@avisecag

We have an older project that we are migrating from 1.4 (wiringPi) to 2.8 (using pigpio). The reason why we're migrating to that is because we need backwards compatibility with buster, which a couple 100 devices deployed to the field still employ.

In any case, I got most things working, but I am running into an issue with the SPI.
The first issue is initialisation. On 1.4, this used to look like this:

                spi = SpiFactory.getInstance(
                    SpiChannel.CS0,
                    1000,  // default spi speed 100 KHz
                    SpiDevice.DEFAULT_SPI_MODE
                )

I think the speed was actually configured wrong here and never had any effect, but the thing was working perfectly fine like this.

During the migration, I replaced that block with this:

                val spiConf = Spi.newConfigBuilder(pi4jContext)
                    .id("SPI${bus}_atmega ")
                    .bus(SpiBus.BUS_0)
                    // TODO: Find a way around addressing conflict when usind CS_0
                    .chipSelect(SpiChipSelect.CS_0)
                    .mode(SpiMode.MODE_0)
                    .provider(pi4jSpiProvider)
                    .build()

                spi = pi4jContext.create(spiConf)

This causes a conflict with a GPIO that's addressed on BCM 0. I have a few suspicions why this might be causing an issue with the new addressing system, but at the end of the day, I need a solution that allows me to initialize the SPI the way it was before while also using that pin on BCM 0. We can't afford to go out and rewire. If it worked before, there must be a way to get it to work again.

Meanwhile I have temporarily disabled the pin on BCM 0 to test the SPI functionality, and there I am running into another problem.
The data exchange on 1.4 looked very simple:

        if (spiLock.tryLock(1000, TimeUnit.MILLISECONDS)) {
            spiResult = spi.write(bytes, 0, bytes.size)
            spiLock.unlock()
        } else throw Exception("Could not get lock on SPI")

This is followed by some code that reads the response. I thought this should be easily enough replaceable with transfer():

        try {
            if (spiLock.tryLock(1000, TimeUnit.MILLISECONDS)) {
                spiResult = ByteArray(bytes.size)
                val status = spi.transfer(bytes, spiResult)
                log.info("datareceived: {}", spiResult)
                if (status != 0) throw RuntimeException("Error while writing to SPI: transfer returned with value $status")
            } else throw Exception("Could not get lock on SPI")
        } finally {
            spiLock.unlock()
        }

Unfortunately, that isn't working either, in more than one way. First of all, the status I'm getting back from spi.transfer is not what I expected from the documentation. According to the docs:

@return Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.

And while there is no further information on what those values are exactly, I have to assume they are equivalent to these: https://github.com/guymcswain/pigpio-client/blob/master/lib/errorcodes.txt

What I'm getting back meanwhile is a positive value that suspiciously corresponds to the length of my write buffer. So I think there's at least some wrong documentation here.
Meanwhile, that is not my main problem. My main problem is that nothing is ever written to the response buffer. It is always filled with zeroes, though I am expecting 2 bytes in response. Again, this worked without issues with the 1.4 code, and so far I have not found any way to reproduce that behaviour, whether by using transfer nor by attempting to do the write/reads myself. It may well be that this is a secondary issue from something I'm doing wrong in initialization, I have no way of knowing. All I know is that I don't have much left to try and even fewer hope that any of it will work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions