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

Parents
  • Hi,

    Unfortunately, it is not possible to use two SPI intances and one TWI instance simultaneously on nRF51 series. The serial instances share the same base address. It is possible to use alle three, but you will have to switch between them (disable one SPI to enable TWI, etc).

    Best regards,
    Jørgen

  • Do you mean output the SPI signals to two set of pins at the same time? This is not supported by the peripheral without physically connecting the pins together. 

    You need to uninit and init the SPI driver in order to switch pins. Unfortunately, the pins are configured inside the driver and not only using SPI HAL function.

  • Hey Jørgen,

    That's what I figured about using the two sets of pins.

    As for uninit and init of the SPI driver, are you saying that this is not possible by using the HAL driver because they're also configured in the driver?  I'm confused by your last statement.

    Best,

    Matt

  • If you look into the source of nrf_drv_spi_init, you can see that the pins are configured with correct GPIO settings, the HAL function only set the correct pin number in the peripheral. You could configure the second set of GPIOs in your application, and set it in the peripheral using the HAL function, but you need to make sure the peripheral is not busy when doing this.

    Also note that you need to control SS pin manually in case of switching SPI pins (set it to NRF_DRV_SPI_PIN_NOT_USED in the config). This pin is controlled as a standard GPIO by the driver.

  • 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

Reply
  • 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

Children
No Data
Related