1 /*
2  * Copyright (c) 2023 Würth Elektronik eiSos GmbH & Co. KG
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "weplatform_spi.h"
8 
9 #include <errno.h>
10 
11 #ifdef CONFIG_SPI
12 #include <zephyr/drivers/spi.h>
13 #endif /* CONFIG_SPI */
14 
15 /**
16  * @brief Read data starting from the addressed register via SPI
17  * @param[in] interface Sensor interface
18  * @param[in] regAdr The register address to read from
19  * @param[in] numBytesToRead Number of bytes to read
20  * @param[out] data The read data will be stored here
21  * @retval Error code
22  */
WE_ReadReg_SPI(WE_sensorInterface_t * interface,uint8_t regAdr,uint16_t numBytesToRead,uint8_t * data)23 inline int8_t WE_ReadReg_SPI(WE_sensorInterface_t *interface, uint8_t regAdr,
24 			     uint16_t numBytesToRead, uint8_t *data)
25 {
26 	int status = 0;
27 
28 #ifdef CONFIG_SPI
29 	uint8_t bytesStep = interface->options.spi.burstMode ? numBytesToRead : 1;
30 
31 	for (uint8_t i = 0; i < numBytesToRead; i += bytesStep) {
32 		uint8_t buffer_tx[2] = { (regAdr + i) | (1 << 7), 0 };
33 
34 		/*  Write 1 byte containing register address (MSB=1) + 1 dummy byte */
35 		const struct spi_buf tx_buf = { .buf = buffer_tx, .len = 2 };
36 		const struct spi_buf_set tx_buf_set = { .buffers = &tx_buf, .count = 1 };
37 
38 		/* Skip first byte, then read "bytesStep" bytes of data */
39 		const struct spi_buf rx_buf[2] = { { .buf = NULL, .len = 1 },
40 						   { .buf = data + i, .len = bytesStep } };
41 		const struct spi_buf_set rx_buf_set = { .buffers = rx_buf, .count = 2 };
42 
43 		status = spi_transceive_dt(interface->handle, &tx_buf_set, &rx_buf_set);
44 		if (status != 0) {
45 			/* Error, abort */
46 			break;
47 		}
48 	}
49 #else
50 	status = -EIO;
51 #endif /* CONFIG_SPI */
52 
53 	return status == 0 ? WE_SUCCESS : WE_FAIL;
54 }
55 
56 /**
57  * @brief Write data starting from the addressed register via SPI
58  * @param[in] interface Sensor interface
59  * @param[in] regAdr Address of register to be written
60  * @param[in] numBytesToWrite Number of bytes to write
61  * @param[in] data Data to be written
62  * @retval Error code
63  */
WE_WriteReg_SPI(WE_sensorInterface_t * interface,uint8_t regAdr,uint16_t numBytesToWrite,uint8_t * data)64 inline int8_t WE_WriteReg_SPI(WE_sensorInterface_t *interface, uint8_t regAdr,
65 			      uint16_t numBytesToWrite, uint8_t *data)
66 {
67 	int status = 0;
68 
69 #ifdef CONFIG_SPI
70 	uint8_t bytesStep = interface->options.spi.burstMode ? numBytesToWrite : 1;
71 
72 	for (uint8_t i = 0; i < numBytesToWrite; i += bytesStep) {
73 		uint8_t buffer_tx[1] = { (regAdr + i) & ~(1 << 7) };
74 
75 		/*
76 		 * First write 1 byte containing register address (MSB=0), then
77 		 * write "bytesStep" bytes of data
78 		 */
79 		const struct spi_buf tx_buf[2] = { { .buf = buffer_tx, .len = 1 },
80 						   { .buf = data + i, .len = bytesStep } };
81 		const struct spi_buf_set tx_buf_set = { .buffers = tx_buf, .count = 2 };
82 
83 		status = spi_write_dt(interface->handle, &tx_buf_set);
84 
85 		if (status != 0) {
86 			/* Error, abort */
87 			break;
88 		}
89 	}
90 #else
91 	status = -EIO;
92 #endif /* CONFIG_SPI */
93 
94 	return status == 0 ? WE_SUCCESS : WE_FAIL;
95 }
96