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 ?

  • Thanks Markus, 

    it was helpful, i am able read/write data using the zephyr apis.

    I am still a bit confused about the spi data structures for read/write and also the 'patch_spi_read' api.

    It doesn't seem to work but i can figure that out. 

    I will try out the i2c in the same way.

    I have a general question regarding the nrfconnect sdk and zephyr,

    As I have mentioned in the initial question, i am trying to port my application code to nrf connect sdk from nrf5 sdk14.00. i am a bit worried about the time required to completely port the code.

    My application requirements are, 

    dfu bootloader, 2 spi, a flash file system(little fs), extended BLE mtu size(>150), low BLE connection interval (<50 ms), 2 timers, 1 i2c and a watchdog.

    Is the nrfconnect sdk drivers required for my application is mature enough? Is there enough examples/documentation available to make the process as quick as possible ?

    Just to make sure it is the right time to port the code to nrfconnect sdk.

    I am adding my code here. 

    Hope this would be helpful for someone.

    /*
     * Copyright (c) 2012-2014 Wind River Systems, Inc.
     *
     * SPDX-License-Identifier: Apache-2.0
     */
    
    #include <zephyr.h>
    #include <sys/printk.h>
    #include <zephyr/types.h>
    #include <stddef.h>
    #include <string.h>
    #include <errno.h>
    #include <drivers/spi.h>
    #include <drivers/gpio.h>
    
    
    #if !DT_NODE_EXISTS(DT_NODELABEL(spi1))
    #error "0oops"
    #endif
    #define SPI1 DT_NODELABEL(spi1)
    
    int spi_cs_pin = 15;
    int led_pin = 14;
    
    static struct spi_config spi_cfg = {
    	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
    	.frequency = 4000000,
    	.slave = 0,
    };
    struct device * spi_dev = NULL;
    struct device * gpio0_dev = NULL;
    struct device * gpio1_dev = NULL;
    
    bool patch_spi_read(uint8_t * tx_ptr, uint8_t * rx_ptr, uint8_t tx_len, uint8_t rx_len){
    
    	int err;
    
    	struct spi_buf tx_buf[2];
    	struct spi_buf rx_buf[2];
    	struct spi_buf_set tx;
    	struct spi_buf_set rx;
    
    	tx_buf[0].buf = tx_ptr;
    	tx_buf[0].len = 1;
    
    	rx_buf[0].buf = rx_ptr;
    	rx_buf[0].len = 1;
    
    	rx_buf[1].buf = &rx_ptr[1];
    	rx_buf[1].len = 4;
    
    	tx.buffers = tx_buf;
    	tx.count = 1;
    	rx.buffers = rx_buf;
    	rx.count = 2;
    
    	gpio_pin_set(gpio0_dev, spi_cs_pin, 0);
    	//err = spi_transceive(spi_dev, &spi_cfg, &tx, &rx);k_sleep(K_MSEC(30));
    	err = spi_write(spi_dev, &spi_cfg, &tx);
    
    	if (err) {
    		printk("spi write error: %d\n", err);
    		return false;
    	}
    	k_sleep(K_MSEC(3));
    	err = spi_read(spi_dev, &spi_cfg, &rx);
    	if (err) {
    		printk("spi read error: %d\n", err);
    		return false;
    	}else {
    		printk("tx data %x\n", tx_ptr[0]);
    
    		for (size_t i = 0; i < 4; i++) {
    			printk("RX recv: %d \n", rx_ptr[i]);
    		}
    	}
    	//gpio_pin_set(gpio0_dev, spi_cs_pin, 1);
    	return true;
    }
    
    void main(void)
    {
    	printk("Hello World! %s\n", CONFIG_BOARD);
    
    	gpio0_dev= device_get_binding("GPIO_0");
    
    	gpio_pin_configure(gpio0_dev, spi_cs_pin, GPIO_OUTPUT); //p0.03 == led_pin2
    	gpio_pin_configure(gpio0_dev, led_pin, GPIO_OUTPUT); //p0.03 == LED2
    	gpio_pin_set(gpio0_dev, spi_cs_pin, 0);
    
    
    	printk(" SPI init\n");
    	spi_dev = device_get_binding(DT_LABEL(SPI1));
    	if (spi_dev == NULL) {
    		printk("Could not find SPI driver\n");
    		return;
    	}else printk("spi init success\n");
    
    	k_sleep(K_MSEC(50));
    
    	static uint8_t tx_buffer[16] = {0x1f, 00, 00, 00};
    	static uint8_t rx_buffer[16];
    	patch_spi_read(tx_buffer, rx_buffer, 1, 4);
    
    	while(true){
    		gpio_pin_set(gpio0_dev, led_pin, 0xff);
    		k_sleep(K_MSEC(2000));
    
    		gpio_pin_set(gpio0_dev, led_pin, 0);
    		k_sleep(K_MSEC(30));
    	}
    
    }
    

  • In general, I recommend you switching over to the NCS since we are not adding any new features to the SDK anymore.

    You can check out this link for available examples and documentation.

    Regarding the time for porting your code: It is of course hard to give you exact numbers, but I do not expect it to take too much time. The API’s are quite similar in general.

    A good way to start would be letting the NCS compiler run through the ported code.

    Cheers,

    Markus

Related