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

How to disable/uninitialize SPI on nRF9160DK used for interfacing SD card?

Hello,

I interfaced nRF9160 and SD card using SPI. I started with this sample: ncs/zephyr/samples/subsys/fs/fat_fs.

Now once the files from SD card are read, I want to uninitialize this SPI, so it can be used by other peripheral. So how can I disable or uninitialize this SPI?

I found that by using "sdhc_spi_set_cs(data, 1)" function, I can deassert chip select pin. But using this function in main program gives the error. I included the header files, still it shows error.

Code:

	while (1) {

              if(sdcard)
              {
                  sd_card();
                  file_open();
                  sdhc_spi_set_cs(data, 1);     //Error
                  sdcard = 0;
              }
		k_sleep(1000);
	}

  • Hi,

    Thank you for the solutions.

    But I don't understand how to implement it.

    Could you please tell in detail? How to use CONFIG_DEVICE_POWER_MANAGEMENT in the application or use the uninit function to disable and again re-enable the SPI?

    Thank you in advance.

  • Hi,

     

    Jagruti said:
    Could you please tell in detail? How to use CONFIG_DEVICE_POWER_MANAGEMENT in the application or use the uninit function to disable and again re-enable the SPI?

    Implementing DEVICE_POWER_MANAGEMENT requires more development, as shown in this example: https://github.com/nrfconnect/sdk-zephyr/tree/master/samples/subsys/power/device_pm/src

     

    If you do not want to implement the above device power management scheme, you can write to the NRF_SPIM3 registers directly to disable it, then write to the GPIOs to set them in default position again. By including "#include <hal/nrf_gpio.h>" in your project, you can almost copy-paste the nrf_gpio calls, you just have to map your pins to the one's that is default set. The pin configuration should be seen in your overlay file.

     

    Kind regards,

    Håkon

  • Hi,

    Thank you for the explaination.

    I tried the 2nd option.

    I am able to disable SPIM3 but I don't understand how to re-enable it.

    The code is:

    #define CS_pin    13
    #define MISO_pin  12
    #define MOSI_pin  11
    
    void disable_spi()
    {
        NRF_SPIM3_NS->TASKS_STOP = 1;
        NRF_SPIM3_NS->ENABLE = 0;      // To disable SPI3
        NRF_SPIM3_NS->PSEL.SCK = 0xFFFFFFFF;
        NRF_SPIM3_NS->PSEL.MISO = 0xFFFFFFFF;
        NRF_SPIM3_NS->PSEL.MOSI = 0xFFFFFFFF;
        NRF_P0_NS->OUTCLR = (1 << CS_pin);
        NRF_P0_NS->OUTCLR = (1 << MISO_pin);
        NRF_P0_NS->OUTCLR = (1 << MOSI_pin);
    }
    
    void enable_spi()
    {
        NRF_SPIM3_NS->ENABLE = 7;     // To enable SPI3
    //    NRF_P0_NS->OUTSET = 0xFFFFFFFF;
    //    NRF_SPIM3_NS->INTENSET = (1 << MISO_pin);
    //    NRF_SPIM3_NS->INTENSET = (1 << MOSI_pin);
        NRF_SPIM3_NS->TASKS_START = 1;
    }
    
    void main(){
    	while (1) {
    
                  if(sdcard)
                  {
    
                      sd_card();
                      file_open();
                      printk("Disabling SPIM3\n");
                      disable_spi();
                      printk("Disabled SPIM3\n");
                      enable_spi();
                      file_open();
                      sdcard = 0;
                  }
    		k_sleep(1000);
    	}
    }

    With the above code, SPIM3 is disabled and all pins goes low.

    1. Is this the correct way to disable SPI or anything else is needed?

    2. To enable, the value is 7 or 8?

    For UART, I saw it is 8. But here https://infocenter.nordicsemi.com/index.jsp?topic=%2Fps_nrf9160%2Fspim.html&cp=2_0_0_5_12, it shows 7 for SPIM. The Enable registers for both UART and SPIM is same. So which value is correct for SPIM?

    When I tried with NRF_SPIM3_NS->ENABLE = 8;

    MISO and MOSI goes high but CS pin is still low.

    When I tried with NRF_SPIM3_NS->ENABLE = 7;

    CS pin goes high but MISO and MOSI are still low and I get the file open error (-5) which is I/O error.

    So which value is correct for Enable register and how does all SPI pin levels goes high again?

    Thanks in advance.

    Regards,

    Jagruti

  • Hi again,

    I tried to implement DEVICE_POWER_MANAGEMENT.

    But by just adding CONFIG_DEVICE_POWER_MANAGEMENT=y in prj.conf file gives error.

    The error is:

    Building ‘zephyr/libzephyr.a’ from solution ‘build’ in configuration ‘Common’
      Compiling ‘device.c’
        #error "Add SoC's core devices list for PM"
        'MAX_PM_DEVICES' undeclared here (not in a function)
        'NUM_CORE_DEVICES' undeclared (first use in this function); did you mean 'MAX_PM_DEVICES'?
        each undeclared identifier is reported only once for each function it appears in
        'core_devices' undeclared (first use in this function); did you mean 'device'?
        
        'device_retval' defined but not used [-Wunused-variable]
        'device_ordered_list' defined but not used [-Wunused-variable]
      Compiling ‘nrf_power_clock.c’
      Compiling ‘sys_clock_init.c’
      Compiling ‘nrf_rtc_timer.c’
      Compiling ‘secure_services_ns.c’
    Build failed

    I tried to compile this example also: https://github.com/nrfconnect/sdk-zephyr/tree/master/samples/subsys/power/device_pm/src, but it gives the same error.

    How to remove this error? Do I need to add anything else in prj.conf file?

  • Hi,

    I solved the issue. Now I am able to disable and enable the SPI peripheral used for SD card as many times as I want. I used device power management for SPI and cleared the CS pin separately by writing into the register NRF_P0_NS.

    Thank you so much for your help.

    Best Regards,

    Jagruti

Related