0

I am using a Linux board called NanoPi Neo based on the H3 chipset. I got the spidev driver working and it appears as /dev/spidev0.0

I am trying to use a SPI module called RF24L01. However, I was not able to read the register values properly. So I hooked up a logic analyzer and found strange peaks in the clock signal which are not supposed to be there.

The SPI is configured as follows

Bits: 8 Speed: 5kHz Mode: 0 (CPOL=0, CPHA=0)

How can I fix this? Kernel version is 4.14 ($uname -r) enter image description here

I have used different spidev based programs for SPI and all their waveforms exhibit this behaviour. I think there is something in the driver which is causing this weird behaviour. Can anyone point me in a direction?

This is the code using spidev driver

#include "spi.h"    
#include <fcntl.h>
#include <linux/spi/spidev.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>

#define RF24_SPIDEV_BITS 8

SPI::SPI():fd(-1) {
}

void SPI::begin(int busNo){

    /* set spidev accordingly to busNo like:
     * busNo = 23 -> /dev/spidev2.3
     *
     * a bit messy but simple
     * */
    char device[] = "/dev/spidev0.0";
    device[11] += (busNo / 10) % 10;
    device[13] += busNo % 10;

    if (this->fd < 0)  // check whether spi is already open
    {
      this->fd = open(device, O_RDWR);

      if (this->fd < 0)
      {
        perror("can't open device");
        abort();
      }
    }

    init();
}

void SPI::init()
{
    uint8_t bits = RF24_SPIDEV_BITS;
    uint32_t speed = RF24_SPIDEV_SPEED;
    uint8_t mode = SPI_MODE_0;

    int ret;
    /*
     * spi mode
     */
    ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode);
    if (ret == -1)
    {
        perror("can't set spi mode");
        abort();
    }

    ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode);
    if (ret == -1)
    {
        perror("can't set spi mode");
        abort();
    }

    /*
     * bits per word
     */
    ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1)
    {
        perror("can't set bits per word");
        abort();
    }

    ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    if (ret == -1)
    {
        perror("can't set bits per word");
        abort();
    }
    /*
     * max speed hz
     */
    ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    if (ret == -1)
    {
        perror("can't set max speed hz");
        abort();
    }

    ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
    if (ret == -1)
    {
        perror("can't set max speed hz");
        abort();
    }
}

uint8_t SPI::transfer(uint8_t tx)
{
    struct spi_ioc_transfer tr;
    memset(&tr, 0, sizeof(tr));
    tr.tx_buf = (unsigned long)&tx;
    uint8_t rx;
    tr.rx_buf = (unsigned long)&rx;
    tr.len = sizeof(tx);
    tr.speed_hz = RF24_SPIDEV_SPEED;
    tr.delay_usecs = 0;
    tr.bits_per_word = RF24_SPIDEV_BITS;
    tr.cs_change = 0;

    int ret;
    ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
    {
        perror("can't send spi message");
        abort();
    }

    return rx;
}

void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
{
    struct spi_ioc_transfer tr;
    memset(&tr, 0, sizeof(tr));
    tr.tx_buf = (unsigned long)tbuf;
    tr.rx_buf = (unsigned long)rbuf;
    tr.len = len;
    tr.speed_hz = RF24_SPIDEV_SPEED;
    tr.delay_usecs = 0;
    tr.bits_per_word = RF24_SPIDEV_BITS;
    tr.cs_change = 0;

    int ret;
    ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
    {
        perror("can't send spi message");
        abort();
    }
}

SPI::~SPI() {
    if (!(this->fd < 0))
        close(this->fd);
}
2
  • I have not heard of any such behaviour. I suggest it is down to incorrect use of the software or possibly poor wiring.
    – joan
    Jan 5, 2018 at 9:20
  • I've tried with two different modules and checked wiring. When I try with SPI Mode 3 or 2 (CPOL = 1) the waveform is perfect. But my module only supports SPI Mode 0, so I am stuck here. Also, I tested kernel 4.10.0, 4.11.0, 4.11.2, 4.14.0 and the behaviour is same! For RF24 SPI i am using the library here github.com/nRF24/RF24
    – azmath
    Jan 5, 2018 at 12:43

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.