Line data Source code
1 1 : /*
2 : * Copyright (c) 2018 Roman Tataurov <diytronic@yandex.ru>
3 : * Copyright (c) 2022 Thomas Stranger
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /**
9 : * @file zephyr/drivers/w1.h
10 : * @ingroup w1_interface
11 : * @brief Main header file for 1-Wire driver API.
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_DRIVERS_W1_H_
15 : #define ZEPHYR_INCLUDE_DRIVERS_W1_H_
16 :
17 : #include <zephyr/types.h>
18 : #include <zephyr/device.h>
19 : #include <zephyr/kernel.h>
20 : #include <zephyr/sys/crc.h>
21 : #include <zephyr/sys/byteorder.h>
22 :
23 : #ifdef __cplusplus
24 : extern "C" {
25 : #endif
26 :
27 : /**
28 : * @brief Interfaces for 1-Wire devices.
29 : * @defgroup w1_interface 1-Wire
30 : * @since 3.2
31 : * @version 0.1.0
32 : * @ingroup io_interfaces
33 : * @{
34 : */
35 :
36 : /** @cond INTERNAL_HIDDEN */
37 :
38 : /*
39 : * Count the number of slaves expected on the bus.
40 : * This can be used to decide if the bus has a multidrop topology or
41 : * only a single slave is present.
42 : * There is a comma after each ordinal (including the last)
43 : * Hence FOR_EACH adds "+1" once too often which has to be subtracted in the end.
44 : */
45 : #define F1(x) 1
46 : #define W1_SLAVE_COUNT(node_id) \
47 : (FOR_EACH(F1, (+), DT_SUPPORTS_DEP_ORDS(node_id)) - 1)
48 : #define W1_INST_SLAVE_COUNT(inst) \
49 : (W1_SLAVE_COUNT(DT_DRV_INST(inst)))
50 :
51 : /** @endcond */
52 :
53 : /**
54 : * @brief Defines the 1-Wire master settings types, which are runtime configurable.
55 : */
56 1 : enum w1_settings_type {
57 : /** Overdrive speed is enabled in case a value of 1 is passed and
58 : * disabled passing 0.
59 : */
60 : W1_SETTING_SPEED,
61 : /**
62 : * The strong pullup resistor is activated immediately after the next
63 : * written data block by passing a value of 1, and deactivated passing 0.
64 : */
65 : W1_SETTING_STRONG_PULLUP,
66 :
67 : /**
68 : * Number of different settings types.
69 : */
70 : W1_SETINGS_TYPE_COUNT,
71 : };
72 :
73 : /** @cond INTERNAL_HIDDEN */
74 :
75 : /** Configuration common to all 1-Wire master implementations. */
76 : struct w1_master_config {
77 : /* Number of connected slaves */
78 : uint16_t slave_count;
79 : };
80 :
81 : /** Data common to all 1-Wire master implementations. */
82 : struct w1_master_data {
83 : /* The mutex used by w1_lock_bus and w1_unlock_bus methods */
84 : struct k_mutex bus_lock;
85 : };
86 :
87 : typedef int (*w1_reset_bus_t)(const struct device *dev);
88 : typedef int (*w1_read_bit_t)(const struct device *dev);
89 : typedef int (*w1_write_bit_t)(const struct device *dev, bool bit);
90 : typedef int (*w1_read_byte_t)(const struct device *dev);
91 : typedef int (*w1_write_byte_t)(const struct device *dev, const uint8_t byte);
92 : typedef int (*w1_read_block_t)(const struct device *dev, uint8_t *buffer,
93 : size_t len);
94 : typedef int (*w1_write_block_t)(const struct device *dev, const uint8_t *buffer,
95 : size_t len);
96 : typedef size_t (*w1_get_slave_count_t)(const struct device *dev);
97 : typedef int (*w1_configure_t)(const struct device *dev,
98 : enum w1_settings_type type, uint32_t value);
99 : typedef int (*w1_change_bus_lock_t)(const struct device *dev, bool lock);
100 :
101 : __subsystem struct w1_driver_api {
102 : w1_reset_bus_t reset_bus;
103 : w1_read_bit_t read_bit;
104 : w1_write_bit_t write_bit;
105 : w1_read_byte_t read_byte;
106 : w1_write_byte_t write_byte;
107 : w1_read_block_t read_block;
108 : w1_write_block_t write_block;
109 : w1_configure_t configure;
110 : w1_change_bus_lock_t change_bus_lock;
111 : };
112 : /** @endcond */
113 :
114 : /** @cond INTERNAL_HIDDEN */
115 : __syscall int w1_change_bus_lock(const struct device *dev, bool lock);
116 :
117 : static inline int z_impl_w1_change_bus_lock(const struct device *dev, bool lock)
118 : {
119 : struct w1_master_data *ctrl_data = (struct w1_master_data *)dev->data;
120 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
121 :
122 : if (api->change_bus_lock) {
123 : return api->change_bus_lock(dev, lock);
124 : }
125 :
126 : if (lock) {
127 : return k_mutex_lock(&ctrl_data->bus_lock, K_FOREVER);
128 : } else {
129 : return k_mutex_unlock(&ctrl_data->bus_lock);
130 : }
131 : }
132 : /** @endcond */
133 :
134 : /**
135 : * @brief Lock the 1-wire bus to prevent simultaneous access.
136 : *
137 : * This routine locks the bus to prevent simultaneous access from different
138 : * threads. The calling thread waits until the bus becomes available.
139 : * A thread is permitted to lock a mutex it has already locked.
140 : *
141 : * @param[in] dev Pointer to the device structure for the driver instance.
142 : *
143 : * @retval 0 If successful.
144 : * @retval -errno Negative error code on error.
145 : */
146 1 : static inline int w1_lock_bus(const struct device *dev)
147 : {
148 : return w1_change_bus_lock(dev, true);
149 : }
150 :
151 : /**
152 : * @brief Unlock the 1-wire bus.
153 : *
154 : * This routine unlocks the bus to permit access to bus line.
155 : *
156 : * @param[in] dev Pointer to the device structure for the driver instance.
157 : *
158 : * @retval 0 If successful.
159 : * @retval -errno Negative error code on error.
160 : */
161 1 : static inline int w1_unlock_bus(const struct device *dev)
162 : {
163 : return w1_change_bus_lock(dev, false);
164 : }
165 :
166 : /**
167 : * @brief 1-Wire data link layer
168 : * @defgroup w1_data_link 1-Wire data link layer
169 : * @ingroup w1_interface
170 : * @{
171 : */
172 :
173 : /**
174 : * @brief Reset the 1-Wire bus to prepare slaves for communication.
175 : *
176 : * This routine resets all 1-Wire bus slaves such that they are
177 : * ready to receive a command.
178 : * Connected slaves answer with a presence pulse once they are ready
179 : * to receive data.
180 : *
181 : * In case the driver supports both standard speed and overdrive speed,
182 : * the reset routine takes care of sendig either a short or a long reset pulse
183 : * depending on the current state. The speed can be changed using
184 : * @a w1_configure().
185 : *
186 : * @param[in] dev Pointer to the device structure for the driver instance.
187 : *
188 : * @retval 0 If no slaves answer with a present pulse.
189 : * @retval 1 If at least one slave answers with a present pulse.
190 : * @retval -errno Negative error code on error.
191 : */
192 1 : __syscall int w1_reset_bus(const struct device *dev);
193 :
194 : static inline int z_impl_w1_reset_bus(const struct device *dev)
195 : {
196 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
197 :
198 : return api->reset_bus(dev);
199 : }
200 :
201 : /**
202 : * @brief Read a single bit from the 1-Wire bus.
203 : *
204 : * @param[in] dev Pointer to the device structure for the driver instance.
205 : *
206 : * @retval rx_bit The read bit value on success.
207 : * @retval -errno Negative error code on error.
208 : */
209 1 : __syscall int w1_read_bit(const struct device *dev);
210 :
211 : static inline int z_impl_w1_read_bit(const struct device *dev)
212 : {
213 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
214 :
215 : return api->read_bit(dev);
216 : }
217 :
218 : /**
219 : * @brief Write a single bit to the 1-Wire bus.
220 : *
221 : * @param[in] dev Pointer to the device structure for the driver instance.
222 : * @param bit Transmitting bit value 1 or 0.
223 : *
224 : * @retval 0 If successful.
225 : * @retval -errno Negative error code on error.
226 : */
227 1 : __syscall int w1_write_bit(const struct device *dev, const bool bit);
228 :
229 : static inline int z_impl_w1_write_bit(const struct device *dev, bool bit)
230 : {
231 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
232 :
233 : return api->write_bit(dev, bit);
234 : }
235 :
236 : /**
237 : * @brief Read a single byte from the 1-Wire bus.
238 : *
239 : * @param[in] dev Pointer to the device structure for the driver instance.
240 : *
241 : * @retval rx_byte The read byte value on success.
242 : * @retval -errno Negative error code on error.
243 : */
244 1 : __syscall int w1_read_byte(const struct device *dev);
245 :
246 : static inline int z_impl_w1_read_byte(const struct device *dev)
247 : {
248 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
249 :
250 : return api->read_byte(dev);
251 : }
252 :
253 : /**
254 : * @brief Write a single byte to the 1-Wire bus.
255 : *
256 : * @param[in] dev Pointer to the device structure for the driver instance.
257 : * @param byte Transmitting byte.
258 : *
259 : * @retval 0 If successful.
260 : * @retval -errno Negative error code on error.
261 : */
262 1 : __syscall int w1_write_byte(const struct device *dev, uint8_t byte);
263 :
264 : static inline int z_impl_w1_write_byte(const struct device *dev, uint8_t byte)
265 : {
266 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
267 :
268 : return api->write_byte(dev, byte);
269 : }
270 :
271 : /**
272 : * @brief Read a block of data from the 1-Wire bus.
273 : *
274 : * @param[in] dev Pointer to the device structure for the driver instance.
275 : * @param[out] buffer Pointer to receive buffer.
276 : * @param len Length of receiving buffer (in bytes).
277 : *
278 : * @retval 0 If successful.
279 : * @retval -errno Negative error code on error.
280 : */
281 1 : __syscall int w1_read_block(const struct device *dev, uint8_t *buffer, size_t len);
282 :
283 : /**
284 : * @brief Write a block of data from the 1-Wire bus.
285 : *
286 : * @param[in] dev Pointer to the device structure for the driver instance.
287 : * @param[in] buffer Pointer to transmitting buffer.
288 : * @param len Length of transmitting buffer (in bytes).
289 : *
290 : * @retval 0 If successful.
291 : * @retval -errno Negative error code on error.
292 : */
293 1 : __syscall int w1_write_block(const struct device *dev,
294 : const uint8_t *buffer, size_t len);
295 :
296 : /**
297 : * @brief Get the number of slaves on the bus.
298 : *
299 : * @param[in] dev Pointer to the device structure for the driver instance.
300 : *
301 : * @retval slave_count Positive Number of connected 1-Wire slaves on success.
302 : * @retval -errno Negative error code on error.
303 : */
304 1 : __syscall size_t w1_get_slave_count(const struct device *dev);
305 :
306 : static inline size_t z_impl_w1_get_slave_count(const struct device *dev)
307 : {
308 : const struct w1_master_config *ctrl_cfg =
309 : (const struct w1_master_config *)dev->config;
310 :
311 : return ctrl_cfg->slave_count;
312 : }
313 :
314 : /**
315 : * @brief Configure parameters of the 1-Wire master.
316 : *
317 : * Allowed configuration parameters are defined in enum w1_settings_type,
318 : * but master devices may not support all types.
319 : *
320 : * @param[in] dev Pointer to the device structure for the driver instance.
321 : * @param type Enum specifying the setting type.
322 : * @param value The new value for the passed settings type.
323 : *
324 : * @retval 0 If successful.
325 : * @retval -ENOTSUP The master doesn't support the configuration of the supplied type.
326 : * @retval -EIO General input / output error, failed to configure master devices.
327 : */
328 1 : __syscall int w1_configure(const struct device *dev,
329 : enum w1_settings_type type, uint32_t value);
330 :
331 : static inline int z_impl_w1_configure(const struct device *dev,
332 : enum w1_settings_type type, uint32_t value)
333 : {
334 : const struct w1_driver_api *api = (const struct w1_driver_api *)dev->api;
335 :
336 : return api->configure(dev, type, value);
337 : }
338 :
339 : /**
340 : * @}
341 : */
342 :
343 : /**
344 : * @brief 1-Wire network layer
345 : * @defgroup w1_network 1-Wire network layer
346 : * @ingroup w1_interface
347 : * @{
348 : */
349 :
350 : /**
351 : * @name 1-Wire ROM Commands
352 : * @{
353 : */
354 :
355 : /**
356 : * This command allows the bus master to read the slave devices without
357 : * providing their ROM code.
358 : */
359 1 : #define W1_CMD_SKIP_ROM 0xCC
360 :
361 : /**
362 : * This command allows the bus master to address a specific slave device by
363 : * providing its ROM code.
364 : */
365 1 : #define W1_CMD_MATCH_ROM 0x55
366 :
367 : /**
368 : * This command allows the bus master to resume a previous read out from where
369 : * it left off.
370 : */
371 1 : #define W1_CMD_RESUME 0xA5
372 :
373 : /**
374 : * This command allows the bus master to read the ROM code from a single slave
375 : * device.
376 : * This command should be used when there is only a single slave device on the
377 : * bus.
378 : */
379 1 : #define W1_CMD_READ_ROM 0x33
380 :
381 : /**
382 : * This command allows the bus master to discover the addresses (i.e., ROM
383 : * codes) of all slave devices on the bus.
384 : */
385 1 : #define W1_CMD_SEARCH_ROM 0xF0
386 :
387 : /**
388 : * This command allows the bus master to identify which devices have experienced
389 : * an alarm condition.
390 : */
391 1 : #define W1_CMD_SEARCH_ALARM 0xEC
392 :
393 : /**
394 : * This command allows the bus master to address all devices on the bus and then
395 : * switch them to overdrive speed.
396 : */
397 1 : #define W1_CMD_OVERDRIVE_SKIP_ROM 0x3C
398 :
399 : /**
400 : * This command allows the bus master to address a specific device and switch it
401 : * to overdrive speed.
402 : */
403 1 : #define W1_CMD_OVERDRIVE_MATCH_ROM 0x69
404 :
405 : /** @} */
406 :
407 : /**
408 : * @name CRC Defines
409 : * @{
410 : */
411 :
412 : /** Seed value used to calculate the 1-Wire 8-bit crc. */
413 1 : #define W1_CRC8_SEED 0x00
414 : /** Polynomial used to calculate the 1-Wire 8-bit crc. */
415 1 : #define W1_CRC8_POLYNOMIAL 0x8C
416 : /** Seed value used to calculate the 1-Wire 16-bit crc. */
417 1 : #define W1_CRC16_SEED 0x0000
418 : /** Polynomial used to calculate the 1-Wire 16-bit crc. */
419 1 : #define W1_CRC16_POLYNOMIAL 0xa001
420 :
421 : /** @} */
422 :
423 : /** This flag can be passed to searches in order to not filter on family ID. */
424 1 : #define W1_SEARCH_ALL_FAMILIES 0x00
425 :
426 : /** Initialize all w1_rom struct members to zero. */
427 1 : #define W1_ROM_INIT_ZERO \
428 : { \
429 : .family = 0, .serial = { 0 }, .crc = 0, \
430 : }
431 :
432 : /**
433 : * @brief w1_rom struct.
434 : */
435 1 : struct w1_rom {
436 : /** @brief The 1-Wire family code identifying the slave device type.
437 : *
438 : * An incomplete list of family codes is available at:
439 : * https://www.analog.com/en/resources/technical-articles/1wire-software-resource-guide-device-description.html
440 : * others are documented in the respective device data sheet.
441 : */
442 1 : uint8_t family;
443 : /** The serial together with the family code composes the unique 56-bit id */
444 1 : uint8_t serial[6];
445 : /** 8-bit checksum of the 56-bit unique id. */
446 1 : uint8_t crc;
447 : };
448 :
449 : /**
450 : * @brief Node specific 1-wire configuration struct.
451 : *
452 : * This struct is passed to network functions, such that they can configure
453 : * the bus to address the specific slave using the selected speed.
454 : */
455 1 : struct w1_slave_config {
456 : /** Unique 1-Wire ROM. */
457 1 : struct w1_rom rom;
458 : /** overdrive speed is used if set to 1. */
459 1 : uint32_t overdrive : 1;
460 : /** @cond INTERNAL_HIDDEN */
461 : uint32_t res : 31;
462 : /** @endcond */
463 : };
464 :
465 : /**
466 : * @brief Define the application callback handler function signature
467 : * for searches.
468 : *
469 : * @param rom found The ROM of the found slave.
470 : * @param user_data User data provided to the w1_search_bus() call.
471 : */
472 1 : typedef void (*w1_search_callback_t)(struct w1_rom rom, void *user_data);
473 :
474 : /**
475 : * @brief Read Peripheral 64-bit ROM.
476 : *
477 : * This procedure allows the 1-Wire bus master to read the peripherals’
478 : * 64-bit ROM without using the Search ROM procedure.
479 : * This command can be used as long as not more than a single peripheral is
480 : * connected to the bus.
481 : * Otherwise data collisions occur and a faulty ROM is read.
482 : *
483 : * @param[in] dev Pointer to the device structure for the driver instance.
484 : * @param[out] rom Pointer to the ROM structure.
485 : *
486 : * @retval 0 If successful.
487 : * @retval -ENODEV In case no slave responds to reset.
488 : * @retval -errno Other negative error code in case of invalid crc and
489 : * communication errors.
490 : */
491 1 : int w1_read_rom(const struct device *dev, struct w1_rom *rom);
492 :
493 : /**
494 : * @brief Select a specific slave by broadcasting a selected ROM.
495 : *
496 : * This routine allows the 1-Wire bus master to select a slave
497 : * identified by its unique ROM, such that the next command will target only
498 : * this single selected slave.
499 : *
500 : * This command is only necessary in multidrop environments, otherwise the
501 : * Skip ROM command can be issued.
502 : * Once a slave has been selected, to reduce the communication overhead, the
503 : * resume command can be used instead of this command to communicate with the
504 : * selected slave.
505 : *
506 : * @param[in] dev Pointer to the device structure for the driver instance.
507 : * @param[in] config Pointer to the slave specific 1-Wire config.
508 : *
509 : * @retval 0 If successful.
510 : * @retval -ENODEV In case no slave responds to reset.
511 : * @retval -errno Other negative error code on error.
512 : */
513 1 : int w1_match_rom(const struct device *dev, const struct w1_slave_config *config);
514 :
515 : /**
516 : * @brief Select the slave last addressed with a Match ROM or Search ROM command.
517 : *
518 : * This routine allows the 1-Wire bus master to re-select a slave
519 : * device that was already addressed using a Match ROM or Search ROM command.
520 : *
521 : * @param dev Pointer to the device structure for the driver instance.
522 : *
523 : * @retval 0 If successful.
524 : * @retval -ENODEV In case no slave responds to reset.
525 : * @retval -errno Other negative error code on error.
526 : */
527 1 : int w1_resume_command(const struct device *dev);
528 :
529 : /**
530 : * @brief Select all slaves regardless of ROM.
531 : *
532 : * This routine sets up the bus slaves to receive a command.
533 : * It is usually used when there is only one peripheral on the bus
534 : * to avoid the overhead of the Match ROM command.
535 : * But it can also be used to concurrently write to all slave devices.
536 : *
537 : * @param[in] dev Pointer to the device structure for the driver instance.
538 : * @param[in] config Pointer to the slave specific 1-Wire config.
539 : *
540 : * @retval 0 If successful.
541 : * @retval -ENODEV In case no slave responds to reset.
542 : * @retval -errno Other negative error code on error.
543 : */
544 1 : int w1_skip_rom(const struct device *dev, const struct w1_slave_config *config);
545 :
546 : /**
547 : * @brief In single drop configurations use Skip Select command, otherwise use
548 : * Match ROM command.
549 : *
550 : * @param[in] dev Pointer to the device structure for the driver instance.
551 : * @param[in] config Pointer to the slave specific 1-Wire config.
552 : *
553 : * @retval 0 If successful.
554 : * @retval -ENODEV In case no slave responds to reset.
555 : * @retval -errno Other negative error code on error.
556 : */
557 1 : int w1_reset_select(const struct device *dev, const struct w1_slave_config *config);
558 :
559 : /**
560 : * @brief Write then read data from the 1-Wire slave with matching ROM.
561 : *
562 : * This routine uses w1_reset_select to select the given ROM.
563 : * Then writes given data and reads the response back from the slave.
564 : *
565 : * @param[in] dev Pointer to the device structure for the driver instance.
566 : * @param[in] config Pointer to the slave specific 1-Wire config.
567 : * @param[in] write_buf Pointer to the data to be written.
568 : * @param write_len Number of bytes to write.
569 : * @param[out] read_buf Pointer to storage for read data.
570 : * @param read_len Number of bytes to read.
571 : *
572 : * @retval 0 If successful.
573 : * @retval -ENODEV In case no slave responds to reset.
574 : * @retval -errno Other negative error code on error.
575 : */
576 1 : int w1_write_read(const struct device *dev, const struct w1_slave_config *config,
577 : const uint8_t *write_buf, size_t write_len,
578 : uint8_t *read_buf, size_t read_len);
579 :
580 : /**
581 : * @brief Search 1-wire slaves on the bus.
582 : *
583 : * This function searches slaves on the 1-wire bus, with the possibility
584 : * to search either all slaves or only slaves that have an active alarm state.
585 : * If a callback is passed, the callback is called for each found slave.
586 : *
587 : * The algorithm mostly follows the suggestions of
588 : * https://www.analog.com/en/resources/app-notes/1wire-search-algorithm.html
589 : *
590 : * Note: Filtering on families is not supported.
591 : *
592 : * @param[in] dev Pointer to the device structure for the driver instance.
593 : * @param command Can either be W1_SEARCH_ALARM or W1_SEARCH_ROM.
594 : * @param family W1_SEARCH_ALL_FAMILIES searcheas all families,
595 : * filtering on a specific family is not yet supported.
596 : * @param callback Application callback handler function to be called
597 : * for each found slave.
598 : * @param[in] user_data User data to pass to the application callback handler
599 : * function.
600 : *
601 : * @retval slave_count Number of slaves found.
602 : * @retval -errno Negative error code on error.
603 : */
604 1 : __syscall int w1_search_bus(const struct device *dev, uint8_t command,
605 : uint8_t family, w1_search_callback_t callback,
606 : void *user_data);
607 :
608 : /**
609 : * @brief Search for 1-Wire slave on bus.
610 : *
611 : * This routine can discover unknown slaves on the bus by scanning for the
612 : * unique 64-bit registration number.
613 : *
614 : * @param[in] dev Pointer to the device structure for the driver instance.
615 : * @param callback Application callback handler function to be called
616 : * for each found slave.
617 : * @param[in] user_data User data to pass to the application callback handler
618 : * function.
619 : *
620 : * @retval slave_count Number of slaves found.
621 : * @retval -errno Negative error code on error.
622 : */
623 1 : static inline int w1_search_rom(const struct device *dev,
624 : w1_search_callback_t callback, void *user_data)
625 : {
626 : return w1_search_bus(dev, W1_CMD_SEARCH_ROM, W1_SEARCH_ALL_FAMILIES,
627 : callback, user_data);
628 : }
629 :
630 : /**
631 : * @brief Search for 1-Wire slaves with an active alarm.
632 : *
633 : * This routine searches 1-Wire slaves on the bus, which currently have
634 : * an active alarm.
635 : *
636 : * @param[in] dev Pointer to the device structure for the driver instance.
637 : * @param callback Application callback handler function to be called
638 : * for each found slave.
639 : * @param[in] user_data User data to pass to the application callback handler
640 : * function.
641 : *
642 : * @retval slave_count Number of slaves found.
643 : * @retval -errno Negative error code on error.
644 : */
645 1 : static inline int w1_search_alarm(const struct device *dev,
646 : w1_search_callback_t callback, void *user_data)
647 : {
648 : return w1_search_bus(dev, W1_CMD_SEARCH_ALARM, W1_SEARCH_ALL_FAMILIES,
649 : callback, user_data);
650 : }
651 :
652 : /**
653 : * @brief Function to convert a w1_rom struct to an uint64_t.
654 : *
655 : * @param[in] rom Pointer to the ROM struct.
656 : *
657 : * @retval rom64 The ROM converted to an unsigned integer in endianness.
658 : */
659 1 : static inline uint64_t w1_rom_to_uint64(const struct w1_rom *rom)
660 : {
661 : return sys_get_be64((uint8_t *)rom);
662 : }
663 :
664 : /**
665 : * @brief Function to write an uint64_t to struct w1_rom pointer.
666 : *
667 : * @param rom64 Unsigned 64 bit integer representing the ROM in host endianness.
668 : * @param[out] rom The ROM struct pointer.
669 : */
670 1 : static inline void w1_uint64_to_rom(const uint64_t rom64, struct w1_rom *rom)
671 : {
672 : sys_put_be64(rom64, (uint8_t *)rom);
673 : }
674 :
675 : /**
676 : * @brief Compute CRC-8 chacksum as defined in the 1-Wire specification.
677 : *
678 : * The 1-Wire of CRC 8 variant is using 0x31 as its polynomial with the initial
679 : * value set to 0x00.
680 : * This CRC is used to check the correctness of the unique 56-bit ROM.
681 : *
682 : * @param[in] src Input bytes for the computation.
683 : * @param len Length of the input in bytes.
684 : *
685 : * @retval crc The computed CRC8 value.
686 : */
687 1 : static inline uint8_t w1_crc8(const uint8_t *src, size_t len)
688 : {
689 : return crc8(src, len, W1_CRC8_POLYNOMIAL, W1_CRC8_SEED, true);
690 : }
691 :
692 : /**
693 : * @brief Compute 1-Wire variant of CRC 16
694 : *
695 : * The 16-bit 1-Wire crc variant is using the reflected polynomial function
696 : * X^16 + X^15 * + X^2 + 1 with the initial value set to 0x0000.
697 : * See also APPLICATION NOTE 27:
698 : * "UNDERSTANDING AND USING CYCLIC REDUNDANCY CHECKS WITH MAXIM 1-WIRE AND IBUTTON PRODUCTS"
699 : * https://www.analog.com/en/resources/technical-articles/understanding-and-using-cyclic-redundancy-checks-with-maxim-1wire-and-ibutton-products.html
700 : *
701 : * @param seed Init value for the CRC, it is usually set to 0x0000.
702 : * @param[in] src Input bytes for the computation.
703 : * @param len Length of the input in bytes.
704 : *
705 : * @retval crc The computed CRC16 value.
706 : */
707 1 : static inline uint16_t w1_crc16(const uint16_t seed, const uint8_t *src,
708 : const size_t len)
709 : {
710 : return crc16_reflect(W1_CRC16_POLYNOMIAL, seed, src, len);
711 : }
712 :
713 : /**
714 : * @}
715 : */
716 :
717 : #ifdef __cplusplus
718 : }
719 : #endif
720 :
721 : /**
722 : * @}
723 : */
724 : #include <zephyr/syscalls/w1.h>
725 :
726 : #endif /* ZEPHYR_INCLUDE_DRIVERS_W1_H_ */
|