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

Two SPI and one I2C master on nRF51

Hi,

I have a custom board someone designed with two SPI masters and one I2C master.  We're now trying to enable the second SPI master and I'm running into errors because you cannot enable SPI1 when TW1 is enabled.


So the simple question is can I use two SPI masters and one I2C master on the nRF51422 simultaneously?  I'm afraid I know my answer already :-/

Best,
Matt

  • Hi Jørgen,

    That makes sense, but I think my case is different because I want to do the following:

    1) Initialize SPI0, I2C1

    2) Uninitialize I2C1

    3) Initialize SPI1

    So instead of uninitializing/initializing SPI, I want to uninitialize the I2C1 instance and initialize a SPI1 instance.

    I've gotten through uninitializing I2C, but the issue with starting a second SPI is that my #defines in nrf_drv_config.h have SPI1_ENABLED = 0, so all the SPI driver indicies, interrupt settings, etc are not set up for SPI1.

    What's your recommendation for the cleanest way to transition from one to two SPI instances like this?

    Thanks!

    Matt

  • Have you set PERIPHERAL_RESOURCE_SHARING_ENABLED to 1 in your nrf_drv_config.h file? Which SDK version are you using?

  • Hey Jorgen,

    Yea I don't have a PERIPHERAL_RESOURCE_SHARING_ENABLED in my nrf_drv_config.h file, nor do I see it anywhere in the SDK files.  I'm on an old SDK version (v10.0) since that's what the customer was using and unfortunately cannot upgrade.

    My current hack is to set SP1_ENABLED in my nrf_drv_config.h and modify the following files:

    1) Disable the warning about turning on I2C1 and SPI1 at the same time in components\drivers_nrf\config\nrf_drv_config_validation.h:

    //#if (TWI1_ENABLED+SPI1_ENABLED)>1
    //#error "TWI1, SPI1 or TWIS1 cannot be enabled together. Peripherals overlaps."
    //#endif

    2) Not initialize the SPI1 IRQ handler (since the I2C1 is the same pointer and already initialized) in components\drivers_nrf\spi_master\nrf_drv_spi.c:

    //#if (SPI1_ENABLED == 1)
    //void SPI1_IRQ_HANDLER(void)
    //{
    //    #if (SPI1_USE_EASY_DMA == 1)
    //        irq_handler_spim(NRF_SPIM1,
    //    #else
    //        irq_handler_spi(NRF_SPI1,
    //    #endif
    //            &m_cb[SPI1_INSTANCE_INDEX]);
    //}
    //#endif // (SPI1_ENABLED == 1)

    I'm not sure if this is a decent workaround, especially due to #2 above.  I was concerned that I might be missing SPI transactions because I'm not listening to the interrupt, but if I try to initialize the SPI1 IRQ, it complains that it's already initialized for I2C1, so I was hoping since they're on the same ISR pointer this workaround is possible.

    I seem to be able to now uninitialize I2C1, initialize SPI1 and get SPI1 transactions back and forth with the hack above, so I think it's working, but would love your input on this and a proper fix if there is one.

    Best,

    Matt

  • I see, PERIPHERAL_RESOURCE_SHARING_ENABLED was first introduced in SDK 11.0.0.

    1. This should be fine, this is check is ignored in SDK 11 if PERIPHERAL_RESOURCE_SHARING_ENABLED is set.
    2. As long as you make sure you do not enable TWI and SPI at the same time, and keep track of which peripheral is enabled at any time, I think this workaround should work. I would anyway recommend you to have a look at SDK 11 to see how PERIPHERAL_RESOURCE_SHARING_ENABLED is implemented here.
Related