SPI communication issue (software problem)

Hello,

I am developing a system with the nRF52832 and SPI peripherals. I have been trying unsuccessfully for a while to resolve a communication issue with one of the devices (Bosch BME280). The strange thing is that (1) when examined with a logic probe, the MOSI and MISO signals are both correct. Also, (2) communication with another SPI peripheral works great. (Currently, I am working with the problematic peripheral in isolation, although eventually I need them to both function at the same time.)

This is all on a custom PCB, but based on the above, I am pretty sure it must be a software issue.

Reading CHIP_ID repeatedly (peripheral correctly supplies the value 0x60):

However, the nRF52 incorrectly gets the value 0x00.

<info> app: BME280 Chip ID: 0

My setup for the SPI interface is as follows:

void bme_init_interface(void)
{
// Init SPI interface

nrf_gpio_cfg_output(BME_SS_PIN); // Make chip select an output
nrf_gpio_cfg_output(MOSI_PIN); // Make MOSI an output
nrf_gpio_cfg_input(MISO_PIN, NRF_GPIO_PIN_NOPULL); // Make MISO an input

nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;

spi_config.ss_pin = NRFX_SPI_PIN_NOT_USED; // NOTE: can try this but chip select toggled manually in BME SPI functions
spi_config.miso_pin = MISO_PIN;
spi_config.mosi_pin = MOSI_PIN;
spi_config.sck_pin = SCK_PIN;
spi_config.frequency = NRF_SPI_FREQ_250K; // NOTE: Low freq for testing
spi_config.mode = NRF_DRV_SPI_MODE_0; // SCK active high (resting low), sample on leading edge of clock. (BME should be compatible with modes 00 and 11)
spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST; // MSB first according to timing diagrams in datasheet
spi_config.irq_priority = APP_IRQ_PRIORITY_HIGHEST; // highest priority level available to application (level 2, higher than default for SPI of 6)

APP_ERROR_CHECK(nrf_drv_spi_init(&spi_bme, &spi_config, spi_bme_event_handler, NULL));


// Lock BME into SPI mode
BME_CsClr(); // Do this before initializing AFE in order to lock BME in SPI mode without incidentally sending commands interpreted as I2C
nrf_delay_ms(3);
BME_CsSet();
nrf_delay_ms(10);

NRF_LOG_INFO("BME280 SPI initialized.");
}

I have triple-checked my pin assignments - MOSI on P0.00, SCLK on P0.01, MISO on P0.06, and !CS on P0.07.

// SPI pins
#define SCK_PIN 1 // SPI clock GPIO pin number.
#define MOSI_PIN 0 // SPI Master Out Slave In GPIO pin number.
#define MISO_PIN 6 // SPI Master In Slave Out GPIO pin number.

// SPI master - BME280 sensor
#define BME_SS_PIN 7 // SPI Slave Select GPIO pin number.
#define BME_SPI_INSTANCE 1 /**< SPI instance index. */

Do the experts have any ideas on what may be going wrong? Thanks in advance.

Parents Reply Children
  • SDK version: nRF5_SDK_17.0.2_d674dde
    I'm not sure which nRF52832 - how would I check that? SoftDevice is S132.
    I did upload the logic analyzer trace, it's in the post. I don't have a trace with all of the signals together, but that one shows CLK & MISO. Here is one more that shows CLK & MOSI for the same command.

  • Two issues most likely:

    1. The useful Rx data from the BME280 starts with the 2nd byte, not the first; the BME280 doesn't know what to send until it receives the first byte, so the id appears in the 2nd received byte. The first byte received and reported  in this case is 0x00, the 2nd byte 0x60. (Ignore this comment if you are already reporting the 2nd Rx byte)

    2. The logic probe is showing ideal signals which don't match actual signals in most cases; improve performance by setting all outputs (SCK, MOSI, CS) (in CNF) to H0H1 drive strength immediately after initializing the SPI peripheral. When all is working well you can experiment by reducing drive strength but there is no real advantage to doing that.

  • I just wanted to thank you for this suggestion to put the SCK and MOSI into H0H1 mode AFTER SPI init.

    The BMP585 has a minimum SPI SCK of 1MHz, but the signals from my nRF52_DK were too weak. The nRF52832_PS1.4 says to not adjust pin settings after enabling SPI, so I wouldn't have tried that without your suggestion. But when I wrote the PIN_CNF for those pins with H0H1, it works!

Related