[riot-notifications] [RIOT-OS/RIOT] cpu/native: Allow Access to Hardware SPI Bus on Linux (#11352)

Frank Hessel notifications at github.com
Sun Apr 7 21:48:31 CEST 2019


### Contribution description

**Motivation:** For my thesis, I need to be able to run the same code on a testbed consisting of microcontrollers as well as SoC platforms like the Raspberry Pi (not on bare metal but as process in Linux userspace, so I'll use the _native_ cpu in RIOT).

**Problem:** The _native_ cpu/board cannot make use of the underlying hardware, even if the CPU does support peripherals like SPI.

**Suggested Solution:** I wrote a wrapper around the Linux userspace SPI API that allows to map the devices from `/dev/spidevB.D` to SPI devices in RIOT. Basically, these device files represent SPI busses, where the first number (B) represents the bus itself, and the second number (D) represents the connected device / hardware CS line. If the RIOT application is compiled for Linux with the `PERIPH_SPI` feature being required, it will provide the `--spi` command line parameter, which can be used to dynamically map those device files to the application. For example, calling:

```bash
./my-application --spi=0:0:/dev/spidev0.0 --spi=0:1:/dev/spidev0.1
```

... will allow to use `SPI_DEV(0)` in RIOT with either `SPI_HWCS(0)` or `SPI_HWCS(1)`. Using arbitrary lines for CS isn't possible until _native_ also has access to GPIOs (related PRs #1737 or #7530 seem to be stuck, and #8048 is more or less raspi-only and also possibly outdated).

In addition to my use case, I think that SPI access under _native_ might as well become handy for development and debugging on device drivers.

### Testing procedure

**Board:** _Native_ CPU/Board on a Linux-based SoC with hardware SPI. I used a Raspberry Pi, where the pinout for Rev. 2 and 3 would be: [more details](https://pinout.xyz/#)

| Function | Pin (physical) | Device File    |
| -------- | -------------- | ------------ |
| MOSI     | 19             | both           |
| MISO     | 21             | both           |
| SCLK     | 23             | both           |
| CE0      | 24             | /dev/spidev0.0 |
| CE1      | 26             | /dev/spidev0.1 |

This means we have one physical bus with two hardware-based CS lines.

#### Loopback test
The easiest way would be a loopback test with the [periph_spi test](https://github.com/RIOT-OS/RIOT/tree/master/tests/periph_spi), as it does not require any additional hardware. For the Raspberry Pi, one would connect MISO and MOSI with each other. Then, in the periph_spi directory:

```bash
BOARD=native make all
./bin/native/tests_periph_spi.elf --spi=0:0:/dev/spidev0.0  --spi=0:1:/dev/spidev0.1
```

And in the application's shell:

```
init 0 0 2 -1 0
send test
```

... or `init 0 0 2 -1 1` for the seconds CS line.

This should output something like this:

```
> send test
send test
Sent bytes
   0    1    2    3 
  0x74 0x65 0x73 0x74
    t    e    s    t 

Received bytes
   0    1    2    3 
  0x74 0x65 0x73 0x74
    t    e    s    t 
```

#### Further Testing
Any further tests, especially with real SPI hardware, are a bit complicated as most drivers also require GPIO functionality in addition to SPI (for CS, RST or IRQ lines), which is not supported by now. I did most of my tests with a [LoRa GPS Hat](http://wiki.dragino.com/index.php?title=Lora/GPS_HAT) which provides a SX1276-compatible transceiver. However, the sx127x driver also requires  GPIO, so I ported some of my former code to RIOT. The [code can be found here](https://gist.github.com/fhessel/52aaf5d200e38a0452517740ca3b1308), if that helps testing in any way.

I did the best I could to find errors in the code, but if you have any suggestions how I could verify the implementation more formally, a hint would be appreciated.

#### Other Build Environments
I also used a VM with FreeBSD to verify that the non-Linux build does not break (unless you require `PERIPH_SPI` as feature). However, due to the lack of hardware, I couldn't verify it for macOS right now.

### Issues/PRs references

Besides the aforementioned PRs regarding GPIOs, I did not find any Issues/PRs related to SPI on native.

You can view, comment on, or merge this pull request online at:

  https://github.com/RIOT-OS/RIOT/pull/11352

-- Commit Summary --

  * cpu/native: Implement hardware SPI access (Linux)
  * boards/native Add SPI feature to doc.txt

-- File Changes --

    M boards/native/doc.txt (1)
    M cpu/native/Makefile.features (4)
    M cpu/native/include/periph_conf.h (41)
    M cpu/native/include/periph_cpu.h (42)
    A cpu/native/include/spidev_linux.h (135)
    M cpu/native/periph/pm.c (11)
    A cpu/native/periph/spi.c (284)
    M cpu/native/startup.c (38)

-- Patch Links --

https://github.com/RIOT-OS/RIOT/pull/11352.patch
https://github.com/RIOT-OS/RIOT/pull/11352.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/RIOT-OS/RIOT/pull/11352
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/notifications/attachments/20190407/1df6da31/attachment.html>


More information about the notifications mailing list