fsl_crc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_crc.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. #if defined(CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT
  35. /* @brief Default user configuration structure for CRC-CCITT */
  36. #define CRC_DRIVER_DEFAULT_POLYNOMIAL kCRC_Polynomial_CRC_CCITT
  37. /*< CRC-CCIT polynomial x^16 + x^12 + x^5 + x^0 */
  38. #define CRC_DRIVER_DEFAULT_REVERSE_IN false
  39. /*< Default is no bit reverse */
  40. #define CRC_DRIVER_DEFAULT_COMPLEMENT_IN false
  41. /*< Default is without complement of written data */
  42. #define CRC_DRIVER_DEFAULT_REVERSE_OUT false
  43. /*< Default is no bit reverse */
  44. #define CRC_DRIVER_DEFAULT_COMPLEMENT_OUT false
  45. /*< Default is without complement of CRC data register read data */
  46. #define CRC_DRIVER_DEFAULT_SEED 0xFFFFU
  47. /*< Default initial checksum */
  48. #endif /* CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT */
  49. /*******************************************************************************
  50. * Code
  51. ******************************************************************************/
  52. void CRC_Init(CRC_Type *base, const crc_config_t *config)
  53. {
  54. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  55. /* enable clock to CRC */
  56. CLOCK_EnableClock(kCLOCK_Crc);
  57. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  58. /* configure CRC module and write the seed */
  59. base->MODE = 0 | CRC_MODE_CRC_POLY(config->polynomial) | CRC_MODE_BIT_RVS_WR(config->reverseIn) |
  60. CRC_MODE_CMPL_WR(config->complementIn) | CRC_MODE_BIT_RVS_SUM(config->reverseOut) |
  61. CRC_MODE_CMPL_SUM(config->complementOut);
  62. base->SEED = config->seed;
  63. }
  64. void CRC_GetDefaultConfig(crc_config_t *config)
  65. {
  66. static const crc_config_t default_config = {CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_REVERSE_IN,
  67. CRC_DRIVER_DEFAULT_COMPLEMENT_IN, CRC_DRIVER_DEFAULT_REVERSE_OUT,
  68. CRC_DRIVER_DEFAULT_COMPLEMENT_OUT, CRC_DRIVER_DEFAULT_SEED};
  69. *config = default_config;
  70. }
  71. void CRC_Reset(CRC_Type *base)
  72. {
  73. crc_config_t config;
  74. CRC_GetDefaultConfig(&config);
  75. CRC_Init(base, &config);
  76. }
  77. void CRC_GetConfig(CRC_Type *base, crc_config_t *config)
  78. {
  79. /* extract CRC mode settings */
  80. uint32_t mode = base->MODE;
  81. config->polynomial = (crc_polynomial_t)((mode & CRC_MODE_CRC_POLY_MASK) >> CRC_MODE_CRC_POLY_SHIFT);
  82. config->reverseIn = (bool)(mode & CRC_MODE_BIT_RVS_WR_MASK);
  83. config->complementIn = (bool)(mode & CRC_MODE_CMPL_WR_MASK);
  84. config->reverseOut = (bool)(mode & CRC_MODE_BIT_RVS_SUM_MASK);
  85. config->complementOut = (bool)(mode & CRC_MODE_CMPL_SUM_MASK);
  86. /* reset CRC sum bit reverse and 1's complement setting, so its value can be used as a seed */
  87. base->MODE = mode & ~((1U << CRC_MODE_BIT_RVS_SUM_SHIFT) | (1U << CRC_MODE_CMPL_SUM_SHIFT));
  88. /* now we can obtain intermediate raw CRC sum value */
  89. config->seed = base->SUM;
  90. /* restore original CRC sum bit reverse and 1's complement setting */
  91. base->MODE = mode;
  92. }
  93. void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize)
  94. {
  95. const uint32_t *data32;
  96. /* 8-bit reads and writes till source address is aligned 4 bytes */
  97. while ((dataSize) && ((uint32_t)data & 3U))
  98. {
  99. *((__O uint8_t *)&(base->WR_DATA)) = *data;
  100. data++;
  101. dataSize--;
  102. }
  103. /* use 32-bit reads and writes as long as possible */
  104. data32 = (const uint32_t *)data;
  105. while (dataSize >= sizeof(uint32_t))
  106. {
  107. *((__O uint32_t *)&(base->WR_DATA)) = *data32;
  108. data32++;
  109. dataSize -= sizeof(uint32_t);
  110. }
  111. data = (const uint8_t *)data32;
  112. /* 8-bit reads and writes till end of data buffer */
  113. while (dataSize)
  114. {
  115. *((__O uint8_t *)&(base->WR_DATA)) = *data;
  116. data++;
  117. dataSize--;
  118. }
  119. }