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

NRF52 as SPI master with Multiple Slaves

Hello, my project has 3 different devices (2 sensor and flash memory) on the same SPI bus all with their own CS. I ran across the following question, which has a response for a workaround for the NRF51. Upon jumping into the NRF52 SDK 12.2 documentation and it looks like the SPI structure has slightly changed.

Is the given solution in the previous post still applicable and if so what changes need to be made to make it work with the SDK 12.2.

If not what is the best route I need to implement 3 slaves on SPI. (GPIOTE and handle each CS individually?)

Thanks in advance

  • I spoke to may layout person and it looks like 2 SPI buses is an option. It appears all the devices use the same mode, but varying speeds. With this change I will still need to have 2 slaves on a single SPI bus. As such when I transition between the slaves do I need to unint the driver and then reinit the driver? Is the overhead light or heavy between this transfer.

  • What everyone else wrote in your comments is good. If you can run mutliple busses, do so because you'll have parallel access and avoid some traps with switching speeds and CS lines. If you absolutely must run multiple devices, that's fine, just plan on not using the hardware CS line imo and come up with a CS_Changer(myDevice) to handle the SPI details. You may need to work around modes and speeds.

    On the multiple slaves, be careful of how you share the MOSI/MISO lines. You can get into a termination and reflection issue. I was surprised to find out how complex SPI to multiple devices can be, most people just hook it up and go, but to really do it right, can be a lot of work.

    If you can daisy chain is better and solves these termination issues, if you must star, do it as short as possible, consider a 22ohm resistor inline to each device off the MISO line if the total MISO length is long, keep the stubs as short as possible.

    Do it right, don't overthink it too much. Plan on testing with a scope when you get a prototype up. Will only be an issue if you're going to push these SPI devices as fast as they go.

  • @SRA

    Interesting point about star vs daisy chain (not sure if daisy chain is the correct term in this case, but I know what you mean)

    I've only had issues with SPI on quite long wires to external displays when running very high speeds (36Mhz) - and that was just the MCU on one end and the display on the other. I had to shorten the leads to the display, and also separate them, as the capacitance in the ribbon cable was causing crosstalk.

    BTW. I don't think anyone has answered @TFETT's last question about the time to reconfigure the SPI to a different speed each time.

    I'd suggest that @TFETT look in the driver code for the SPI and see how much code is in the SPI config api call.

    I'm not an expert on the nRF51 hardware, but I know that other MCU's etc STM32 have to completely shut down the SPI sub system and re-start it, if you want to change the clock speed.

  • I did the following to add this capability:

    1. I moved the definition of spi_control_block_t from nrf_drv_spi.c to nrf_drv_spi.h, just above the declaration of nrf_drv_spi_init

    2. Also added #include "nrf_drv_common.h" to the top of nrf_drv_spi.h for compiling

    3. This allows the spi_control_block_t struct to be accessed my any source code that includes "nrf_drv_spi.h". Here is my CS change function:

      /*

      • Function for changing Chip Selecti pins in the nRF52 */

      void spi_switch_chips( uint32_t chip_select ) { volatile spi_control_block_t * my_setup = mw_spi_instance.drv_inst_idx; my_setup->ss_pin = chip_select;

       //A Slave select must be set as high before setting it as output,
       //because during connect it to the pin it causes glitches.
       nrf_gpio_pin_set(my_setup->ss_pin);
       nrf_gpio_cfg_output(my_setup->ss_pin);
       nrf_gpio_pin_set(my_setup->ss_pin);
      

      }

  • What Should i write in case of nrf51422? in place of mw_spi_instance.drv_inst_idx ? Please help, Thank you in advance.

Related