SPI Master can't work together with bluetooth stack

Hello Nordic,

I want to use SPI master with bluetooth on nrf52840 board. When I use the project under nRF5_SDK_17.1.0\examples\peripheral\spi, I can see the clock signal under oscilloscope. But when I add the SPI master code into the project of nRF5_SDK_17.1.0\examples\ble_peripheral\ble_app_uart. I can not see clock signal under oscilloscope. And I notice that the SPI master is blank project, and the bluetooth is s140 project. Can you give me any suggestion about this problem?

  • I get clock signal on oscilloscope now, master should send data periodically.

  • Hi,

    Can you post the code where you have integrated SPI with ble_app_uart?

    Do you start the transfer(s) from main or interrupt context?

    Which GPIOs are you using for MOSI and MISO?

    Is the other parts of the application working as expected?

    Do you run this on a nRF52840 DK, or on a custom board?

    Best regards,
    Jørgen

  • Hello Jorgen, thanks for your reply. I get this issue fixed. When I send data periodically, I can get clock wave signal on oscilloscope. Actually, I want to use SPI master to write/read ADS1293 registers. But I always read the data is 0x00, even though no MISO and MOSI connected. Can you help to investigate it? Below is my code:

    #define SPI_INSTANCE 0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_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_tx_buf[2]; /**< TX buffer. */
    static uint8_t m_rx_buf[2]; /**< RX buffer. */
    static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */

    static const uint8_t ADS1293_SS = USER_SPI_ADS1293_SS; // SPI_SS_PIN
    static const uint8_t ADS1293_DRDYB = USER_SPI_ADS1293_DRDYB;

    // Useful definitions
    #define ADS1293_READ_BIT (0x80)
    #define ADS1293_WRITE_BIT (0x7F)


    void spi_event_handler(nrf_drv_spi_evt_t const * p_event, void * p_context)
    {
    spi_xfer_done = true;
    //printf("Transfer completed.\n");
    if (m_rx_buf[0] != 0)
    {
    printf("Received: 0x%x\n", m_rx_buf[0]);
    //NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
    }
    }

    static void ads1293_write_reg(uint8_t addr, uint8_t value)
    {
    nrf_gpio_pin_clear(ADS1293_SS);

    user_spi_wdata(ADS1293_WRITE_BIT & addr);
    user_spi_wdata(value);

    nrf_gpio_pin_set(ADS1293_SS);
    }

    static uint8_t ads1293_read_reg(uint8_t addr)
    {
    uint8_t value = 0;

    nrf_gpio_pin_clear(ADS1293_SS);

    value = user_spi_rdata(ADS1293_READ_BIT | addr);

    nrf_gpio_pin_set(ADS1293_SS);

    return value;
    }

    #define NRF_DRV_SPI_DEFAULT_CONFIG \
    { \
    .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \
    .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \
    .orc = 0xFF, \
    .frequency = NRF_DRV_SPI_FREQ_1M, \
    .mode = NRF_DRV_SPI_MODE_0, \
    .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \
    }

    void user_spi_service_init(void)
    {
    nrf_gpio_pin_dir_set(ADS1293_SS, NRF_GPIO_PIN_DIR_OUTPUT);
    nrf_gpio_pin_dir_set(ADS1293_DRDYB, GPIO_PIN_CNF_DIR_Input);

    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;
    spi_config.miso_pin = SPI_MISO_PIN; //USER_SPI_MISO_PIN; //
    spi_config.mosi_pin = SPI_MOSI_PIN; //USER_SPI_MOSI_PIN; //
    spi_config.sck_pin = SPI_SCK_PIN; //USER_SPI_SCK_PIN; //

    APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
    }

    static void user_spi_wdata(uint8_t data)
    {
    spi_xfer_done = false;

    m_tx_buf[0] = data;

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, 0));

    while (!spi_xfer_done)
    {
    __WFE();
    }
    }

    static uint8_t user_spi_rdata(uint8_t data)
    {
    spi_xfer_done = false;

    m_tx_buf[0] = data;
    m_tx_buf[1] = 0x00;

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 2, m_rx_buf, 1));

    while (!spi_xfer_done)
    {
    __WFE();
    }

    return m_rx_buf[0];
    }

    void main(void)
    {
    user_spi_service_init();

    for(; ;)
    {
    uint8_t reg_data, reg_addr;

    nrf_delay_ms(1000);

    reg_addr = 0x01;
    ads1293_write_reg(0x01, 0x11);
    reg_data = ads1293_read_reg(reg_addr);

    printf("reg_addr = 0x%x, reg_data = 0x%x\n", reg_addr, reg_data);
    }
    }

    The following is result:

  • It seems you are passing wrong length parameters to nrf_drv_spi_transfer(). If your intention is to write 1 or 2 bytes, then read out 1 byte after writing is done, you need to set the rx_length parameter to tx_length + rx_length. The RX buffer will start filling when you clock out data from TX buffer, and will stop when you reach the specified rx_length. The function will not first do TX and then do RX after this, as some SPI devices may support full duplex write/read operations (write address for next read while you read out data from last write, etc).

    AllenSun said:
    But I always read the data is 0x00, even though no MISO and MOSI connected

    If the pins are not connected, why do you expect different values?

  • Jorgen, Thank you for your reply. But it still does not work, even if I set rx_length as you said. Both m_rx_buf[0]  and m_rx_buf[1] are 0x00. Do you have sample code of Nrf52840 write/read Ads1293 correctly? 

    static uint8_t ads1293_read_reg(uint8_t addr)
    {
    uint8_t value = 0;

    nrf_gpio_pin_clear(ADS1293_SS);

    user_spi_wdata(ADS1293_READ_BIT | addr);

    value = user_spi_rdata(0x00);

    nrf_gpio_pin_set(ADS1293_SS);

    return value;
    }

    static uint8_t user_spi_rdata(uint8_t data)
    {
    spi_xfer_done = false;

    m_tx_buf[0] = data;
    m_rx_buf[0] = 0xff;
    m_rx_buf[1] = 0xff;

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, 1, m_rx_buf, 2));

    while (!spi_xfer_done)
    {
    __WFE();
    }

    if(m_rx_buf[0] == 0){printf("0x%x", m_rx_buf[0]);}
    if(m_rx_buf[1] == 0){printf("0x%x", m_rx_buf[1]);}

    return m_rx_buf[1];
    }

     

Related