spi_transceive() writes zero into the buffer in runtime

Hello everyone,

I am working with a BMI160 6-DoF sensor. I have some drivers related to this chip. Using the Segger J-Link debugger the drivers just work fine without any issues I am able to read the data registers on the sensor via SPI interface.

uint8_t getData_bmx160(bmx160_spi * bmxIMU_spi_p, bmx160_sensor_data * sen_data)
{
...
    uint8_t data[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
    result = readReg_bmx160(bmxIMU_spi_p, BMX160_GYR_X_LSB_REG, data, 12);
...
}



int readReg_bmx160(bmx160_spi * bmxIMU_spi_p, uint8_t reg, uint8_t *data, size_t len)
{
    int result;
	unsigned char tx_buffer[2] = { 0, 0};

	tx_buffer[0] = 0x80 | reg;

	const struct spi_buf tx_buf = {
		.buf = tx_buffer,
		.len = 1,
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1,
	};

	struct spi_buf rx_buf[2] = {
		{
			.buf = tx_buffer,
			.len = 1,
		},
		{
			.buf = data,
			.len = len,
		}
	};

	const struct spi_buf_set rx = {
		.buffers = rx_buf,
		.count = 2,
	};
	gpio_pin_set(bmxIMU_spi_p->gpio0_dev, bmxIMU_spi_p->spi_cs_pin, 1);
	result = spi_transceive(bmxIMU_spi_p->spi_dev, &bmxIMU_spi_p->spi_cfg, &tx, &rx);
    gpio_pin_set(bmxIMU_spi_p->gpio0_dev, bmxIMU_spi_p->spi_cs_pin, 0);

	if (result) {
		return result;
	}

	return 0;
}

This is how the registers are read on the driver. However, when I switch to the runtime the 'data' is not updated even though 'spi_transceive(..)' returns >= 0 . 

  • Hello,

    Different behavior when you are using the debugger and not is some times caused by timing or clock issues. What HW are you testing this on? The nRF52832 DK? Or some custom HW? If it is custom HW, does it have an external LFXTAL?

    One thing you can test is to use a logic analyzer to capture a trace of the SPI pins. Is the correct data going out on the MOSI from the nRF? And is the data that you are looking for coming back in on the MISO? 

    When you say that it is working when you are debugging? Does it mean that you are stepping through the SPI part of the code? Perhaps you need to add a small delay after enabling the Chip Select (CS) pin and before you call spi_transceive()? It is at least worth a shot.

    When it doesn't work, what does spi_transceive return? I see that you store the return value in result. Is "result" always 0?

    Best regards,

    Edvin

Related