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.
