1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2024 Carl Zeiss Meditec AG
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <zephyr/sys/util.h>
7 
8 #include "adi_tmc_spi.h"
9 
10 #define BUFFER_SIZE 5U
11 
12 #include <zephyr/logging/log.h>
13 
14 LOG_MODULE_REGISTER(tmc_spi, CONFIG_SPI_LOG_LEVEL);
15 
parse_tmc_spi_status(const uint8_t status_byte)16 static void parse_tmc_spi_status(const uint8_t status_byte)
17 {
18 	if ((status_byte & BIT_MASK(0)) != 0) {
19 		LOG_WRN("spi dataframe: reset_flag detected");
20 	}
21 	if ((status_byte & BIT_MASK(1)) != 0) {
22 		LOG_WRN("spi dataframe: driver_error(1) detected");
23 	}
24 	if ((status_byte & BIT_MASK(2)) != 0) {
25 		LOG_WRN("spi dataframe: driver_error(2) detected");
26 	}
27 }
28 
print_tx_rx_buffer(const uint8_t * const tx_buffer,const uint8_t * const rx_buffer)29 static void print_tx_rx_buffer(const uint8_t *const tx_buffer, const uint8_t *const rx_buffer)
30 {
31 	LOG_HEXDUMP_DBG(tx_buffer, BUFFER_SIZE, "TX: ");
32 	LOG_HEXDUMP_DBG(rx_buffer, BUFFER_SIZE, "RX: ");
33 }
34 
tmc_spi_read_register(const struct spi_dt_spec * bus,const uint8_t read_address_mask,const uint8_t register_address,uint32_t * data)35 int tmc_spi_read_register(const struct spi_dt_spec *bus, const uint8_t read_address_mask,
36 			  const uint8_t register_address, uint32_t *data)
37 {
38 	uint8_t tx_buffer[BUFFER_SIZE] = {read_address_mask & register_address, 0U, 0U, 0U, 0U};
39 	uint8_t rx_buffer[BUFFER_SIZE];
40 	int status;
41 
42 	const struct spi_buf spi_buffer_tx = {
43 		.buf = &tx_buffer,
44 		.len = sizeof(tx_buffer),
45 	};
46 	struct spi_buf_set spi_buffer_array_tx = {
47 		.buffers = &spi_buffer_tx,
48 		.count = 1U,
49 	};
50 
51 	struct spi_buf spi_buffer_rx = {
52 		.buf = &rx_buffer,
53 		.len = sizeof(rx_buffer),
54 	};
55 	struct spi_buf_set spi_buffer_array_rx = {
56 		.buffers = &spi_buffer_rx,
57 		.count = 1U,
58 	};
59 
60 	/** send read with the address byte */
61 	status = spi_transceive_dt(bus, &spi_buffer_array_tx, &spi_buffer_array_rx);
62 	if (status < 0) {
63 		return status;
64 	}
65 
66 	print_tx_rx_buffer(tx_buffer, rx_buffer);
67 	parse_tmc_spi_status(rx_buffer[0]);
68 
69 	/** read the value from the address */
70 	status = spi_transceive_dt(bus, &spi_buffer_array_tx, &spi_buffer_array_rx);
71 	if (status < 0) {
72 		return status;
73 	}
74 
75 	*data = ((uint32_t)rx_buffer[1] << 24) + ((uint32_t)rx_buffer[2] << 16) +
76 		((uint32_t)rx_buffer[3] << 8) + (uint32_t)rx_buffer[4];
77 
78 	print_tx_rx_buffer(tx_buffer, rx_buffer);
79 	parse_tmc_spi_status(rx_buffer[0]);
80 	return status;
81 }
82 
tmc_spi_write_register(const struct spi_dt_spec * bus,const uint8_t write_bit,const uint8_t register_address,const uint32_t data)83 int tmc_spi_write_register(const struct spi_dt_spec *bus, const uint8_t write_bit,
84 			   const uint8_t register_address, const uint32_t data)
85 {
86 	uint8_t tx_buffer[BUFFER_SIZE] = {write_bit | register_address, data >> 24, data >> 16,
87 					  data >> 8, data};
88 	uint8_t rx_buffer[BUFFER_SIZE];
89 	int status;
90 
91 	const struct spi_buf spi_buffer_tx = {
92 		.buf = &tx_buffer,
93 		.len = sizeof(tx_buffer),
94 	};
95 	struct spi_buf_set spi_buffer_array_tx = {
96 		.buffers = &spi_buffer_tx,
97 		.count = 1U,
98 	};
99 
100 	struct spi_buf spi_buffer_rx = {
101 		.buf = &rx_buffer,
102 		.len = sizeof(rx_buffer),
103 	};
104 	struct spi_buf_set spi_buffer_array_rx = {
105 		.buffers = &spi_buffer_rx,
106 		.count = 1U,
107 	};
108 
109 	status = spi_transceive_dt(bus, &spi_buffer_array_tx, &spi_buffer_array_rx);
110 	if (status < 0) {
111 		return status;
112 	}
113 
114 	print_tx_rx_buffer(tx_buffer, rx_buffer);
115 	parse_tmc_spi_status(rx_buffer[0]);
116 
117 	return status;
118 }
119