This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Migrating a design from Raspberry pi Zero to nRF9160 DK - Need I2C and SPI interfaces

Hi,

I have developed a simple system based around a Raspberry Pi Zero. The system uses a couple of sensors to measure temperature and water pressure using a ADS51115 A/D and a MAX 31865 RTD to digital convertor. These connect to the Pi zero via the !2C bus and the SPI interface. I would like to replace the Pi zero with the nRF9160 dev board, can some one point me to some example hw and sw that will enable me to quickly convert. Thanks, Rod

Parents
  • Hi, 

    In order to use SPI and I2C peripherals, the following configurations can be placed in `prj.conf` to enable them and select the nrfx driver:

    CONFIG_I2C=y
    CONFIG_I2C_NRFX=y
    CONFIG_I2C_2=y
    CONFIG_I2C_2_NRF_TWIM=y

    CONFIG_SPI=y
    CONFIG_SPI_NRFX=y
    CONFIG_SPI_3=y
    CONFIG_SPI_3_NRF_SPIM=y

    This will enable I2C instance 2 and SPI instance 3, configure them to use nrfx driver. Note that these are the ones declared in the default secure boot to be available for a non-secure application:
    https://github.com/NordicPlayground/fw-nrfconnect-nrf/blob/master/samples/nrf9160/secure_boot/src/main.c#L321

    You can choose other instances as long as you also adjust which peripherals are set as non-secure.

    You then need to defined the peripherals in an overlay file for the board where you can set the pin numbers and clock speed. Name it `nrf9160_pca10090.overlay` and place it in the application folder. The contents of the file may be as follows:


    &i2c2 {
            status = "ok";
            sda-pin = <30>;
            scl-pin = <31>;
            clock-frequency = <I2C_BITRATE_FAST>;
    };

    &spi3 {
            status = "ok";
            sck-pin = <6>;
            mosi-pin = <7>;
            miso-pin = <8>;
            spi-max-frequency = <4000000>;
    };


    The devices get the labels "I2C_2" and "SPI_3" to be used in the `device_get_binding()` call, according to their instance numbers.

    When you have the configuration set, you will be able to use the generic I2C and SPI drivers in Zephyr, and can build use those samples and the API documentation as reference:

    I2C API:
    https://docs.zephyrproject.org/latest/api/io_interfaces.html?#i2c-interface

    SPI API:
    https://docs.zephyrproject.org/latest/api/io_interfaces.html?#spi-interface

    Samples:
    https://github.com/zephyrproject-rtos/zephyr/tree/master/samples/drivers 

  • Jan, thank you for your reply. A couple  of follow on questions.
    1. Am I correct in saying that I can assign any GPIO pins as SPI and I2C interfaces?
    2. As part of my development process, I want to phase in the replacement of the Raspberry Pi. In the next version on the prototype, I would like to keep the Pi zero and add the nRF9160DK effectively as a peripheral. 
    So, please can you advise how I can add the nRF9160DK as a peripheral to the Pi. Do I just connect over UART or can you suggest a better way?
  • Hi Jan,

    Finally I have had the opportunity to get back to this. (Im doing this work as a side line!) Anyway, I have Zephyr now running on the board and have verified my tool chain with the standard hello World example. Next, I want to try my first sensor, the BME280. I was pleased to see there is already example code there. I added the overlay fine as you suggested above. Please can you tell me what the proper syntax is for defining the sensor. I get the error below. I guess I need to define the sensor either in my config or overlay file? Sorry, I appreciate this is quite basic stuff, Im a h/w guy in a s/w world!

    Watts-MacBook-Pro:build Watt$ ninja

    [102/109] Building C object zephyr/drivers/sensor/bme280/CMakeFiles/drivers__sensor__bme280.dir/bme280.c.obj

    FAILED: zephyr/drivers/sensor/bme280/CMakeFiles/drivers__sensor__bme280.dir/bme280.c.obj 

    ccache /Users/Watt/gnuarmemb/bin/arm-none-eabi-gcc -DBUILD_VERSION=v1.14.0-rc1-1246-g959abdf1c9c9 -DKERNEL -DNRF9160_XXAA -D_FORTIFY_SOURCE=2 -D__ZEPHYR_SUPERVISOR__ -D__ZEPHYR__=1 -I../../../../kernel/include -I../../../../arch/arm/include -I../../../../include -I../../../../include/drivers -Izephyr/include/generated -I../../../../soc/arm/nordic_nrf/nrf91 -I../../../../soc/arm/nordic_nrf/include -I../../../../lib/libc/minimal/include -I../../../../ext/hal/cmsis/Include -I../../../../ext/hal/nordic/nrfx -I../../../../ext/hal/nordic/nrfx/drivers/include -I../../../../ext/hal/nordic/nrfx/hal -I../../../../ext/hal/nordic/nrfx/mdk -I../../../../ext/hal/nordic/. -isystem /Users/Watt/gnuarmemb/bin/../lib/gcc/arm-none-eabi/7.3.1/include -isystem /Users/Watt/gnuarmemb/bin/../lib/gcc/arm-none-eabi/7.3.1/include-fixed -Os -nostdinc -g -Wall -Wformat -Wformat-security -Wno-format-zero-length -imacros /Users/Watt/zephyrproject/zephyr/samples/sensor/bme280/build/zephyr/include/generated/autoconf.h -ffreestanding -Wno-main -fno-common -mthumb -mcpu=cortex-m33 -fno-asynchronous-unwind-tables -fno-pie -fno-pic -fno-strict-overflow -Wno-pointer-sign -Wno-unused-but-set-variable -fno-reorder-functions -fno-defer-pop -Werror=implicit-int -Wpointer-arith -ffunction-sections -fdata-sections -mabi=aapcs -march=armv8-m.main+dsp -std=c99 -MD -MT zephyr/drivers/sensor/bme280/CMakeFiles/drivers__sensor__bme280.dir/bme280.c.obj -MF zephyr/drivers/sensor/bme280/CMakeFiles/drivers__sensor__bme280.dir/bme280.c.obj.d -o zephyr/drivers/sensor/bme280/CMakeFiles/drivers__sensor__bme280.dir/bme280.c.obj   -c /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c

    In file included from /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c:24:0:

    /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.h:111:2: error: #error "BME280 device type not specified"

     #error "BME280 device type not specified"

      ^~~~~

    /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c: In function 'bme280_init':

    /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c:357:22: warning: unused variable 'data' [-Wunused-variable]

      struct bme280_data *data = dev->driver_data;

                          ^~~~

    In file included from ../../../../include/sensor.h:23:0,

                     from /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c:11:

    /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c: At top level:

    /Users/Watt/zephyrproject/zephyr/drivers/sensor/bme280/bme280.c:385:29: error: 'DT_BOSCH_BME280_0_LABEL' undeclared here (not in a function); did you mean 'DT_FLASH_AREA_0_LABEL'?

     DEVICE_AND_API_INIT(bme280, DT_BOSCH_BME280_0_LABEL, bme280_init, &bme280_data,

                                 ^

    ../../../../include/device.h:107:11: note: in definition of macro 'DEVICE_AND_API_INIT'

       .name = drv_name, .init = (init_fn),     \

               ^~~~~~~~

    ninja: build stopped: subcommand failed.

  • Hi,

    It looks like what you're seeing here is because the BME280 is not set up to be attached to one of your serial buses. The BME280 driver is configured to use automatically generated information from the device tree to determine which serial bus and other HW configuration to use. Every macro starting with `DT_` originates from the device tree, meaning .dts and .overlay files. So, the device tree needs to contain information about BME280. That's done by adding it to your .overlay file (named the same as your board). If you have BME280 on the I2C bus, it would look like this:

    &i2c2 {
        /* Your bus configuration goes here */
    
        /* The I2C address could be one of two, here 0x76 is assumed */
    	bme280@76 {
    		compatible = "bosch,bme280";
    		reg = <0x76>;
    		label = "BME280";
    	};
    };


    And for SPI something like this:
    &spi3 {
        /* Bus configuration here */
    
    	bme280@0 {
    		compatible = "bosch,bme280";
    		reg = <0>;
    		spi-max-frequency = <8000000>;
    		label = "BME280";
    	};
    };

    Hopefully that would get you started.

    Best regards,

    Jan Tore

  • Thanks Jan,

    OK, I have created an overly file, nrf9160_pca10090.overlay and have added the code as detailed in your message above. This is in my application directory

    Watts-MacBook-Pro:BME280_Test_Code Watt$ ls

    CMakeLists.txt prj_spi.conf

    build sample.yaml

    nrf9160_pca10090.overlay src

    prj.conf

    When I try to build

    cmake -GNinja -DSHIELD=nrf9160_pca10090 -DBOARD=nrf9160_pca10090 ..

    I get an error

    Zephyr version: 1.14.0

    -- Found PythonInterp: /usr/local/bin/python3 (found suitable version "3.7.3", minimum required is "3.4") 

    -- Selected BOARD nrf9160_pca10090

    No shield named 'nrf9160_pca10090' found

    Any ideas?

  • Hi,

    I might be misunderstanding here, but it looks liek you're trying to use another nRF91 DK as a shield. If you build without the -DSHIELD option, this should work. If you have a (BME280?) shield connected to your board, you can create an overlay with its name like you did for the board. Then you can feed the shield name into the build system using -DSHIELD. 

    Please correct me if I'm not understanding what you want to achieve.

    Best regards,

    Jan Toe

Reply
  • Hi,

    I might be misunderstanding here, but it looks liek you're trying to use another nRF91 DK as a shield. If you build without the -DSHIELD option, this should work. If you have a (BME280?) shield connected to your board, you can create an overlay with its name like you did for the board. Then you can feed the shield name into the build system using -DSHIELD. 

    Please correct me if I'm not understanding what you want to achieve.

    Best regards,

    Jan Toe

Children
No Data
Related