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

Problem using 3 instances of SPIM on NRF52840 Zephyr RTOS

When enabling 3 instances of SPIM (1,2,3) on NRF52840 the application doesn't start at all.

Weirdly however, the application works fine when SPI3 takes SPIM3 and the rest SPI0, SPI2 respectively, or when SPIM1 and SPIM2 are enabled and "SPI3 instance" is disabled

The simultaneous sending on 3 SPI, which I need for my application can only happen if all are SPIM thanks to easyDMA

snippets:

prj.conf:

# SPI
CONFIG_SPI=y
CONFIG_SPI_ASYNC=y
CONFIG_SPI_INIT_PRIORITY=70
CONFIG_SPI_0=n
CONFIG_SPI_1=y
CONFIG_SPI_2=y
CONFIG_SPI_3=y
CONFIG_SPI_NRFX=y
CONFIG_SPI_1_NRF_SPIM=y
CONFIG_SPI_1_OP_MODES=1
CONFIG_SPI_1_NRF_ORC=0x00
CONFIG_SPI_2_NRF_SPIM=y
CONFIG_SPI_2_OP_MODES=1
CONFIG_SPI_2_NRF_ORC=0x00
CONFIG_SPI_3_NRF_SPIM=y
CONFIG_SPI_3_OP_MODES=1
CONFIG_SPI_3_NRF_ORC=0x00

.overlay file:

&spi1{
compatible = "nordic,nrf-spim";
status = "okay";
};
&spi2{
compatible = "nordic,nrf-spim";
status = "okay";
};
&spi3{
compatible = "nordic,nrf-spim";
status = "okay";
};

Help is highly appreciated :).

Parents
  • haven't seen this myself, but what does it mean that the application start at all? So it does not reach to the main()? If so, there could be something in the driver initialization phase that fails that happens before the control reaches to main. Please start the program in the debugger to see what is the failure. 

  • Thank you for your answer,

    The behavior is that the device_get_binding() function does not return a reference to the SPI1 or SPI2 devices if either of them chooses SPIM driver and the SPI3 is enabled with SPIM.

    The application keeps on restarting in this function before reaching the while(true) loop

    static void spi_init(){
            spi_1_dev = device_get_binding("SPI_1");
            if(!spi_1_dev) printk("no SPI1!\n");
            else printk("found SPI1!\n");
            gpio_0_dev1 = device_get_binding("GPIO_0");
            if(!gpio_0_dev1) printk("no gpio_0_dev1!");
            cs1_control.delay = 0;
                cs1_control.gpio_dev = gpio_0_dev1;
               cs1_control.gpio_pin = 14;
            spi_1_cfg.cs = &cs1_control;

            spi_2_dev = device_get_binding("SPI_2");
            if(!spi_2_dev) printk("no Spi2!\n");
            else printk("found SPI2!\n");
            gpio_0_dev2 = device_get_binding("GPIO_0");
            if(!gpio_0_dev2) printk("no gpio_0_dev2!");
            cs2_control.delay = 0;
                cs2_control.gpio_dev = gpio_0_dev2;
               cs2_control.gpio_pin = 26;
               spi_2_cfg.cs = &cs2_control;

            spi_3_dev = device_get_binding("SPI_3");
            if(!spi_3_dev) printk("no SPI3\n");
            else printk("found SPI3!\n");
            gpio_0_dev3 = device_get_binding("GPIO_0");
            if(!gpio_0_dev3) printk("no gpio_0_dev3!");
            cs3_control.delay = 0;
                cs3_control.gpio_dev = gpio_0_dev3;
               cs3_control.gpio_pin = 24;
               spi_3_cfg.cs = &cs3_control;
            
    }

    the application would work if both SPI1 and SPI2 chooses the SPI driver without easyDMA but that is not the behavior I want

  • smells like a bug in the driver. Let me reproduce this tomorrow and we can together agree on a workaround.

    BTW, have you checked if the erratas workaround have been applied?

  • Thank you for your reply Susheel,

    I also think there is a bug in the driver.

    Having looked at the driver implementation of SPIM, I have not found any special treatment for the SPI 3 instance

  • Since you already have the setup to reproduce this, can you please give me a simplified project to test this. Will save a lot of my time trying to set it up.. Are you using Nordic Connect SDK or cloning Zephyr directly? which version ?
    Once I reproduce it, we can try to figure out a workaround for this problem.

Reply Children
Related