1 /* ieee802154_rf2xx_iface.c - ATMEL RF2XX IEEE 802.15.4 Interface */
2 
3 /*
4  * Copyright (c) 2019-2020 Gerson Fernando Budke
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #define LOG_MODULE_NAME ieee802154_rf2xx_iface
10 #define LOG_LEVEL CONFIG_IEEE802154_DRIVER_LOG_LEVEL
11 
12 #include <zephyr/logging/log.h>
13 LOG_MODULE_REGISTER(LOG_MODULE_NAME);
14 
15 #include <errno.h>
16 
17 #include <zephyr/device.h>
18 #include <zephyr/drivers/spi.h>
19 #include <zephyr/drivers/gpio.h>
20 
21 #include <zephyr/net/ieee802154_radio.h>
22 
23 #include "ieee802154_rf2xx.h"
24 #include "ieee802154_rf2xx_regs.h"
25 #include "ieee802154_rf2xx_iface.h"
26 
rf2xx_iface_phy_rst(const struct device * dev)27 void rf2xx_iface_phy_rst(const struct device *dev)
28 {
29 	const struct rf2xx_config *conf = dev->config;
30 
31 	/* Ensure control lines have correct levels. */
32 	gpio_pin_set_dt(&conf->reset_gpio, 0);
33 	gpio_pin_set_dt(&conf->slptr_gpio, 0);
34 
35 	/* Wait typical time of timer TR1. */
36 	k_busy_wait(330);
37 
38 	gpio_pin_set_dt(&conf->reset_gpio, 1);
39 	k_busy_wait(10);
40 	gpio_pin_set_dt(&conf->reset_gpio, 0);
41 }
rf2xx_iface_phy_tx_start(const struct device * dev)42 void rf2xx_iface_phy_tx_start(const struct device *dev)
43 {
44 	const struct rf2xx_config *conf = dev->config;
45 
46 	/* Start TX transmission at rise edge */
47 	gpio_pin_set_dt(&conf->slptr_gpio, 1);
48 	/* 16.125[μs] delay to detect signal */
49 	k_busy_wait(20);
50 	/* restore initial pin state */
51 	gpio_pin_set_dt(&conf->slptr_gpio, 0);
52 }
53 
rf2xx_iface_reg_read(const struct device * dev,uint8_t addr)54 uint8_t rf2xx_iface_reg_read(const struct device *dev,
55 			     uint8_t addr)
56 {
57 	const struct rf2xx_config *conf = dev->config;
58 	uint8_t status;
59 	uint8_t regval = 0;
60 
61 	addr |= RF2XX_RF_CMD_REG_R;
62 
63 	const struct spi_buf tx_buf = {
64 		.buf = &addr,
65 		.len = 1
66 	};
67 	const struct spi_buf_set tx = {
68 		.buffers = &tx_buf,
69 		.count = 1
70 	};
71 	const struct spi_buf rx_buf[2] = {
72 		{
73 			.buf = &status,
74 			.len = 1
75 		},
76 		{
77 			.buf = &regval,
78 			.len = 1
79 		},
80 	};
81 	const struct spi_buf_set rx = {
82 		.buffers = rx_buf,
83 		.count = 2
84 	};
85 
86 	if (spi_transceive_dt(&conf->spi, &tx, &rx) != 0) {
87 		LOG_ERR("Failed to exec rf2xx_reg_read CMD at address %d",
88 			addr);
89 	}
90 
91 	LOG_DBG("Read Address: %02X, PhyStatus: %02X, RegVal: %02X",
92 		(addr & ~(RF2XX_RF_CMD_REG_R)), status, regval);
93 
94 	return regval;
95 }
96 
rf2xx_iface_reg_write(const struct device * dev,uint8_t addr,uint8_t data)97 void rf2xx_iface_reg_write(const struct device *dev,
98 			   uint8_t addr,
99 			   uint8_t data)
100 {
101 	const struct rf2xx_config *conf = dev->config;
102 	uint8_t status;
103 
104 	addr |= RF2XX_RF_CMD_REG_W;
105 
106 	const struct spi_buf tx_buf[2] = {
107 		{
108 			.buf = &addr,
109 			.len = 1
110 		},
111 		{
112 			.buf = &data,
113 			.len = 1
114 		}
115 	};
116 	const struct spi_buf_set tx = {
117 		.buffers = tx_buf,
118 		.count = 2
119 	};
120 	const struct spi_buf rx_buf = {
121 		.buf = &status,
122 		.len = 1
123 	};
124 	const struct spi_buf_set rx = {
125 		.buffers = &rx_buf,
126 		.count = 1
127 	};
128 
129 	if (spi_transceive_dt(&conf->spi, &tx, &rx) != 0) {
130 		LOG_ERR("Failed to exec rf2xx_reg_write at address %d",
131 			addr);
132 	}
133 
134 	LOG_DBG("Write Address: %02X, PhyStatus: %02X, RegVal: %02X",
135 		(addr & ~(RF2XX_RF_CMD_REG_W)), status, data);
136 }
137 
rf2xx_iface_bit_read(const struct device * dev,uint8_t addr,uint8_t mask,uint8_t pos)138 uint8_t rf2xx_iface_bit_read(const struct device *dev,
139 			     uint8_t addr,
140 			     uint8_t mask,
141 			     uint8_t pos)
142 {
143 	uint8_t ret;
144 
145 	ret = rf2xx_iface_reg_read(dev, addr);
146 	ret &= mask;
147 	ret >>= pos;
148 
149 	return ret;
150 }
151 
rf2xx_iface_bit_write(const struct device * dev,uint8_t reg_addr,uint8_t mask,uint8_t pos,uint8_t new_value)152 void rf2xx_iface_bit_write(const struct device *dev,
153 			   uint8_t reg_addr,
154 			   uint8_t mask,
155 			   uint8_t pos,
156 			   uint8_t new_value)
157 {
158 	uint8_t current_reg_value;
159 
160 	current_reg_value = rf2xx_iface_reg_read(dev, reg_addr);
161 	current_reg_value &= ~mask;
162 	new_value <<= pos;
163 	new_value &= mask;
164 	new_value |= current_reg_value;
165 	rf2xx_iface_reg_write(dev, reg_addr, new_value);
166 }
167 
rf2xx_iface_frame_read(const struct device * dev,uint8_t * data,uint8_t length)168 void rf2xx_iface_frame_read(const struct device *dev,
169 			    uint8_t *data,
170 			    uint8_t length)
171 {
172 	const struct rf2xx_config *conf = dev->config;
173 	uint8_t cmd = RF2XX_RF_CMD_FRAME_R;
174 
175 	const struct spi_buf tx_buf = {
176 		.buf = &cmd,
177 		.len = 1
178 	};
179 	const struct spi_buf_set tx = {
180 		.buffers = &tx_buf,
181 		.count = 1
182 	};
183 	const struct spi_buf rx_buf = {
184 		.buf = data,
185 		.len = length
186 	};
187 	const struct spi_buf_set rx = {
188 		.buffers = &rx_buf,
189 		.count = 1
190 	};
191 
192 	if (spi_transceive_dt(&conf->spi, &tx, &rx) != 0) {
193 		LOG_ERR("Failed to exec rf2xx_frame_read PHR");
194 	}
195 
196 	LOG_DBG("Frame R: PhyStatus: %02X. length: %02X", data[0], length);
197 	LOG_HEXDUMP_DBG(data + RX2XX_FRAME_HEADER_SIZE, length, "payload");
198 }
199 
rf2xx_iface_frame_write(const struct device * dev,uint8_t * data,uint8_t length)200 void rf2xx_iface_frame_write(const struct device *dev,
201 			     uint8_t *data,
202 			     uint8_t length)
203 {
204 	const struct rf2xx_config *conf = dev->config;
205 	uint8_t cmd = RF2XX_RF_CMD_FRAME_W;
206 	uint8_t status;
207 	uint8_t phr;
208 
209 	/* Sanity check */
210 	if (length > 125) {
211 		length = 125;
212 	}
213 
214 	phr = length + RX2XX_FRAME_FCS_LENGTH;
215 
216 	const struct spi_buf tx_buf[3] = {
217 		{
218 			.buf = &cmd,
219 			.len = 1
220 		},
221 		{
222 			.buf = &phr,    /* PHR */
223 			.len = 1
224 		},
225 		{
226 			.buf = data,    /* PSDU */
227 			.len = length
228 		},
229 	};
230 	const struct spi_buf_set tx = {
231 		.buffers = tx_buf,
232 		.count = 3
233 	};
234 	const struct spi_buf rx_buf = {
235 		.buf = &status,
236 		.len = 1
237 	};
238 	const struct spi_buf_set rx = {
239 		.buffers = &rx_buf,
240 		.count = 1
241 	};
242 
243 	if (spi_transceive_dt(&conf->spi, &tx, &rx) != 0) {
244 		LOG_ERR("Failed to exec rf2xx_frame_write");
245 	}
246 
247 	LOG_DBG("Frame W: PhyStatus: %02X. length: %02X", status, length);
248 	LOG_HEXDUMP_DBG(data, length, "payload");
249 }
250 
rf2xx_iface_sram_read(const struct device * dev,uint8_t address,uint8_t * data,uint8_t length)251 void rf2xx_iface_sram_read(const struct device *dev,
252 			    uint8_t address,
253 			    uint8_t *data,
254 			    uint8_t length)
255 {
256 	const struct rf2xx_config *conf = dev->config;
257 	uint8_t cmd = RF2XX_RF_CMD_SRAM_R;
258 	uint8_t status[2];
259 
260 	const struct spi_buf tx_buf[2] = {
261 		{
262 			.buf = &cmd,
263 			.len = 1
264 		},
265 		{
266 			.buf = &address,
267 			.len = 1
268 		},
269 	};
270 	const struct spi_buf_set tx = {
271 		.buffers = tx_buf,
272 		.count = 2
273 	};
274 	const struct spi_buf rx_buf[2] = {
275 		{
276 			.buf = status,
277 			.len = 2
278 		},
279 		{
280 			.buf = data,
281 			.len = length
282 		},
283 	};
284 	const struct spi_buf_set rx = {
285 		.buffers = rx_buf,
286 		.count = 2
287 	};
288 
289 	if (spi_transceive_dt(&conf->spi, &tx, &rx) != 0) {
290 		LOG_ERR("Failed to exec rf2xx_sram_read");
291 	}
292 
293 	LOG_DBG("SRAM R: length: %02X, status: %02X", length, status[0]);
294 	LOG_HEXDUMP_DBG(data, length, "content");
295 }
296