Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] spi_xfer Currently Fails #19

Open
TheCedarPrince opened this issue Dec 21, 2024 · 2 comments
Open

[BUG] spi_xfer Currently Fails #19

TheCedarPrince opened this issue Dec 21, 2024 · 2 comments

Comments

@TheCedarPrince
Copy link

Hi @Alexander-Barth and co,

Just wanted to report that while #18 did work to open a SPI interface, it now appears I am unable to write with SPI. Here's code in Python (using your tip about checking out the Python library):

import pigpio

pi = pigpio.pi()

SPI_CHANNEL = 0  # SPI channel (0 or 1)
SPI_SPEED = 1000000  # SPI speed in Hz (1 MHz)
SPI_FLAGS = 0  # SPI flags (0 for default)

handle = pi.spi_open(SPI_CHANNEL, SPI_SPEED, SPI_FLAGS)
data_to_send = [0x01, 0x02, 0x03, 0x04]  # Example data
count, data_received = pi.spi_xfer(handle, data_to_send)

And the output

>>> handle
0 # Or 1 -- this is correct to the Julia version

>>> count
4

>>> data_received
bytearray(b'\x00\x00\x00\x00')

Here's the same version in Julia:

julia> using PiGPIO

julia> p = Pi();
[ Info: Successfully connected!

julia> h = PiGPIO.spi_open(p, 1, 100000, 0)
0

julia> data_to_send = [0x01, 0x02, 0x03, 0x04]
4-element Vector{UInt8}:
 0x01
 0x02
 0x03
 0x04


julia> count, data = PiGPIO.spi_xfer(p, h, data_to_send)
ERROR: UndefVarError: `u2i` not defined
Stacktrace:
 [1] spi_xfer(self::Pi, handle::Int32, data::Vector{UInt8})
   @ PiGPIO ~/.julia/packages/PiGPIO/UOeJH/src/spiSerial.jl:199
 [2] top-level scope
   @ REPL[5]:1

I then tried to patch it with the following fix:

julia> function spi_xfer(self::Pi, handle, data)
           # I p1 handle
           # I p2 0
           # I p3 len
           ## extension ##
           # s len data bytes

           # Don't raise exception.  Must release lock.
           bytes = signed(PiGPIO._pigpio_command_ext(
           self.sl, PiGPIO._PI_CMD_SPIX, handle, 0, length(data), data, false))
           if bytes > 0
               data = PiGPIO.rxbuf(bytes)
           else
               data = ""
           end
           unlock(self.sl.l)
           return bytes, data
       end
spi_xfer (generic function with 1 method)

julia> (count, data) = spi_xfer(p, h, data_to_send)
(0, "")

But that doesn't return what the Python version did. Any thoughts about how to fix this @Alexander-Barth or @aviks? I can examine the Python version a bit more, but was curious what your thought is here first.

Cheers!

~ tcp 🌳

@TheCedarPrince TheCedarPrince changed the title [HELP] spi_xfer Currently Fails [BUG] spi_xfer Currently Fails Dec 21, 2024
@Alexander-Barth
Copy link
Contributor

I just made a couple of commits, but I don't think that they address the root issue here.
When you rerun your code with:

ENV["JULIA_DEBUG"] = "PiGPIO"

Can you copy the screen output here? It would be useful to compare them to also some internal calls in pigpio.py (the python functions spi_xfer, _pigpio_command_ext_nolock,...). This, however, would require to change also the python code to some print calls there.

@TheCedarPrince
Copy link
Author

Hey @Alexander-Barth, seems like we are moving a little bit further along! Here is what I am seeing:

julia> ENV["JULIA_DEBUG"] = "PiGPIO"
"PiGPIO"

julia> using PiGPIO

julia> p = Pi()
┌ Debug: _pigpio_command
│   out =
│    16-element Vector{UInt8}:
│     0x63
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
└ @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/pi.jl:111
[ Info: Successfully connected!
Pi("localhost", 8888, true, PiGPIO.SockLock(Sockets.TCPSocket(RawFD(17) open, 0 bytes waiting), ReentrantLock(nothing, 0x00000000, 0x00, Base.GenericCondition{Base.Threads.SpinLock}(Base.IntrusiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), (0, 0, 0))), PiGPIO.CallbackThread(PiGPIO.SockLock(Sockets.TCPSocket(RawFD(17) open, 0 bytes waiting), ReentrantLock(nothing, 0x00000000, 0x00, Base.GenericCondition{Base.Threads.SpinLock}(Base.IntrusiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), (0, 0, 0))), PiGPIO.SockLock(Sockets.TCPSocket(RawFD(18) paused, 0 bytes waiting), ReentrantLock(nothing, 0x00000000, 0x00, Base.GenericCondition{Base.Threads.SpinLock}(Base.IntrusiveLinkedList{Task}(nothing, nothing), Base.Threads.SpinLock(0)), (0, 0, 0))), true, true, 0, 0x00000000, Any[]))
julia> h = PiGPIO.spi_open(p, 0, 100000, 0)
┌ Debug: _pigpio_command_ext
│   out =
│    16-element Vector{UInt8}:
│     0x47
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│        ⋮
│     0x01
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│   ext =
│    20-element Vector{UInt8}:
│     0x47
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│        ⋮
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
└ @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/pi.jl:137
0
julia> data_to_send = [0x01, 0x02, 0x03, 0x04]
4-element Vector{UInt8}:
 0x01
 0x02
 0x03
 0x04

julia> count, data = PiGPIO.spi_xfer(p, h, data_to_send)
┌ Debug: _pigpio_command_ext
│   out =
│    16-element Vector{UInt8}:
│     0x4b
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│        ⋮
│     0x00
│     0x00
│     0x04
│     0x00
│     0x00
│     0x00
│   ext =
│    20-element Vector{UInt8}:
│     0x4b
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│        ⋮
│     0x00
│     0x00
│     0x01
│     0x02
│     0x03
│     0x04
└ @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/pi.jl:137
ERROR: UndefVarError: `readbytes` not defined
Stacktrace:
 [1] rxbuf(self::Pi, count::Int32)
   @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/pi.jl:354
 [2] spi_xfer(self::Pi, handle::Int32, data::Vector{UInt8})
   @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/spiSerial.jl:205
 [3] top-level scope
   @ REPL[8]:1

Here I'll note that it does appear like the ext array does receive the byte data. But I am not sure how to access it. However, I did a small patch to the rxbuf and spi_xfer functions as follows:

julia> function rxbuf(self::Pi, count)
           ext = readbytes!(self.sl.s, count, all)
           return ext
       end
rxbuf (generic function with 1 method)

julia> function spi_xfer(self::Pi, handle, data)
           # I p1 handle
           # I p2 0
           # I p3 len
           ## extension ##
           # s len data bytes

           # Don't raise exception.  Must release lock.
           bytes = PiGPIO.u2i(PiGPIO._pigpio_command_ext(
           self.sl, PiGPIO._PI_CMD_SPIX, handle, 0, length(data), data, false))
           if bytes > 0
               data = rxbuf(self, bytes)
           else
               data = ""
           end
           unlock(self.sl.l)
           return bytes, data
       end
spi_xfer (generic function with 1 method)

julia> (count, data) = spi_xfer(p, 1, data_to_send)
┌ Debug: _pigpio_command_ext
│   out =
│    16-element Vector{UInt8}:
│     0x00
│     0x00
│     0x00
│     0x00
│     0x4b
│     0x00
│        ⋮
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│     0x00
│   ext =
│    20-element Vector{UInt8}:
│     0x4b
│     0x00
│     0x00
│     0x00
│     0x01
│     0x00
│        ⋮
│     0x00
│     0x00
│     0x01
│     0x02
│     0x03
│     0x04
└ @ PiGPIO ~/.julia/packages/PiGPIO/I3q1H/src/pi.jl:137
(0, "")

But it still does not return what the Python code does. I can try a fork of the pigpio python package as well and adding in some debug statements while I tinker if that would be helpful @Alexander-Barth. Otherwise, any other thoughts?

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants