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

Slave select pin always low

Hi 

The slave select (ss) pin during the spi communication is always low even when i make it high to release the spi bus. It looks to me that I'm not actually controlling the ss pin. 

I am using nrf52840, soft device is enabled.

My spi open code looks like following:


bool spi_open(uint8_t index, nrf_drv_spi_frequency_t freq, nrf_drv_spi_mode_t mode)
{

  if (index == SPI0)
  {
    nrf_drv_spi_config_t spi0_config = NRF_DRV_SPI_DEFAULT_CONFIG;

    spi0_config.miso_pin = SPI0_MISO_PIN;
    spi0_config.mosi_pin = SPI0_MOSI_PIN;
    spi0_config.sck_pin = SPI0_SCK_PIN;  
      
    spi0_config.ss_pin = SDCARD_CS1;
    spi0_config.frequency = freq;
    spi0_config.mode = mode;
    spi0_config.orc = 0x00;

    APP_ERROR_CHECK(nrf_drv_spi_init(&spi_0, &spi0_config, NULL, NULL)); // with blocking mode
  }
  else if (index == SPI1)
  {
    nrf_drv_spi_config_t spi1_config = NRF_DRV_SPI_DEFAULT_CONFIG;

    spi1_config.miso_pin = SPI1_MISO_PIN;
    spi1_config.mosi_pin = SPI1_MOSI_PIN;
    spi1_config.sck_pin = SPI1_SCK_PIN;
#if (SDCARD == ON)
    spi1_config.ss_pin =SDCARD_CS;
#endif

    spi1_config.frequency = freq;
    spi1_config.mode = mode;
    spi1_config.orc = 0x00;

    APP_ERROR_CHECK(nrf_drv_spi_init(&spi_1, &spi1_config, NULL, NULL)); // with blocking mode
  }
}

Parents
  • Hi,

    It's not clear from the code that you've shared what the value that you set the slave select pin SDCARD_CS1 is.

    • What is the nRF connected to via SPI?
    • How are you measuring the state of the slave select pin? Logic analyzer, Oscilloscope? 
    • What is SDCARD_CS1? Could you share more of your code?
    • Which SDK and Softdevice version are you using?

    regards

    Jared

  • Hi thanks

    Soft device version is s140_nrf52_6.1.0_softdevice

    I'm measuring the state of the slave select pin using oscilloscope

    Two SPI instances are there and SDCARD_CS and SDCARD_CS1 are slave select pins (two gpio pin declared as output)

    SPI communication is used to communicate with SD CARD.

  • Hi,

    Could you share a project that will run on the nRF52840 DK? I would like reproduce it myself.

    regards

    Jared 

  • Hi Jared 

    I would not be able to share the whole project but I can tell  some of the details how I'm using  spi in my project.

     #define NRF_DRV_SPI_USE_SPIM  true                 //from nrf_drv_spi.h
     
     
     /* Serial Peripheral Interface Master with DMA */  //from nrf52840_peripherals.h
    #define SPIM_PRESENT
    #define SPIM_COUNT 4

    #define SPI_INSTANCE_0          2 /**< SPI instance index. */  
    #define SPI_INSTANCE_1          1 /**< SPI instance index. */ 

    static const nrf_drv_spi_t spi_0 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE_0);  
    static const nrf_drv_spi_t spi_1 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE_1);  

    //gpios for spi0
    #define SDCARD_CS1                 30 //SIO_30
    #define SPI0_SCK_PIN               26 
    #define SPI0_MISO_PIN              27  
    #define SPI0_MOSI_PIN              31
    
    //gpios for spi1
    #define SDCARD_CS                  03 //SIO_03
    #define SPI1_MISO_PIN              28
    #define SPI1_MOSI_PIN              29
    #define SPI1_SCK_PIN               45
    
        
    nrf_drv_spi_t spi_0;// = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    nrf_drv_spi_t spi_1;// = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    
    void spi_set(nrf_drv_spi_t spi0, nrf_drv_spi_t spi1)
    {
      spi_0 = spi0;
      spi_1 = spi1;
    }
    void  peripheral_init(void)
    {
        spi_set(spi_0, spi_1);
        spi_open(SPI0, NRF_SPI_FREQ_8M, NRF_DRV_SPI_MODE_0);
    #if (SDCARD == ON)
        spi_open(SPI1, NRF_SPI_FREQ_250K, NRF_DRV_SPI_MODE_3); //SD card frequency range 100-400 KHz while initializing
    #endif
    
     nrf_gpio_cfg_output(SDCARD_CS);
     nrf_gpio_cfg_output(SDCARD_CS1);
    }

    bool spi_open(uint8_t index, nrf_drv_spi_frequency_t freq, nrf_drv_spi_mode_t mode)
    {
    
      if (index == SPI0)
      {
        nrf_drv_spi_config_t spi0_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    
        spi0_config.miso_pin = SPI0_MISO_PIN;
        spi0_config.mosi_pin = SPI0_MOSI_PIN;
        spi0_config.sck_pin = SPI0_SCK_PIN;  
          
        spi0_config.ss_pin = SDCARD_CS1;
        spi0_config.frequency = freq;
        spi0_config.mode = mode;
        spi0_config.orc = 0x00;
    
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi_0, &spi0_config, NULL, NULL)); // with blocking mode
      }
      else if (index == SPI1)
      {
        nrf_drv_spi_config_t spi1_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    
        spi1_config.miso_pin = SPI1_MISO_PIN;
        spi1_config.mosi_pin = SPI1_MOSI_PIN;
        spi1_config.sck_pin = SPI1_SCK_PIN;
    #if (SDCARD == ON)
        spi1_config.ss_pin = SDCARD_CS;
    #endif
    
        spi1_config.frequency = freq;
        spi1_config.mode = mode;
        spi1_config.orc = 0x00;
    
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi_1, &spi1_config, NULL, NULL)); // with blocking mode
      }
    }

    /*******************************************************************************
     * @fn        select
     *
     * @brief     Select the card and wait for ready
     *
     * @return    none
     */
    static int select(void)   /* 1:OK, 0:Timeout */
    {
        /* Set SDCARD_CS low */
        SetPin(SDCARD_CS, LOW);
       /* Dummy clock (force DO enabled) */
        spi_write(SPI1, wBuf, 1);
    
        return 1;
    }
    
    
    /*******************************************************************************
     * @fn        deselect
     *
     * @brief      Deselect the card and release SPI bus
     *
     * @return    none
     */
    static void deselect(void)
    {
        /* Set SDCARD_CS high */
        SetPin(SDCARD_CS, HIGH);
        /* Dummy clock (force DO hi-z for multiple slave SPI) */
        spi_write(SPI1, wBuf, 1);
    }

    I'm calling the deselect function after every spi write to sd card but i'm still getting the ss/cs (slave/chip select) pin as low (ss pin monitored in oscilloscope.

  • Hi,

    • Setting the slave select pin works but setting it high after a transfer doesn't work? Could you try disconnecting it from the output and see if it goes high?
    • Does the SPI example in the SDK work with your board properly? 

    regards

    Jared 

  • Hi 

    I got solution for this, the SPIM driver makes the slave select pin active high, making the pin low after the spi transfer is done and we can not make it high. I used SPI driver instead of SPIM driver to make the slave select pin high when there is no spi transfer. 

    The driver uses slave select pin as active high during transfer. Changing from nrfx_spim.c to nrfx_spi.c resolved the issue.

    /**
     * @brief SPIM master driver instance configuration structure.
     */
    typedef struct
    {
        uint8_t sck_pin;      ///< SCK pin number.
        uint8_t mosi_pin;     ///< MOSI pin number (optional).
                              /**< Set to @ref NRFX_SPIM_PIN_NOT_USED
                               *   if this signal is not needed. */
        uint8_t miso_pin;     ///< MISO pin number (optional).
                              /**< Set to @ref NRFX_SPIM_PIN_NOT_USED
                               *   if this signal is not needed. */
        uint8_t ss_pin;       ///< Slave Select pin number (optional).
                              /**< Set to @ref NRFX_SPIM_PIN_NOT_USED
                               *   if this signal is not needed. */
        bool ss_active_high;  ///< Polarity of the Slave Select pin during transmission.
        uint8_t irq_priority; ///< Interrupt priority.
        uint8_t orc;          ///< Over-run character.
                              /**< This character is used when all bytes from the TX buffer are sent,
                                   but the transfer continues due to RX. */
        nrf_spim_frequency_t frequency; ///< SPI frequency.
        nrf_spim_mode_t      mode;      ///< SPI mode.
        nrf_spim_bit_order_t bit_order; ///< SPI bit order.
    #if NRFX_CHECK(NRFX_SPIM_EXTENDED_ENABLED) || defined(__NRFX_DOXYGEN__)
        uint8_t              dcx_pin;     ///< D/CX pin number (optional).
        uint8_t              rx_delay;    ///< Sample delay for input serial data on MISO.
                                          /**< The value specifies the delay, in number of 64 MHz clock cycles
                                           *   (15.625 ns), from the the sampling edge of SCK (leading edge for
                                           *   CONFIG.CPHA = 0, trailing edge for CONFIG.CPHA = 1) until
                                           *   the input serial data is sampled.*/
        bool                 use_hw_ss;   ///< Indication to use software or hardware controlled Slave Select pin.
        uint8_t              ss_duration; ///< Slave Select duration before and after transmission.
                                          /**< Minimum duration between the edge of CSN and the edge of SCK and minimum
                                           *   duration of CSN must stay inactive between transactions.
                                           *   The value is specified in number of 64 MHz clock cycles (15.625 ns).
                                           *   Supported only for hardware controlled Slave Select.*/
    #endif
    } nrfx_spim_config_t;

    Thanks and regards

  • Hi,

    Good that you found the solution and returned with it.

    regards

    Jared 

Reply Children
No Data
Related