Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to disable SPI and TWI communication without interrupting GPIO.

Hi

I am using nrf51822 , sdk version 11 and softdevice version 130

In project I am trying to disable SPI1 and TWI0 channel by using following command

NRF_TWI0->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;

NRF_SPI1->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);

For TWI, above command fails to disable TWI0 communication. (I am using 'deprecated' files for TWI communication)

For SPI, after disable SPI ,it also affect  GPIO's working, device unable to sense input and also fails to generate output. I also tried with re-initialization of GPIO which giving ble disconnection error.

I want help to disable SPI and TWI channel and also way to change communication channel from SPI 1 to SPI 0. 

Thanking you.

Parents
  • HI Suvarna, 

    Firstly, if the drivers you are using are marked as deprecated then you should move to the latest drivers. We do not support deprecated SW.

    If you want to use the pins previously used by the SPI or TWI peripheral as GPIOs then you need to configure the GPIOs as outputs after the SPI or TWI periheral has been disabled. Generally I would recommend to use the driver API to disable the peripherals, e.g. nrf_drv_twi_uninit().

    What errors do you get when you try to intialize the pins as outputs after disabling the TWI/SPI peripheral?

    Best regards

    Bjørn

Reply
  • HI Suvarna, 

    Firstly, if the drivers you are using are marked as deprecated then you should move to the latest drivers. We do not support deprecated SW.

    If you want to use the pins previously used by the SPI or TWI peripheral as GPIOs then you need to configure the GPIOs as outputs after the SPI or TWI periheral has been disabled. Generally I would recommend to use the driver API to disable the peripherals, e.g. nrf_drv_twi_uninit().

    What errors do you get when you try to intialize the pins as outputs after disabling the TWI/SPI peripheral?

    Best regards

    Bjørn

Children
  • Hi Bjorn

    1. I am using diferent pin for SPI and TWI peripheral as well as GPIOs.
    2. Our system works as follows
      2.1 OLED is on SPI1 , Accelerometer is on TWI0 for 100ms. 
      2.2 OLED is on SPI0, Heart rate sensor on TWI1 for next 100ms.

      we are doing this because of the following point mentioned in the nrf51 reference manual.
      'same peripheral base address cannot be used at the same time.'
    3. Error: when we switch from point number 2.1 to 2.2, the other parts of the system stop working (Button and timer and GPIO functionality).
    4. Note: I have already tried with nrf_drv_spi_uninit(), It was giving same problem mentioned in point 3.
    5. I have also tried the following combinations mentioned in the code below.

    //== SECTION FROM spi.c ==//
    //====================== code to disable SPI ==============================
    
    #if (SPI0_ENABLED == 1)
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(0); 
    #elif (SPI1_ENABLED == 1)
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(1); 
    #elif (SPI2_ENABLED == 1)
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(2); 
    #else
    #error "No SPI enabled."
    #endif
    
    void disable_SPI()
    {
    	// === Method 1 ===//
    	// nrf_drv_spi_uninit(&spi);
    	
    	// ===  Method 2 ===//
        //	nrf_drv_spi_disable(&spi)
        
    	// ===  Method 3 ===//
    	//NRF_SPIM_Type * p_spim = p_instance->p_registers;
    	//NRF_SPI1->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
    
    	//=== Method 4 ===//
        NRF_SPI1->ENABLE = 0;
    }
    
    //===========================================================================
    
    

    //== SECTION FROM nrf_drv_spi.c file ==//
    //============================================
    // *** customised function for DISABLE SPI *** //
    void nrf_drv_spi_disable(nrf_drv_spi_t const * const p_instance)
    {
    	// ==== only for method 2 ===//
    	NRF_SPI_Type * p_spi = p_instance->p_registers;
    	nrf_spi_disable(p_spi);
    	nrf_delay_ms(10);
    }
    //============================================
    

    What could be the problem?

    Thank you.

  • Un-initializing the SPI and/or TWI peripheral should not affect any other peripherals like TIMERs and GPIO as they are instanced at other addresses that the SPI and TWI peripherals. 

    Why are you switching between the serial interfaces in the first place? You are aware that you can have multiple TWI slaves on a TWI bus?

    Why are you switching the OLED? I would just keep the OLED on SPI0 and then you connect both the heart rate sensor and the accelerometer to the TWI1 bus. If the two sensors use different TWI frequencies, then I would just reinitialize the TWI1 instance every 100ms. This makes things less complicated. 

    Best regards

    Bjørn

  • In my hardware Heart rate and Accelerometer using different pins as peripheral, so I could not use the same TWI channel for both.

  • OK, i would consider connecting the SDA and SCL lines of both sensor to one TWI bus so that you do not have to switch. If you do not want to do that then then keep the OLED on SPI0 and then reinitialize the TWI1 instance every 100ms with the pin configuration of the sensor you want to use the next 100ms. 

Related