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

Getting started with spi and i2c on nrf connect sdk

Hi,

I have been working with nrf5 sdk for my projects and now i am trying to port it into the nrfconnect sdk.

It looks a bit confusing and not able to find the proper documentation channels to add spi communication to my sample project. I have seen some of the posts here that looks out dated.

I couldn't make any progress in communicating with my device over spi or twi. 

What is simplest way to add an spi sensor ?

  • Hello,

    I can recommend a tutorial written by my colleague Simon. Chapter 1.2 should be of special interest for you:

    https://devzone.nordicsemi.com/nordic/nrf-connect-sdk-guides/b/getting-started/posts/nrf-connect-sdk-tutorial---part-3-ncs-v1-4-0#h79sk0f70607qwcyitkx2xn61bmh9mo

    Note that the tutorial is not up to date anymore, so instead of using

    CONFIG_I2C_1=y

    in prj.conf, you have to use this option instead:

    CONFIG_I2C=y

    I hope this will help you! Let me know if you have any more questions.

    Regards,

    Markus

  • Hi,

    That is pretty good, thanks.

     

    I have tried a simple test code for spi but i am not able to get the device_get_binding().

    prj.config

    CONFIG_NCS_SAMPLES_DEFAULTS=y
    
    CONFIG_BT=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DEVICE_NAME="Nordic_Blinky"
    
    # Enable the LBS service
    CONFIG_BT_LBS=y
    CONFIG_BT_LBS_POLL_BUTTON=y
    CONFIG_DK_LIBRARY=y
    
    CONFIG_GPIO=y
    CONFIG_SPI=y
    CONFIG_I2C=n
    CONFIG_NRFX_SPIM=n
    CONFIG_NRFX_SPIM1=n
    
    
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

    #if !DT_NODE_EXISTS(DT_NODELABEL(spi1))
    #error "whoops"
    #endif
    #define SPI1 DT_NODELABEL(spi1)
    
        struct device * spi_dev;
        spi_dev = device_get_binding(DT_LABEL(SPI1));   
    
    
    	const char* const spiName = "SPI_1";
    	//spi_dev = device_get_binding(spiName);
        spi_dev = device_get_binding(MYSPI);
    	if (spi_dev == NULL) {
    		printk("Could not find SPI driver\n");
    		return;
    	}else printk("spi success");
    	
    	
    	uint8_t tx_buf[4]={(0x0F<<1 ) | 0x01};
    	uint8_t rx_buf[4]={0};
    	struct spi_buf spi_tx_buf_struct;
    	spi_tx_buf_struct.buf = tx_buf;
    	spi_tx_buf_struct.len = 4;
    
    	struct spi_buf spi_rx_buf_struct;
    	spi_tx_buf_struct.buf = rx_buf;
    	spi_tx_buf_struct.len = 4;
    
    	struct spi_buf_set spi_bufs;
    	spi_bufs.buffers = &spi_tx_buf_struct;
    	spi_bufs.count = 4;
    	struct spi_buf_set spi_bufs_rx;
    	spi_bufs.buffers = &spi_rx_buf_struct;
    	spi_bufs.count = 4;
    	//
    
    
    	spi_transceive(spi_dev, &spi_cfg, &spi_bufs, &spi_bufs_rx);
    	//spi_write(spi_dev, &spi_cfg, &spi_bufs);
    	k_sleep(K_MSEC(100));
    	printk("read %d %d %d \n\n", rx_buf[1], rx_buf[2], rx_buf[3]);
    

    I have also had a look at the "device tree how to  ",

    
    my .dts for 52840,
    
    &spi1 {
    	compatible = "nordic,nrf-spi";
    	/* Cannot be used together with i2c0. */
    	/* status = "okay"; */
    	sck-pin = <13>;
    	mosi-pin = <14>;
    	miso-pin = <16>;
    };
    
    zephyr.dts, 
    
    spi1: spi@40004000 {
    	#address-cells = < 0x1 >;
    	#size-cells = < 0x0 >;
    	reg = < 0x40004000 0x1000 >;
    	interrupts = < 0x4 0x1 >;
    	status = "disabled";
    	label = "SPI_1";
    	compatible = "nordic,nrf-spi";
    	sck-pin = < 0xd >;
    	mosi-pin = < 0xe >;
    	miso-pin = < 0x10 >;
    };


    I think It initializes the spi, my i am getting this error,

    *** Booting Zephyr OS build v2.4.99-ncs1  ***␍␊
    Starting Bluetooth Peripheral LBS example␍␊
     SPI init␍␊
    spi successI: CS control inhibited (no GPIO device)␍␊
    E: ***** BUS FAULT *****␍␊
    E:   Precise data bus error␍␊
    E:   BFAR Address: 0x20040000␍␊
    E: r0/a1:  0x40004000  r1/a2:  0x20002e1c  r2/a3:  0x0003dbb8␍␊
    E: r3/a4:  0x20002448 r12/ip:  0x20002e28 r14/lr:  0x0001da9b␍␊
    E:  xpsr:  0x21000014␍␊
    E: Faulting instruction address (r15/pc): 0x00024216␍␊
    E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0␍␊
    E: Fault during interrupt handling␍␊

    I have tied the cs pin low always.

    Do i have to specify the pin numbers elsewhere other than the .dts file ? does it get override from somewhere else ?

  • There are no silly questions, only silly answers. Right? ;-)

    Are you using your own board together with the nRF52840 or a DK? I am asking because if you work with the nRF52840 DK for instance, you do not need an overlay file to get SPI1 to work. It is already part of the device tree, which you can check via a file called zephyr.dts located in: ../<your build folder>/zephyr/.

     

    spi1: spi@40004000 {
    	#address-cells = < 0x1 >;
    	#size-cells = < 0x0 >;
    	reg = < 0x40004000 0x1000 >;
    	interrupts = < 0x4 0x1 >;
    	status = "okay";
    	label = "SPI_1";
    	compatible = "nordic,nrf-spi";
    	sck-pin = < 0x1f >;
    	mosi-pin = < 0x1e >;
    	miso-pin = < 0x28 >;
    };

    I ran your C-snippet through a simple “Hello World” application on the nRF52840 DK and the binding worked fine.

    Regards,

    Markus

  • I am using a custom board based on nrf52840.

    I have not created a new board but edited the existing .dts file according my custom board specifications.

    I have ran it on a dk also but getting the same error.

    i have chosen a ble code as my base, let me get back to you after trying it out with simple example.

    This how the zephyr.dts file looks like,

    		};
    		spi0: spi@40003000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40003000 0x1000 >;
    			interrupts = < 0x3 0x1 >;
    			status = "disabled";
    			label = "SPI_0";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0x1f >;
    			mosi-pin = < 0x1e >;
    			miso-pin = < 0x28 >;
    		};
    		spi1: spi@40004000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40004000 0x1000 >;
    			interrupts = < 0x4 0x1 >;
    			status = "okay";
    			label = "SPI_1";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0xd >;
    			mosi-pin = < 0xe >;
    			miso-pin = < 0x10 >;
    		};
    		spi2: spi@40023000 {
    			#address-cells = < 0x1 >;
    			#size-cells = < 0x0 >;
    			reg = < 0x40023000 0x1000 >;
    			interrupts = < 0x23 0x1 >;
    			status = "disabled";
    			label = "SPI_2";
    			compatible = "nordic,nrf-spi";
    			sck-pin = < 0x13 >;
    			mosi-pin = < 0x14 >;
    			miso-pin = < 0x15 >;
    		};

    How do i create an overlay file ?

  • Chapter 3.4 of Simons tutorial gives you a basic introduction on how to create an overlay file. I hope this will be useful for you.

    Cheers!

    Markus

Related