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

SPI hangs when accessing different peripherals connected to the same SPI line

I know this may be a duplicate of this: https://devzone.nordicsemi.com/f/nordic-q-a/37732/nrf52840-spi-clock-line-contention-causing-spi-driver-to-hang/145521#145521

I say that because my code is hanging in the same line of code. Buy my hardware is a little different:

We have two versions of hardware and each one of them has a different peripheral connected to the same SPI pins: one of them is an IMU and the other one is an Ethernet chip.

So, if we build the code for the HW version that has the ETH chip and load it into a board with the HW version that has the IMU, it will hang, probably for the same reason as in the linked topic.

But for my case just rebooting the SPI peripheral doesn't work because the code itself is expecting a different peripheral. So, is there a workaround for this that doesn't include changing the SDK?

The only solution that I can think of is: adding another flag to the loop, and then using a timer that will set this flag to false after a period of time, making the code jump out of the loop. Something like:

//setting up a timer outside of the SDK to set timer_flag to false after a while

timer_flag = true;

while ( !nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END) && timer_flag ) {

}

Any thoughts on this problem would be appreciated.

Thank you so much!

Parents
  • Hi,

    First, I would like to point out that the slave shouldn't drive the SCLK line as this should only be done by the master according to the TWI specification. The driver is designed accordingly to the specification which means that if you want it to work in a scenario which doesn't follow the specification then you would need to modify it. I think your suggestion of using a timer is a valid workaround Slight smile

    regards

    Jared

Reply
  • Hi,

    First, I would like to point out that the slave shouldn't drive the SCLK line as this should only be done by the master according to the TWI specification. The driver is designed accordingly to the specification which means that if you want it to work in a scenario which doesn't follow the specification then you would need to modify it. I think your suggestion of using a timer is a valid workaround Slight smile

    regards

    Jared

Children
  • I know this shouldn't happen. What I'm saying is: if the code is expecting to talk with the IMU and you accidentally flash the wrong build on the board, then the pin configuration gets messed up.
    Whats happens in this case is:

    Code Side  |   IMU Side

    CLK Pin      |   INT pin
    MOSI          |   INT pin
    MISO          |   INT pin
      SS            |   DATA enable pin


    This wrong setup of pins causes the SPI to hang on the first time it tries to read a WHO_AM_I register in the IMU, so I can't have a firmware solution that could check if the IMU is really present by reading this register and then switching to the correct pin configuration. I wonder if there's something some kind of configuration in the SDK that would prevent this from happening. I think that the SDK should not let the SPI code hang so "easily" (I know it's a bit of an overkill because I'm using a completely wrong pin config).


  • Hi,

    This is a HW design choice which means that there is limited to what you can do in SW to "fix" this. My guess is that you don't have any GPIOs that you can control from either the IMU or the ETH chip and use to signalize which peripheral that is connected?

    I still think a timer which forces the application to jump out of the loop and eventually shift the pin configuration and reset would be good enough solution. 

  • Yes, I don't have any of this available. One thing that I could do is to use the timer to generate an interrupt and the handler would write to the flash that the configuration is invalid and then reboot the chip, and then it will try to boot up using another set of pins (hopefully the correct one this time). This way I don't need to change the SDK.
    Thanks for the tips!

Related