summaryrefslogtreecommitdiff
path: root/nrfdemo/src/bme680/bme680_spi.c
diff options
context:
space:
mode:
authorMichal Hanus <hanus.michal@divelit.cz>2025-04-23 13:43:14 +0200
committerMichal Hanus <hanus.michal@divelit.cz>2025-04-23 13:43:14 +0200
commitd1c04e8b36bc206eb520f7b79183d5c015855252 (patch)
tree469857024814e16b8ed27c52c5b8689358455f33 /nrfdemo/src/bme680/bme680_spi.c
parent851d92974af6cefa00de1379dad8b8076c2dd107 (diff)
parent0dee9f28ef79d54ec06f460b5e1deb10a8efd303 (diff)
Merge remote-tracking branch 'refs/remotes/xyz/master'
Diffstat (limited to 'nrfdemo/src/bme680/bme680_spi.c')
-rw-r--r--nrfdemo/src/bme680/bme680_spi.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/nrfdemo/src/bme680/bme680_spi.c b/nrfdemo/src/bme680/bme680_spi.c
new file mode 100644
index 0000000..54840a7
--- /dev/null
+++ b/nrfdemo/src/bme680/bme680_spi.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2016, 2017 Intel Corporation
+ * Copyright (c) 2017 IpTronix S.r.l.
+ * Copyright (c) 2021 Nordic Semiconductor ASA
+ * Copyright (c) 2022, Leonard Pollak
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/*
+ * Bus-specific functionality for BME680s accessed via SPI.
+ */
+
+#include <zephyr/logging/log.h>
+#include "bme680.h"
+
+#if BME680_BUS_SPI
+
+LOG_MODULE_DECLARE(bme680, CONFIG_SENSOR_LOG_LEVEL);
+
+static int bme680_bus_check_spi(const union bme680_bus *bus)
+{
+ return spi_is_ready_dt(&bus->spi) ? 0 : -ENODEV;
+}
+
+static inline int bme680_set_mem_page(const struct device *dev, uint8_t addr)
+{
+ const struct bme680_config *config = dev->config;
+ struct bme680_data *data = dev->data;
+ uint8_t page = (addr > 0x7f) ? 0U : 1U;
+ int err = 0;
+
+ if (data->mem_page != page) {
+ uint8_t buf[2];
+
+ struct spi_buf tx_buf = {
+ .buf = &buf[0],
+ .len = 1,
+ };
+ const struct spi_buf_set tx = {
+ .buffers = &tx_buf,
+ .count = 1,
+ };
+
+ const struct spi_buf rx_buf[] = {
+ { .buf = NULL, .len = 1 },
+ { .buf = &buf[1], .len = 1 },
+ };
+ const struct spi_buf_set rx = {
+ .buffers = rx_buf,
+ .count = ARRAY_SIZE(rx_buf),
+ };
+
+ buf[0] = BME680_REG_STATUS | BME680_SPI_READ_BIT;
+ err = spi_transceive_dt(&config->bus.spi, &tx, &rx);
+ if (err < 0) {
+ return err;
+ }
+
+ if (data->mem_page == 1U) {
+ buf[1] &= ~BME680_SPI_MEM_PAGE_MSK;
+ } else {
+ buf[1] |= BME680_SPI_MEM_PAGE_MSK;
+ }
+
+ buf[0] = BME680_REG_STATUS & BME680_SPI_WRITE_MSK;
+ tx_buf.len = 2;
+ err = spi_write_dt(&config->bus.spi, &tx);
+ if (err < 0) {
+ return err;
+ }
+
+ data->mem_page = page;
+ }
+
+ return err;
+}
+
+static int bme680_reg_write_spi(const struct device *dev,
+ uint8_t reg, uint8_t val)
+{
+ const struct bme680_config *config = dev->config;
+ int err;
+ uint8_t cmd[] = { reg & BME680_SPI_WRITE_MSK, val };
+ const struct spi_buf tx_buf = {
+ .buf = cmd,
+ .len = sizeof(cmd)
+ };
+ const struct spi_buf_set tx = {
+ .buffers = &tx_buf,
+ .count = 1
+ };
+
+ err = bme680_set_mem_page(dev, reg);
+ if (err) {
+ return err;
+ }
+
+ err = spi_write_dt(&config->bus.spi, &tx);
+
+ return err;
+}
+
+static int bme680_reg_read_spi(const struct device *dev,
+ uint8_t start, uint8_t *buf, int size)
+{
+ const struct bme680_config *config = dev->config;
+ int err;
+ uint8_t addr;
+ const struct spi_buf tx_buf = {
+ .buf = &addr,
+ .len = 1
+ };
+ const struct spi_buf_set tx = {
+ .buffers = &tx_buf,
+ .count = 1
+ };
+ struct spi_buf rx_buf[2];
+ const struct spi_buf_set rx = {
+ .buffers = rx_buf,
+ .count = ARRAY_SIZE(rx_buf)
+ };
+
+ rx_buf[0].buf = NULL;
+ rx_buf[0].len = 1;
+
+ addr = start | BME680_SPI_READ_BIT;
+ rx_buf[1].buf = buf;
+ rx_buf[1].len = size;
+
+ err = bme680_set_mem_page(dev, start);
+ if (err) {
+ return err;
+ }
+
+ err = spi_transceive_dt(&config->bus.spi, &tx, &rx);
+
+ return err;
+}
+
+const struct bme680_bus_io bme680_bus_io_spi = {
+ .check = bme680_bus_check_spi,
+ .read = bme680_reg_read_spi,
+ .write = bme680_reg_write_spi,
+};
+#endif /* BME680_BUS_SPI */