SPI not working

Dear Ladies and Gentlemen,

I am trying to get a DPS310 pressure sensor to work via SPI. As I use I2C for other purposes, I chose SPI1 channel. The given SPI example in SDK 17.02 sadly still uses the legacy driver, I wanted to use the new nrfx interface described in:

https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/group__nrf__spi.html

So I coded:

#include "spi.h"

#define strLen 64
enum pin_t{_red=0, _green=1, __red=4, __green=8, __bt1=31, __sck=26, __mosi=27, __miso=7, __csbar=22};

#define SPI_INSTANCE  1 /**< SPI instance index. */
static const nrfx_spi_t spi = NRFX_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */

static uint8_t       m_rx_buf[strLen + 1];    /**< RX buffer. */
static const uint8_t m_length = strLen;       /**< Transfer length. */

/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrfx_spi_evt_t const* p_event, void* p_context)
{
    spi_xfer_done = true;
    NRF_LOG_INFO("Transfer completed.");
    if (m_rx_buf[0] != 0)
    {
        NRF_LOG_INFO(" Received:");
        NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    }
}

char* DPS_reg_read(uint8_t regIndex)
{
    ret_code_t err_code;
    uint8_t regSel[1];
    regSel[0]=regIndex;
    memset(m_rx_buf, 0, m_length);
    spi_xfer_done = false;

    nrfx_spi_xfer_desc_t m_pos_write;
    m_pos_write.p_tx_buffer = regSel;
    m_pos_write.tx_length = sizeof(regSel);
    m_pos_write.p_rx_buffer = m_rx_buf;
    m_pos_write.rx_length = m_length;

    //nrf_gpio_pin_clear(__csbar);   //Set CS to 0 (on)

    err_code=nrfx_spi_xfer(&spi, &m_pos_write, 0);
    APP_ERROR_CHECK(err_code);
    while (!spi_xfer_done)
    {
        __WFE();
    }
    //nrf_gpio_pin_set(__csbar);   //Set CS to 1 (off)
    return m_rx_buf;
}

/**@brief Function for initializing the nrf log module. */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}

int main(void)
{
    log_init();
    NRF_LOG_INFO("Log on.");
    nrfx_spi_config_t spi_config = NRFX_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = __csbar;//SPI_SS_PIN;
    spi_config.miso_pin = __miso;//SPI_MISO_PIN;
    spi_config.mosi_pin = __mosi;//SPI_MOSI_PIN;
    spi_config.sck_pin  = __sck;//SPI_SCK_PIN;
    err_code = nrfx_spi_init(&spi, &spi_config, spi_event_handler, NULL);
    APP_ERROR_CHECK(err_code);
    char* res=DPS_reg_read(0x28);
    NRF_LOG_INFO("Read: %d", res[0]);
    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
    return 0;
}

But the example never puts out anything as soon as I call DPS_reg_read(); I also tried commenting out the __WFE(); in completion loop, but this also failed. I never saw, that the spi event handler reported transfer complete. Can you give advice, what must be done to get SPI to run?

Best regards,

Richard

Parents
  • Reopening needed:

    I can read the registers of the DPS310 with my configuration, but I fail to write. As I can read now, I assume, that my configuration (HW/SW) is correct, because reading requires the DPS310 to be informed about which register is to be read (Data-line to SPI slave) and the Nordic BM833 to obtain the value (Data-line from slave). There is one major thing I wonder about now:

    Currently, I have the following enabled:

    // <e> NRFX_SPI_ENABLED - nrfx_spi - SPI peripheral driver
    //==========================================================
    #ifndef NRFX_SPI_ENABLED
    #define NRFX_SPI_ENABLED 1
    #endif
    // <q> NRFX_SPI0_ENABLED  - Enable SPI0 instance
     
    
    #ifndef NRFX_SPI0_ENABLED
    #define NRFX_SPI0_ENABLED 0
    #endif
    
    // <q> NRFX_SPI1_ENABLED  - Enable SPI1 instance
     
    
    #ifndef NRFX_SPI1_ENABLED
    #define NRFX_SPI1_ENABLED 1
    #endif
    

    But i did not include/enable SPIM. Is that additionally required?

    Finally:

    If there is a secondary SPI slave connected to the same SPI bus (using same sck/miso/mosi pins but, of course, another ss_pin), what is programming best-practice to repeatedly (with fixed-interval) switch between devices?

    Best regards,

    Richard

  • You should get a logic analyzer to check the actual data on spi, the problem can be any kind of misconfiguration (e.g. wrong spi mode can cause reading to marginally work, while writing fails etc).

    There is no problem to have multiple slaves devices, just make sure to control the ss_pin's such that only one slave is interfaced at a time.

    Kenneth

Reply Children
No Data
Related