Reading LIS2DH12 register via SPI

Hi.

I am using a custom board on an nRF52810 microcontroller and a LIS2DH12 accelerometer connected to it via SPI. SDK version 2.7.0. 

Here's my settings:

.dts file -->

&spi0 {
    compatible = "nordic,nrf-spim";
	status = "okay";
	pinctrl-0 = <&spi0_default>;
	pinctrl-1 = <&spi0_sleep>;
	pinctrl-names = "default", "sleep";
	cs-gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
	
	lis2dh12: lis2dh12@0{
        compatible = "st,lis2dh";
        reg = <0>;
		spi-max-frequency = <10000000>;
    };
};

Devicetree visual editor screen -->

pinctrl file -->

&pinctrl {

	spi0_default: spi0_default {
		group1 {
				psels = <NRF_PSEL(SPIM_SCK, 0, 9)>,
						<NRF_PSEL(SPIM_MOSI, 0, 6)>,
						<NRF_PSEL(SPIM_MISO, 0, 7)>;
		};
	};

	spi0_sleep: spi0_sleep {
		group1 {
				psels = <NRF_PSEL(SPIM_SCK, 0, 9)>,
						<NRF_PSEL(SPIM_MOSI, 0, 6)>,
						<NRF_PSEL(SPIM_MISO, 0, 7)>;
				low-power-enable;
		};
	};

};

prj.conf -->

# Enable SPI
CONFIG_SPI=y

main.c code -->

...
#include <zephyr/drivers/spi.h>
...

#define SLEEP_TIME_MS   3000

#define SPIOP SPI_WORD_SET(8) | SPI_TRANSFER_MSB
struct spi_dt_spec lis2dh12_spi = SPI_DT_SPEC_GET(DT_NODELABEL(lis2dh12), SPIOP, 0);

int32_t lis2dh12_read_reg(uint8_t reg, uint8_t *data, uint8_t size)
{
  int ret;

  if (data == NULL || size == 0) {
    return -EINVAL;
  }
 
  uint8_t tx_buffer = reg | 0x80;
  struct spi_buf tx_spi_buf = {.buf = (void *)&tx_buffer, .len = 1};
  struct spi_buf_set tx_spi_buf_set = {.buffers = &tx_spi_buf, .count = 1};
  
  uint8_t rx_buffer[size + 1];
  struct spi_buf rx_spi_bufs = {.buf = rx_buffer, .len = size + 1};
  struct spi_buf_set rx_spi_buf_set = {.buffers = &rx_spi_bufs, .count = 1};

  ret = spi_transceive_dt(&lis2dh12_spi, &tx_spi_buf_set, &rx_spi_buf_set);
  if (ret < 0) {
    LOG_ERR("spi_transceive_dt() failed, err: %d", ret);
    return ret;
  }

  memcpy(data, rx_buffer + 1, size);

  return 0;
}

int main(void)
{ 	
	int ret;
	uint8_t who_am_i;

	if (!device_is_ready(lis2dh12_spi.bus)) {
    printf("SPI bus %s is not ready\n", lis2dh12_spi.bus->name);
    return 0;
	}

	while (1) {

   // Read register WHO_AM_I
    ret = lis2dh12_read_reg(0x0F, &who_am_i, 1);
    if (ret == 0) {
        LOG_DBG("WHO_AM_I value: 0x%02X", who_am_i);
        if (who_am_i == 0x33) {  // 0x33 - expected value for LIS2DH12
            LOG_DBG("LIS2DH12 successfully identified");
        } else {
            LOG_DBG("Unexpected value WHO_AM_I\n");
        }
    } else {
        LOG_DBG("Error reading WHO_AM_I: %d\n", ret);
    }

	    k_msleep(SLEEP_TIME_MS);
	}
	
	return 0;
}

Terminal output -->

Logic analyzer output -->

As you can see, I get the wrong WHO_AM_I register value when reading. For some reason there is no signal on the SCK line (although there is physical contact between the microcontroller and LIS2DH12). Perhaps I made a mistake in the dts setup or code?
Please help me to solve this problem.

Also I don't understand why in devicetree editor the maximum frequency is 8MHz, although I set it to 10MHz?

Thanks.

Related