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

Complications with SPI configuration

Hi,

I am having issues with getting SPI up and running on my nrf52840-DK using NCS.  I've tried getting support about this in another ticket but it seems like it lead to a dead end https://devzone.nordicsemi.com/f/nordic-q-a/60878/configuring-spi0---dt_nordic_nrf_spi_spi_0_irq_0_priority-undeclared.

To summarize my issues:

  1. SPI0 does not seem to work at all, configuring it either causes the build to fail due to "DT_NORDIC_NRF_SPI_SPI_0_IRQ_0_PRIORITY' undeclared" or the device bind fails.
  2. I've managed to get SPI1, SPI2 and SPIM3 to working using a clean empty project but as soon as I try to implement them in my main project I get the following error:

[00:00:00.008,209] <err> os: ***** BUS FAULT *****
[00:00:00.008,209] <err> os:   Instruction bus error
[00:00:00.008,209] <err> os: r0/a1:  0x00000000  r1/a2:  0x20001ce8  r2/a3:  0x20001d00
[00:00:00.008,209] <err> os: r3/a4:  0x00000000 r12/ip:  0x20fe24f0 r14/lr:  0x00000ee1
[00:00:00.008,209] <err> os:  xpsr:  0x60000000
[00:00:00.008,209] <err> os: Faulting instruction address (r15/pc): 0x20fe24f0
[00:00:00.008,239] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
[00:00:00.008,239] <err> os: Current thread: 0x20000328 (unknown)
[00:00:00.942,657] <err> fatal_error: Resetting system

All other peripherals I've used so far, I2C, ADC, GPIO hasn't had any problems at all. Is there any guide at all on how to correctly configure multiple SPIM devices using the configuration manger in SES? I find it confusing why using the old deprecated SPI seems to work but not SPIM. Is there any extra steps required to get this working? I've been troubleshooting this error for weeks now and I am starting to run out of time.

I've attached my proj.conf that has been generated using the configuration tool in SES and my .overlay file.

5556.files.zip

Any help is appreciated, I am starting to lose hope.

  • I see some problems:

    Spi0:

    # CONFIG_SPI_0 is not set

    You need to enable SPI 0.

    Also check the following:

    # CONFIG_SPI_1_NRF_SPIM is not set

    # CONFIG_SPI_2_NRF_SPIM is not set

    Spi1:

    sck-pin = <0>;
    mosi-pin = <1>;

    P0.0 and P0.1 are the LF crystal pins and should never be used as anything else on the DK.

    SPIM3 has serious hardware bugs on the NRF52840 - see errata sheet. No idea whether the software workaround is properly implemented in zephyr - my guess would be: No.

  • Hi,

    Yeah I double checked the pins and have reverted to the default pins set in the .dts file:

    &spi0 {
    	compatible = "nordic,nrf-spi";
            status = "okay";
    	sck-pin = <27>;
    	mosi-pin = <26>;
    	miso-pin = <29>;
    };
    
    &spi1 {
    	compatible = "nordic,nrf-spi";
    	status = "okay";
    	sck-pin = <31>;
    	mosi-pin = <30>;
    	miso-pin = <40>;
    };
    
    &spi2 {
    	compatible = "nordic,nrf-spi";
    	status = "okay";
    	sck-pin = <42>;
    	mosi-pin = <43>;
    	miso-pin = <44>;
    };
    
    &spi3 {
    	status = "okay";
    	sck-pin = <47>;
    	miso-pin = <46>;
    	mosi-pin = <45>;
    };

    However, the issue still persists.

    # CONFIG_SPI_0 is not set

    This is intentional for now as the build fails if I enable this.

    # CONFIG_SPI_1_NRF_SPIM is not set
    # CONFIG_SPI_2_NRF_SPIM is not set

    This is also intentional because configuring SPI1 & SPi2 as the old deprecated way is the only way I've manage to get it working somewhat as expected.

  • Update, I've seem to be able to successfully bind SPI1, SPI2 and SPIM3. However, as soon as I try to write something I get hard fault.

    I init the SPI with the following function:

    int32_t get_spi_device(struct device* dev_ptr, char* dev)
    {
      printk("Getting device %s...\n", dev);
      dev_ptr  = device_get_binding(dev);
      if(!dev_ptr)
      {
        printk("Error getting %s\n", dev);
        return 1;
      }
      
      return 0;
    }
    

    And I have the following settings and buffers:

    static struct spi_buf      tx_buf;
    static struct spi_buf      rx_buf;
    
    static struct spi_buf_set  tx_bufs = {
      .buffers = &tx_buf,
      .count = 1,
    };
    
    static struct spi_buf_set  rx_bufs = {
      .buffers = &rx_buf,
      .count = 1,
    };
    
    static const struct spi_config spi_cfg = {
    	.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
    		     SPI_MODE_CPOL | SPI_MODE_CPHA,
    	.frequency = 1000000,
    	.slave = 0,
    };

    And finally I try to write on the bus using:

    spi_write(spi1, &spi_cfg, &tx_bufs);

    Once I try writing with this function the device hard faults. I've been trying to debug to see where the error occurs but I only reach static inline int z_impl_spi_transceive before I get error "Not enough hardware instruction breakpoints"

  • Seems like I managed to get SPI1 and SPI2 working. I will use these for the moment and see if I can figure out why SPIM0 doesn't work. Please close ticket when able.

  • Probably not helpful, but I see you mentioned I2C/TWI worked. Just for clarification (in case a reader doesn't know) SPI0 and TWI0 are the same underlying hardware which can be configured as SPI or TWI (but not both at the same time) and therefore share registers and interrupt. Any register left set by TWI0 (or be still in use by TWI0) can cause SPI0 to misbehave. SPI1 and TWI1 ditto; there are not 5 SPI & TWI interfaces, only 3 total.

Related