dotnet / iot

This repo includes .NET Core implementations for various IoT boards, chips, displays and PCBs.
MIT License
2.17k stars 585 forks source link

Clarify board support #1176

Open raghur opened 4 years ago

raghur commented 4 years ago

Describe the bug

At the moment, it isnt clear from the README what versions of Raspberry PI are supported. The driver files indicate Pi3 and above but it isn't clear. It looks like on PI2, it should be able to use libgpiod or sysfs but that isn't clear. If that's indeed the case, then maybe clarify the build process (for ex. right now, I'm compiling on my desktop for linux-arm. If I have to rely on libgpiod-dev, then does that mean that cross compiling is ruled out and I have to build on the RPi?

For context: I'm trying to connect to a NRF24L01 on a Rpi2 B+. As of now, my code compiles and seems to be failing silently (no errors, but no pin ops are working)

Expected behavior

  1. README or Docs clearly list out supported boards.
  2. Should native libraries be required, then clarify if cross compiling is still an option.
  3. A sample project would be terrific.

Describe what did you expect to happen

Actual behavior

Unable to find if a Rpi2 is actually supported or not. Linux drivers folder only says Rpi3 and above in code comments.

Detection behavior in GpioController.cs seems to only checks for BCM2385 in /proc/cpuinfo which from this page https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md says that all PIs will report BCM2385

image

Versions used

Add following information:

Runtime Environment: OS Name: neon OS Version: 20.04 OS Platform: Linux RID: linux-x64 Base Path: /usr/share/dotnet/sdk/3.1.401/


- `dotnet --info` on the machine where app is being run (not applicable for self-contained apps)
using self-contained apps

- Version of `System.Device.Gpio` package
`nuget System.Device.Gpio 1.1.0-prerelease.20276.1 prerelease`
pgrawehr commented 4 years ago

Related: #1145 The board detection is currently broken.

Would it be possible for you to test whether the Pi3 driver works on the Pi2 if you explicitly load it?

raghur commented 4 years ago

I tried with explicit loading - doesn't seem to make a difference

let Connect packetSize (radio:RadioConfig) (cancellationToken:CancellationToken) =
        task {
            try
            let gpioDriver = new RaspberryPi3Driver()
            let controller = new GpioController(PinNumberingScheme.Logical, gpioDriver);
            let settings = SpiConnectionSettings(radio.SpiBusId, 0)
            settings.ClockFrequency <- Nrf24l01.SpiClockFrequency
            settings.Mode <- Nrf24l01.SpiMode
            let device = SpiDevice.Create(settings);
            let nrf = new Nrf24l01(device, radio.ChipEnable, radio.Irq, packetSize, 46uy, OutputPower.N00dBm, DataRate.Rate250Kbps,
                                        PinNumberingScheme.Logical, controller)
            radio.RxPipeBytes |> Option.map (fun v ->
                                                nrf.Pipe0.Address <- v
                                                printfn "Set rx address %A" v
                                            ) |> ignore
            nrf.Channel <- 46uy
            nrf.DataReceived.Add (recieveHandler radio nrf)
            Thread.Sleep(2000)
            printRadioDetails nrf
            // more code - not relevant.

No exception thrown but when I read values off the chip, I get only defaults/unset values. Python code with the same connections works - so I know that this isn't a jiggly wire.

pgrawehr commented 4 years ago

That's weird, looks more like a problem with the SpiDevice. This typically happens when the CS line is not properly set (there are some conceptual problems with the use of it and whether it is explicitly controlled or implicitly by the spi driver). Assuming the radio is the only attached device, can you try hardwiring the CS line to ground (or 3.3V, not sure what this device needs) with something like an 1k resistor?

raghur commented 4 years ago

Hmm - I switched to a RPi 4 with the same pin connections the radio responds to commands - so doesn't that rule out any pin problems?

Oh - and I should have stated this before - but somehow missed it - even on the RPi2, my python version based on pyNRF ( https://github.com/nRF24/RF24) has been working for many months... so that definitely rules out hw issues.

pgrawehr commented 4 years ago

The problem I mention above is not directly a HW issue, but one about how the SPI driver is being used. But since switching to a PI4 works fine, this looks really more like a problem of the implementation. I don't know why the SPI access should be different between an PI2 and a PI4. Maybe this requires a different driver usage or something.

krwq commented 4 years ago

I think what should come out of this issue is some kind of doc explaining on what's supported and that's not a simple answer of "we support it" or "not supported".

But to give some answer here. There are couple of levels of what's supported and what's not: Iot.Device.Bindings to the most part (with exception of few bindings) is not depending on any OS or board. As long as you pass in I2cDevice/SpiDevice/GpioController/PwmChannel the device should just work. I.e. if you use Ft4222 almost whole Iot.Device.Bindings will work on any Linux/Windows/OSX (minus PWM channel which you can get by connecting a specific I2C device which exposes PwmChannels so technically you can get anything to work with that one dongle)

There are two pieces of System.Device.Gpio which are unfortunately put in one place (see: https://github.com/dotnet/iot/issues/1182):

Now let's expand on the implementations in System.Device.Gpio or GPIO specifically (I2C/SPI are relatively painless):

By default you will get auto-detection logic which will pick the best driver implementation for your board - the problem is this logic hard to get right so we've had many issues with that and still have some and the most reliable way is to actually use driver directly (but then you might be limited to building for a specific board)