BPI-R2 SPI Communication

Thanks for the update @frank-w I did not tried SPI after that. May I know if you have prebuilt kernel/u-boot to test it out as quick turn around.

TIA

Kernel is on my repo (releases),uboot i can send you but you need a dto matching your hardware. You have to create this and compile. If you need additional driver tell me.

dto matching your hardware

I am going to interface LORA Radio based on SPI communication. Should I need any special driver for to communicate over BPI-R2?. I done the similar interfaces on others boards without any additional drivers.

TIA

Here a compatible “sx1278” is used…have to look which driver is defining that

As far as i see you have to compile the module by youself with referencing your kernel-source (and maybe crosscompiler).

have tried adding source to my repo in folder utils, but facing many build-problems

lora.tar.gz (11,3 KB) build.log (112,1 KB)

seems lora is not compatible with 4.19…

there is a lkml-thread for lora from july 18, but files are not included in 4.19 yet: https://lwn.net/Articles/758774/ Patchset should be this: https://patchwork.ozlabs.org/cover/937545/

u-boot-2019-01-bpi-r2.bin.gz (163,4 KB)

have applied Patches without error to separate branch (not pushed) and tried to compile…

ERROR: "__aeabi_ldivmod" [drivers/net/lora/lora-sx1276.ko] undefined!
ERROR: "__aeabi_uldivmod" [drivers/net/lora/lora-sx1276.ko] undefined!
make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2

have not found this functions in my source-tree, also not in lora-source…i don’t know why this is needed…

https://stackoverflow.com/questions/25623956/aeabi-ldivmod-undefined-when-compiling-kernel-module recommends using div64.h…but where?

Not sure why we want to add LORA component as part of the kernel since the LORA radio will be using generic SPI communication b/w the host. We enabled SPI and started using radio straightaway in RPI boards by this library, I am using this source, https://github.com/CongducPham/LowCostLoRaGw/tree/master/gw_full_latest

This is the another good source, https://github.com/hallard/RadioHead

@frank-w If you confirmed the generic SPI communication is working fine on the updated kernel, then I can give a try with LORA and let us know the outcome.

TIA

I cannot try spi because i have no spi-device here…i had only tried with wired miso/mosi,but testapp is strange (always shows rx…also if circuit is open)

good news…i got lora-driver compiled here: https://github.com/frank-w/BPI-R2-4.14/tree/4.19-lora_new

currently hang on dt-overlay

will upload kernel and module for you to test (you will need also new uboot and have to load nodt-kernel with dtb+dto)…take a look here how to configure uboot:

to flash uboot:

gunzip u-boot-2019-01-bpi-r2.bin.gz
dd of=/dev/mmcblk0 if=u-boot-2019-01-bpi-r2.bin bs=1k seek=320 #for SD-Card

download files from here:

https://drive.google.com/open?id=1jropgAtqSgkV6UTKNv39r_FaRceLPhjV

unpack kernel (change uImage_nodt and dtb to another filename and use it below)+modules to your SD-card and put this in your uEnv.txt (changed to your filenames)

kernel419_nodt=uImage_4.19.20-main_nodt
fdt419=4.19.20-main.dtb
dtolist419=bpi-r2-lora-spi.dtbo

put sx1278.ko to BPI_ROOT/lib/modules/4.19.20-bpi-r2-lora_new/extra/

and select “Boot from SD/EMMC 4.19 (fdt/dto)” from uboot-menu

@asprakash can you please try it out (lora on spi0) with new uboot and overlay?

Hi, I am trying to get SPI working for BPI R2, but I can’t find /dev/spidev. I tried modprobe spidev, but still nothing.

When I lsmod, I can see spidev. Also, there is /sys/class/spi_master/spi0. Directory /sys/class/spidev is empty.

Is there anything else I need to do?

My kernel version Linux version 5.4.27-bpi-r2-main

afair dts needs to modify to use spidev (adding node with your device connected to match driver) and adding driver for your device…imho a generic spidev device cannot be created to operate lowlevel over it…at least nobody had told me a way to do it

you can create a dt overlay but you need to load kernel without DT in uboot, than your devicetree and the overlay(s) and merge them with fdt-command…i had done some basic work in my uboot environment…

Where do I get a driver? Will I need to compile the kernel?

Honestly, it is probably going to be easier to just write a C library. I looked into datasheet and it doesn’t seem to be that hard. At least I have fun for tonight…

When I finish, we can work together and you can create a driver from it and implement it into your repo.

It depends on device you want to connect. Drivers for e.g. some display-controller already in linux source,but you need to compile kernel with the matching driver and change dts to link driver to spi(dev)-node

I would like to enable general SPI interface. I would sort out any device-related things later. There was a misunderstanding.

Have you made some progress? Afair in 5.4 i have not changed anything for spi (not adding spidev node)

I am working on it. It is not as easy as I thought tho. Turns out I need to write my own kernel module in order to allocate memory for buffer, otherwise I won’t be able to get physical memory address from a user space (I don’t really want to use page mapping.) Anyway… I encountered problems during build. I had to download linux headers and then I couldn’t build scripts. I sorted it out by commenting some lines in scripts/Makefile. Then there was a problem with not building a scripts/mod folder during make scripts… I got that all sorted out and now I am able to build my own kernel module.

I think I finished writing the logic for SPI itself, now I need to test it. I also need to sort out bad documentation for SPI clock speed. Maybe some of you can help? https://electronics.stackexchange.com/questions/536609/how-to-set-spi-clock-speed-for-mt7623n

I wanted to try SPI communication between arduino and RPI Zero first, but I just could not make it work. I have some stepdowns to 3.3V, but they are not fast enough and it does not work even without them (with 5V on Gpio :frowning:) So before I can try to test it, I need to sort out the clock speed issue and then sort out how can I actually test it, because the RPI and BPI are both masters-only. Any ideas?

I simply could have tried to make spidev work, but this is more fun.

Hi all,

I made some corrections in 5.4 (source from https://github.com/frank-w/BPI-R2-4.14) in the hope it may be useful for you!

mt7623n-bananapi-bpi-r2.dts:

&spi0 {
    pinctrl-names = "default";
    pinctrl-0 = <&spi0_pins_a>;
    status = "okay";
    spidev: spidev@0 {
        compatible = "linux,spidev";
        spi-max-frequency = <1000000>;
        reg = <0>;
    };
};

spidev.c:

static struct class *spidev_class;

#ifdef CONFIG_OF
    static const struct of_device_id spidev_dt_ids[] = {
        { .compatible = "linux,spidev" },

spi-mt65xx.c:

static int mtk_spi_fifo_transfer(struct spi_master *master,
                 struct spi_device *spi,
                 struct spi_transfer *xfer)
{
    int cnt, remainder;
    u32 reg_val;
    struct mtk_spi *mdata = spi_master_get_devdata(master);

    mdata->cur_transfer = xfer;
    mdata->xfer_len = min(MTK_SPI_MAX_FIFO_SIZE, xfer->len);
    mdata->num_xfered = 0;
    mtk_spi_prepare_transfer(master, xfer);
    mtk_spi_setup_packet(master);

    cnt = xfer->len / 4;
    if (xfer->tx_buf)
        iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt);
    if (xfer->rx_buf)
        ioread32_rep(mdata->base + SPI_RX_DATA_REG, xfer->rx_buf, cnt); 
    remainder = xfer->len % 4;
    if (remainder > 0) {
        reg_val = 0;
        if (xfer->tx_buf) {
            memcpy(&reg_val, xfer->tx_buf + (cnt * 4), remainder);
            writel(reg_val, mdata->base + SPI_TX_DATA_REG);
        }
        if (xfer->rx_buf) {
            reg_val = readl(mdata->base + SPI_RX_DATA_REG);
            memcpy(xfer->rx_buf + (cnt * 4),&reg_val, remainder);
        }
    }

    mtk_spi_enable_transfer(master);

    return 1;
}
2 Likes

Hi,that means you’ve got spidev working?

Yes, it works with a LoRa concentrator hardware/software (designed for RPI). It uses all three spi modes (Single, FiFo and DMA) provided by the mt65xx driver. spi_test.c works also fine.

applied your patch to https://github.com/frank-w/BPI-R2-4.14/commits/5.4-spi

seems like in original version RX is not handled…that may explain why ryders display (tx only) works but not my tests with the spidev_test (rx + tx)

why do you drop mtk_spi_enable_transfer(master);? and afaik return value should be passed too, as function is defined as returning non-void