crc_api.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /** \addtogroup hal */
  2. /** @{*/
  3. /* mbed Microcontroller Library
  4. * Copyright (c) 2018 ARM Limited
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef MBED_CRC_HAL_API_H
  19. #define MBED_CRC_HAL_API_H
  20. #include <stdbool.h>
  21. #include <stddef.h>
  22. #include <stdint.h>
  23. /** CRC Polynomial value
  24. *
  25. * Different polynomial values supported
  26. */
  27. typedef enum crc_polynomial {
  28. POLY_OTHER = 0,
  29. POLY_8BIT_CCITT = 0x07, // x8+x2+x+1
  30. POLY_7BIT_SD = 0x9, // x7+x3+1;
  31. POLY_16BIT_CCITT = 0x1021, // x16+x12+x5+1
  32. POLY_16BIT_IBM = 0x8005, // x16+x15+x2+1
  33. POLY_32BIT_ANSI = 0x04C11DB7, // x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1
  34. } crc_polynomial_t;
  35. typedef struct crc_mbed_config {
  36. /** CRC Polynomial. Example polynomial: 0x21 = 0010_0011 = x^5+x+1 */
  37. uint32_t polynomial;
  38. /** CRC Bit Width */
  39. uint32_t width;
  40. /** Initial seed value for the computation. */
  41. uint32_t initial_xor;
  42. /** Final xor value for the computation. */
  43. uint32_t final_xor;
  44. /** Reflect bits on input. */
  45. bool reflect_in;
  46. /** Reflect bits in final result before returning. */
  47. bool reflect_out;
  48. } crc_mbed_config_t;
  49. #ifdef DEVICE_CRC
  50. #ifdef __cplusplus
  51. extern "C" {
  52. #endif
  53. /**
  54. * \defgroup hal_crc Hardware CRC
  55. *
  56. * The Hardware CRC HAL API provides a low-level interface to the Hardware CRC
  57. * module of a target platform.
  58. *
  59. * # Defined behaviour
  60. *
  61. * * Function hal_crc_is_supported() returns true if platform supports hardware
  62. * CRC for the given polynomial/width - verified by test ::crc_is_supported_test.
  63. * * Function hal_crc_is_supported() returns false if platform does not support hardware
  64. * CRC for the given polynomial/width - verified by test ::crc_is_supported_test.
  65. * * Function hal_crc_is_supported() returns false if given pointer to configuration
  66. * structure is undefined (NULL) - verified by test ::crc_is_supported_invalid_param_test.
  67. * * If CRC module does not support one of the following settings: initial_xor, final_xor
  68. * reflect_in, reflect_out, then these operations should be handled by the driver
  69. * - Verified by test ::crc_calc_single_test.
  70. * * Platform which supports hardware CRC must be able to handle at least one of the predefined
  71. * polynomial/width configurations that can be constructed in the MbedCRC class: POLY_8BIT_CCITT,
  72. * POLY_7BIT_SD, POLY_16BIT_CCITT, POLY_16BIT_IBM, POLY_32BIT_ANSI
  73. * - verified by test ::crc_is_supported_test, ::crc_calc_single_test.
  74. * * Function hal_crc_compute_partial_start() configures CRC module with the given configuration
  75. * - Verified by test ::crc_calc_single_test.
  76. * * Calling hal_crc_compute_partial_start() without finalising the
  77. * CRC calculation overrides the current configuration - Verified by test ::crc_reconfigure_test.
  78. * * Function hal_crc_compute_partial() writes data to the CRC module - verified by test ::crc_calc_single_test.
  79. * * Function hal_crc_compute_partial() can be call multiple times in succession in order to
  80. * provide additional data to CRC module - verified by test ::crc_calc_multi_test.
  81. * * Function hal_crc_compute_partial() does nothing if pointer to buffer is undefined or
  82. * data length is equal to 0 - verified by test ::crc_compute_partial_invalid_param_test.
  83. * * Function hal_crc_get_result() returns the checksum result from the CRC module
  84. * - verified by tests ::crc_calc_single_test, ::crc_calc_multi_test, ::crc_reconfigure_test.
  85. *
  86. * # Undefined behaviour
  87. *
  88. * * Calling hal_crc_compute_partial_start() function with invalid (unsupported) polynomial.
  89. * * Calling hal_crc_compute_partial() or hal_crc_get_result() functions before hal_crc_compute_partial_start().
  90. * * Calling hal_crc_get_result() function multiple times.
  91. *
  92. * # Non-functional requirements
  93. *
  94. * * CRC configuration provides the following settings:
  95. * * polynomial - CRC Polynomial,
  96. * * width - CRC bit width,
  97. * * initial_xor - seed value for the computation,
  98. * * final_xor - final xor value for the computation,
  99. * * reflect_in - reflect bits on input,
  100. * * reflect_out - reflect bits in final result before returning.
  101. *
  102. * # Potential bugs
  103. *
  104. * @{
  105. */
  106. /**
  107. * \defgroup hal_crc_tests crc hal tests
  108. * The crc HAL tests ensure driver conformance to defined behaviour.
  109. *
  110. * To run the crc hal tests use the command:
  111. *
  112. * mbed test -t <toolchain> -m <target> -n tests-mbed_hal-crc*
  113. *
  114. */
  115. /** Determine if the current platform supports hardware CRC for given polynomial
  116. *
  117. * The purpose of this function is to inform the CRC Platform API whether the
  118. * current platform has a hardware CRC module and that it can support the
  119. * requested polynomial.
  120. *
  121. * Supported polynomials are restricted to the named polynomials that can be
  122. * constructed in the MbedCRC class, POLY_8BIT_CCITT, POLY_7BIT_SD,
  123. * POLY_16BIT_CCITT, POLY_16BIT_IBM and POLY_32BIT_ANSI.
  124. *
  125. * The current platform must support the given polynomials default parameters
  126. * in order to return a true response. These include: reflect in, reflect out,
  127. * initial xor and final xor. For example, POLY_32BIT_ANSI requires an initial
  128. * and final xor of 0xFFFFFFFF, and reflection of both input and output. If any
  129. * of these settings cannot be configured, the polynomial is not supported.
  130. *
  131. * This function is thread safe; it safe to call from multiple contexts if
  132. * required.
  133. *
  134. * \param config Contains CRC configuration parameters for initializing the
  135. * hardware CRC module. For example, polynomial and initial seed
  136. * values.
  137. *
  138. * \return True if running if the polynomial is supported, false if not.
  139. */
  140. bool hal_crc_is_supported(const crc_mbed_config_t *config);
  141. /** Initialize the hardware CRC module with the given polynomial
  142. *
  143. * After calling this function, the CRC HAL module is ready to receive data
  144. * using the hal_crc_compute_partial() function. The CRC module on the board
  145. * is configured internally with the specified configuration and is ready
  146. * to receive data.
  147. *
  148. * The platform configures itself based on the default configuration
  149. * parameters of the input polynomial.
  150. *
  151. * This function must be called before calling hal_crc_compute_partial().
  152. *
  153. * This function must be called with a valid polynomial supported by the
  154. * platform. The polynomial must be checked for support using the
  155. * hal_crc_is_supported() function.
  156. *
  157. * Calling hal_crc_compute_partial_start() multiple times without finalizing the
  158. * CRC calculation with hal_crc_get_result() overrides the current
  159. * configuration and state, and the intermediate result of the computation is
  160. * lost.
  161. *
  162. * This function is not thread safe. A CRC calculation must not be started from
  163. * two different threads or contexts at the same time; calling this function
  164. * from two different contexts may lead to configurations being overwritten and
  165. * results being lost.
  166. *
  167. * \param config Contains CRC configuration parameters for initializing the
  168. * hardware CRC module. For example, polynomial and initial seed
  169. * values.
  170. */
  171. void hal_crc_compute_partial_start(const crc_mbed_config_t *config);
  172. /** Writes data to the current CRC module.
  173. *
  174. * Writes input data buffer bytes to the CRC data register. The CRC module
  175. * must interpret the data as an array of bytes.
  176. *
  177. * The final transformations are not applied to the data; the CRC module must
  178. * retain the intermediate result so that additional calls to this function
  179. * can be made, appending the additional data to the calculation.
  180. *
  181. * To obtain the final result of the CRC calculation, hal_crc_get_result() is
  182. * called to apply the final transformations to the data.
  183. *
  184. * If the function is passed an undefined pointer, or the size of the buffer is
  185. * specified to be 0, this function does nothing and returns.
  186. *
  187. * This function can be called multiple times in succession. This can be used
  188. * to calculate the CRC result of streamed data.
  189. *
  190. * This function is not thread safe. There is only one instance of the CRC
  191. * module active at a time. Calling this function from multiple contexts
  192. * appends different data to the same, single instance of the module, which causes an
  193. * erroneous value to be calculated.
  194. *
  195. * \param data Input data stream to be written into the CRC calculation
  196. * \param size Size of the data stream in bytes
  197. */
  198. void hal_crc_compute_partial(const uint8_t *data, const size_t size);
  199. /* Reads the checksum result from the CRC module.
  200. *
  201. * Reads the final checksum result for the final checksum value. The returned
  202. * value is cast as an unsigned 32-bit integer. The actual size of the returned
  203. * result depends on the polynomial used to configure the CRC module.
  204. *
  205. * Additional transformations that are used in the default configuration of the
  206. * input polynomial are applied to the result before it is returned from this
  207. * function. These transformations include: the final xor being appended to the
  208. * calculation, and the result being reflected if required.
  209. *
  210. * Calling this function multiple times is undefined. The first call to this
  211. * function returns the final result of the CRC calculation. The return
  212. * value on successive calls is undefined because the contents of the register after
  213. * accessing them is platform-specific.
  214. *
  215. * This function is not thread safe. There is only one instance of the CRC
  216. * module active at a time. Calling this function from multiple contexts may
  217. * return incorrect data or affect the current state of the module.
  218. *
  219. * \return The final CRC checksum after the reflections and final calculations
  220. * have been applied.
  221. */
  222. uint32_t hal_crc_get_result(void);
  223. /**@}*/
  224. #ifdef __cplusplus
  225. };
  226. #endif
  227. #endif // DEVICE_CRC
  228. #endif // MBED_CRC_HAL_API_H
  229. /**@}*/