1wire_crc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /****************************************************************************
  2. * drivers/1wire/1wire_crc.c
  3. *
  4. * Copyright (C) 2018 Haltian Ltd. All rights reserved.
  5. * Author: Juha Niskanen <juha.niskanen@haltian.com>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <stdint.h>
  39. #include <stdbool.h>
  40. #include <string.h>
  41. #include "1wire_internal.h"
  42. /****************************************************************************
  43. * Public Functions
  44. ****************************************************************************/
  45. /* Compute a Dallas Semiconductor 8 bit CRC. */
  46. uint8_t onewire_crc8(FAR const uint8_t *input, uint8_t len)
  47. {
  48. uint8_t crc = 0;
  49. while (len-- > 0)
  50. {
  51. int i;
  52. uint8_t inbyte = *input++;
  53. for (i = 0; i < 8; i++)
  54. {
  55. uint8_t mix = (crc ^ inbyte) & 0x01;
  56. crc >>= 1;
  57. if (mix)
  58. crc ^= 0x8c;
  59. inbyte >>= 1;
  60. }
  61. }
  62. return crc;
  63. }
  64. /* Compute a Dallas Semiconductor 16 bit CRC. This is used to check
  65. * the integrity of received data from many 1-wire devices.
  66. *
  67. * Note: the CRC-16 computed here is not what you'll get from the 1-wire
  68. * network, because:
  69. * - The CRC-16 is transmitted bitwise inverted.
  70. * - The binary representation of the return value may have a different
  71. * byte order than the two bytes you get from 1-wire due to endian-ness.
  72. */
  73. uint16_t onewire_crc16(FAR const uint8_t *input, uint16_t len,
  74. uint16_t initial_crc)
  75. {
  76. uint16_t crc = initial_crc;
  77. while (len-- > 0)
  78. {
  79. int i;
  80. uint8_t inbyte = *input++;
  81. for (i = 0; i < 8; i++)
  82. {
  83. uint8_t mix = ((crc & 0xff) ^ inbyte) & 0x01;
  84. crc >>= 1;
  85. if (mix)
  86. {
  87. crc ^= 0xa001;
  88. }
  89. inbyte >>= 1;
  90. }
  91. }
  92. return crc;
  93. }
  94. /****************************************************************************
  95. * Name: onewire_valid_rom
  96. *
  97. * Description:
  98. * Check CRC-8 of received input
  99. *
  100. * Input Parameters:
  101. * rom - 64-bit rom code
  102. *
  103. * Returned Value:
  104. * true if CRC-8 of rom matches
  105. *
  106. ****************************************************************************/
  107. bool onewire_valid_rom(uint64_t rom)
  108. {
  109. uint8_t crc;
  110. uint8_t buf[8];
  111. memcpy(buf, &rom, sizeof(buf));
  112. crc = onewire_crc8(buf, 7);
  113. return crc == buf[7];
  114. }
  115. /****************************************************************************
  116. * Name: onewire_check_crc16
  117. *
  118. * Description:
  119. * Check CRC-16 of received input
  120. *
  121. * Input Parameters:
  122. * input - Array of bytes to checksum
  123. * len - Length of input
  124. * inverted_crc - The two CRC16 bytes in the received data
  125. *
  126. * Returned Value:
  127. * true if CRC-16 matches
  128. *
  129. ****************************************************************************/
  130. bool onewire_check_crc16(FAR const uint8_t *input, uint16_t len,
  131. FAR const uint8_t *inverted_crc)
  132. {
  133. uint16_t crc;
  134. crc = ~onewire_crc16(input, len, 0);
  135. return (crc & 0xff) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
  136. }