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