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

Basic SPI reads and writes

Hi,

I have a SPI peripheral connected to the nRF960 DK. In order to access this correctly, I need to be able to write a byte to a specific address first and then read back from specific addresses. 

I can run the basic SPI example

https://github.com/Rallare/fw-nrfconnect-nrf/tree/nrf9160_samples/samples/nrf9160/spi

which carries out a basic loop back. This all works fine but I can't see how to write a specific byte to a specific address or read a specific address.

So, ideally I would like to write 0xD2 to address 0x80, wait 1 second and then read data from address 0x00.

Can you point me to a simple example please?

Ta,
Rod

Parents
  • Hello Rod, 

    The SPI example you are using is the only one we have at the moment. The example is using the built-in SPI functions of the Zephyr project, perhaps you are able to find what you are looking for in the Zephyr samples? Also, have a look at the Zephyr SPI API and the SPI header file.

    Ref. similar answer given by my colleague Jan Tore here

    Kind regards,
    Øyvind

  • Hi Øyvind,

    I went back to the reply from Jan Tore on the ticket here. I realised that the BME280 has both an I2C and an SPI interface. So, I thought if I can get this sensor working over SPI and I can then try and migrate it to my own SPI sensor.

    I have successfully connected and ran the BME280 sensor over I2C. I am now trying to access this over SPI. 

    Im using the sample given here, 

    https://github.com/zephyrproject-rtos/zephyr/blob/master/samples/sensor/bme280/src/main.c

    I have set up SPI in my overlay file as suggested by Jan in the other ticket.

    /*
     *
     * Copyright (c) 2018 Linaro Limited
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    
    &i2c2 {
            status = "ok";
            sda-pin = <1>;
            scl-pin = <0>;
            clock-frequency = <I2C_BITRATE_FAST>;
            };
    
    &spi3 {
            status = "ok";
    	sck-pin = <10>;
    	mosi-pin = <11>;
    	miso-pin = <12>;
    	ss-pin = <13>;
    	spi-max-frequency = <8000000>;
    	bme280@0 {
    		compatible = "bosch,bme280";
    		reg = <0>;
    		spi-max-frequency = <8000000>;
    		label = "BME280";
    	};
    
    };
    

    and also I have enabled SPI in my conf file

    CONFIG_CONSOLE_SUBSYS=y
    CONFIG_CONSOLE_GETCHAR=y
    CONFIG_GPIO=y
    CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_SERIAL=y
    CONFIG_STDOUT_CONSOLE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_TEST_RANDOM_GENERATOR=y
    
    CONFIG_I2C=y
    CONFIG_SENSOR=y
    
    CONFIG_NET_BUF_USER_DATA_SIZE=1
    
    CONFIG_LOG=n
    CONFIG_LOG_DEFAULT_LEVEL=4
    CONFIG_HEAP_MEM_POOL_SIZE=1024
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_NEWLIB_LIBC=y
    
    # SPI
    CONFIG_SPI=y
    CONFIG_SPI_3=y
    CONFIG_SPI_3_NRF_SPIM=y
    CONFIG_BME280=y
    CONFIG_SPI_NRFX=y

    However, I get an error

    Secure Boot: MSP_NS 200216b0

    Secure Boot: prepare to jump to Non-Secure image

    ***** Booting Zephyr OS v1.13.99-ncs1-5561-gde69d2df908f *****

    Exception occurred in Secure State

    ***** HARD FAULT *****

      Fault escalation (see below)

    ***** BUS FAULT *****

      Precise data bus error

      BFAR Address: 0x50008120

    ***** Hardware exception *****

    Current thread ID = 0x20020154

    Faulting instruction address = 0x41f98

    Fatal fault in ISR! Spinning...

    Any thoughts?

  • Hi Rod, 

    Really sorry for this being so difficult to fix, I have not seen similar issues. 

    RodWatt said:
    2. I tried a complete new install. But as you will see from below, I still get the "West already initialised" error

     You need to find a folder named .west on your computer. This folder is generated when initializing west. Try to find this folder and delete it to see if this has any impact.

    I am discussing the issue in my team and will get back to you asap.

    Kind regards,
    Øyvind

  • Hi Øyvind,

    I got this working but not 100% sure what actually did the trick. Based on this thread "

    nRF9160 at_client sample project"

    i deleted my path and env variables.

    I then ran this again..

    pip3 install -r zephyr/scripts/requirements.txt
    pip3 install -r nrf/scripts/requirements.txt
    pip3 install -r mcuboot/scripts/requirements.txt

    as well as the update as above. Something did the trick and it burst into life.

    So,  I can no generate a merged.hex file and my code complies and runs. Unfortunately, my basic SPI reads and writes still dont work but at least I am now running on SPM

    Rod

  • Really glad to hear that it solved the issue!

    -Øyvind

  • Yes, it solved the SPM issue, but Im now back to the problem of trying to get SPI to work!

  • Ok. Just to get back on the right track again:

    • Are you able to run the SPI example without BME280? What problems are you seeing?
    • Is the hard fault issue still there?
      • In prj.conf, you must add:
        CONFIG_MAIN_STACK_SIZE=4096

    Kind regards,
    Øyvind

Reply Children
  • Hi,

    I managed to get it working !

    Thanks,

    Rod

  • Hi Rod,

    I'm travelling the same route on nrfConnect SDK 1.4

    Like you I got my I2C version working first and then wanted to use SPI.

    Any chance you could share your working sample?

    I have also posted this https://devzone.nordicsemi.com/f/nordic-q-a/70393/nrf9160-dk-spi-from-bme280-sensor-config-issue - no answer on that so far.

    Thx.

    Regards, Paul

  • Hi Paul,

    I have not looked at this for a while so I can't say 100% that this code is correct, but I have shared it anyway. Let me know if it works and if not, I will do a bit more digging my end.

    &spi3 {
            status = "ok";
    	sck-pin = <10>;
    	mosi-pin = <11>;
    	miso-pin = <12>;
    	ss-pin = <13>;
    	spi-max-frequency = <4000000>;
    	bme280@76 {
    		compatible = "bosch,bme280";
    		reg = <0x76>;
    		spi-max-frequency = <4000000>;
    		label = "BME280";
    	};
    
    };
    

    CONFIG_CONSOLE_SUBSYS=y
    CONFIG_CONSOLE_GETCHAR=y
    CONFIG_GPIO=y
    CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_SERIAL=y
    CONFIG_STDOUT_CONSOLE=y
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_TEST_RANDOM_GENERATOR=y
    
    CONFIG_SENSOR=y
    
    CONFIG_NET_BUF_USER_DATA_SIZE=1
    
    CONFIG_LOG=y
    CONFIG_LOG_DEFAULT_LEVEL=4
    CONFIG_HEAP_MEM_POOL_SIZE=1024
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_NEWLIB_LIBC=y
    
    # SPI
    CONFIG_SPI=y
    CONFIG_SPI_3=y
    CONFIG_SPI_3_NRF_SPIM=y
    CONFIG_BME280=y
    CONFIG_SPI_NRFX=y
    CONFIG_SENSOR_LOG_LEVEL_WRN=y
    
    CONFIG_TRUSTED_EXECUTION_NONSECURE=y
    
    
    

    #include <zephyr.h>
    #include <device.h>
    #include <sensor.h>
    #include <stdio.h>
    
    #undef DT_BOSCH_BME280_BUS_I2C
    #define DT_BOSCH_BME280_BUS_SPI
    
    void main(void)
    {
    
    int i;
    	printf("Boiler Guardian Test Code - BME280 over SPI \n");
    	printf(" \n");
    
    	struct device *dev = device_get_binding("BME280");
    
    	printf("dev %p name %s\n", dev, dev->config->name);
    
    	printf("Boiler Guardian Test Code - BME280 - got binding  \n");
    	printf(" \n");
    
    	for(i = 1; i < 2; i++) {
    		struct sensor_value temp, press, humidity;
    
    		sensor_sample_fetch(dev);
    		sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
    		sensor_channel_get(dev, SENSOR_CHAN_PRESS, &press);
    		sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity);
    
    
    		printf("Environmental Temperature: %d.%d Degrees Cent. \n", temp.val1, temp.val2);
    		printf("Environmental Pressure: %d.%02d Bar \n", press.val1, press.val2);
    		printf("Environmental Humidity: %d.%02d per/cent \n", humidity.val1, humidity.val2);
    
    
    	}
    }
    

  • Many thanks Rod.

    Things have moved on a lot but this was very helpful in getting me unstuck.

    With a bit of help from Simon this is now sorted out.

    devzone.nordicsemi.com/.../290233

    Regards, Paul

Related