游戏王对战板,目前code还是空的

Committer:
WFKnight
Date:
Thu Jun 21 13:51:43 2018 +0000
Revision:
0:9b3d4731edbb
UART, RTOS, LED

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WFKnight 0:9b3d4731edbb 1 /* mbed Microcontroller Library
WFKnight 0:9b3d4731edbb 2 * Copyright (c) 2018 ARM Limited
WFKnight 0:9b3d4731edbb 3 *
WFKnight 0:9b3d4731edbb 4 * Licensed under the Apache License, Version 2.0 (the "License");
WFKnight 0:9b3d4731edbb 5 * you may not use this file except in compliance with the License.
WFKnight 0:9b3d4731edbb 6 * You may obtain a copy of the License at
WFKnight 0:9b3d4731edbb 7 *
WFKnight 0:9b3d4731edbb 8 * http://www.apache.org/licenses/LICENSE-2.0
WFKnight 0:9b3d4731edbb 9 *
WFKnight 0:9b3d4731edbb 10 * Unless required by applicable law or agreed to in writing, software
WFKnight 0:9b3d4731edbb 11 * distributed under the License is distributed on an "AS IS" BASIS,
WFKnight 0:9b3d4731edbb 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
WFKnight 0:9b3d4731edbb 13 * See the License for the specific language governing permissions and
WFKnight 0:9b3d4731edbb 14 * limitations under the License.
WFKnight 0:9b3d4731edbb 15 */
WFKnight 0:9b3d4731edbb 16 #ifndef MBED_CRC_API_H
WFKnight 0:9b3d4731edbb 17 #define MBED_CRC_API_H
WFKnight 0:9b3d4731edbb 18
WFKnight 0:9b3d4731edbb 19 #include "drivers/TableCRC.h"
WFKnight 0:9b3d4731edbb 20 #include "hal/crc_api.h"
WFKnight 0:9b3d4731edbb 21 #include "platform/mbed_assert.h"
WFKnight 0:9b3d4731edbb 22
WFKnight 0:9b3d4731edbb 23 /* This is invalid warning from the compiler for below section of code
WFKnight 0:9b3d4731edbb 24 if ((width < 8) && (NULL == _crc_table)) {
WFKnight 0:9b3d4731edbb 25 p_crc = (uint32_t)(p_crc << (8 - width));
WFKnight 0:9b3d4731edbb 26 }
WFKnight 0:9b3d4731edbb 27 Compiler warns of the shift operation with width as it is width=(std::uint8_t),
WFKnight 0:9b3d4731edbb 28 but we check for ( width < 8) before performing shift, so it should not be an issue.
WFKnight 0:9b3d4731edbb 29 */
WFKnight 0:9b3d4731edbb 30 #if defined ( __CC_ARM )
WFKnight 0:9b3d4731edbb 31 #pragma diag_suppress 62 // Shift count is negative
WFKnight 0:9b3d4731edbb 32 #elif defined ( __GNUC__ )
WFKnight 0:9b3d4731edbb 33 #pragma GCC diagnostic push
WFKnight 0:9b3d4731edbb 34 #pragma GCC diagnostic ignored "-Wshift-count-negative"
WFKnight 0:9b3d4731edbb 35 #elif defined (__ICCARM__)
WFKnight 0:9b3d4731edbb 36 #pragma diag_suppress=Pe062 // Shift count is negative
WFKnight 0:9b3d4731edbb 37 #endif
WFKnight 0:9b3d4731edbb 38
WFKnight 0:9b3d4731edbb 39 namespace mbed {
WFKnight 0:9b3d4731edbb 40 /** \addtogroup drivers */
WFKnight 0:9b3d4731edbb 41 /** @{*/
WFKnight 0:9b3d4731edbb 42
WFKnight 0:9b3d4731edbb 43 /** CRC object provides CRC generation through hardware/software
WFKnight 0:9b3d4731edbb 44 *
WFKnight 0:9b3d4731edbb 45 * ROM polynomial tables for supported polynomials (:: crc_polynomial_t) will be used for
WFKnight 0:9b3d4731edbb 46 * software CRC computation, if ROM tables are not available then CRC is computed runtime
WFKnight 0:9b3d4731edbb 47 * bit by bit for all data input.
WFKnight 0:9b3d4731edbb 48 *
WFKnight 0:9b3d4731edbb 49 * @tparam polynomial CRC polynomial value in hex
WFKnight 0:9b3d4731edbb 50 * @tparam width CRC polynomial width
WFKnight 0:9b3d4731edbb 51 *
WFKnight 0:9b3d4731edbb 52 * Example: Compute CRC data
WFKnight 0:9b3d4731edbb 53 * @code
WFKnight 0:9b3d4731edbb 54 *
WFKnight 0:9b3d4731edbb 55 * #include "mbed.h"
WFKnight 0:9b3d4731edbb 56 *
WFKnight 0:9b3d4731edbb 57 * int main() {
WFKnight 0:9b3d4731edbb 58 * MbedCRC<POLY_32BIT_ANSI, 32> ct;
WFKnight 0:9b3d4731edbb 59 *
WFKnight 0:9b3d4731edbb 60 * char test[] = "123456789";
WFKnight 0:9b3d4731edbb 61 * uint32_t crc = 0;
WFKnight 0:9b3d4731edbb 62 *
WFKnight 0:9b3d4731edbb 63 * printf("\nPolynomial = 0x%lx Width = %d \n", ct.get_polynomial(), ct.get_width());
WFKnight 0:9b3d4731edbb 64 *
WFKnight 0:9b3d4731edbb 65 * ct.compute((void *)test, strlen((const char*)test), &crc);
WFKnight 0:9b3d4731edbb 66 *
WFKnight 0:9b3d4731edbb 67 * printf("The CRC of data \"123456789\" is : 0x%lx\n", crc);
WFKnight 0:9b3d4731edbb 68 * return 0;
WFKnight 0:9b3d4731edbb 69 * }
WFKnight 0:9b3d4731edbb 70 * @endcode
WFKnight 0:9b3d4731edbb 71 * Example: Compute CRC with data available in parts
WFKnight 0:9b3d4731edbb 72 * @code
WFKnight 0:9b3d4731edbb 73 *
WFKnight 0:9b3d4731edbb 74 * #include "mbed.h"
WFKnight 0:9b3d4731edbb 75 * int main() {
WFKnight 0:9b3d4731edbb 76 * MbedCRC<POLY_32BIT_ANSI, 32> ct;
WFKnight 0:9b3d4731edbb 77 *
WFKnight 0:9b3d4731edbb 78 * char test[] = "123456789";
WFKnight 0:9b3d4731edbb 79 * uint32_t crc = 0;
WFKnight 0:9b3d4731edbb 80 *
WFKnight 0:9b3d4731edbb 81 * printf("\nPolynomial = 0x%lx Width = %d \n", ct.get_polynomial(), ct.get_width());
WFKnight 0:9b3d4731edbb 82 *
WFKnight 0:9b3d4731edbb 83 * ct.compute_partial_start(&crc);
WFKnight 0:9b3d4731edbb 84 * ct.compute_partial((void *)&test, 4, &crc);
WFKnight 0:9b3d4731edbb 85 * ct.compute_partial((void *)&test[4], 5, &crc);
WFKnight 0:9b3d4731edbb 86 * ct.compute_partial_stop(&crc);
WFKnight 0:9b3d4731edbb 87 *
WFKnight 0:9b3d4731edbb 88 * printf("The CRC of data \"123456789\" is : 0x%lx\n", crc);
WFKnight 0:9b3d4731edbb 89 * return 0;
WFKnight 0:9b3d4731edbb 90 * }
WFKnight 0:9b3d4731edbb 91 * @endcode
WFKnight 0:9b3d4731edbb 92 * @ingroup drivers
WFKnight 0:9b3d4731edbb 93 */
WFKnight 0:9b3d4731edbb 94
WFKnight 0:9b3d4731edbb 95 template <uint32_t polynomial=POLY_32BIT_ANSI, uint8_t width=32>
WFKnight 0:9b3d4731edbb 96 class MbedCRC
WFKnight 0:9b3d4731edbb 97 {
WFKnight 0:9b3d4731edbb 98 public:
WFKnight 0:9b3d4731edbb 99 enum CrcMode { HARDWARE = 0, TABLE, BITWISE };
WFKnight 0:9b3d4731edbb 100
WFKnight 0:9b3d4731edbb 101 public:
WFKnight 0:9b3d4731edbb 102 typedef uint64_t crc_data_size_t;
WFKnight 0:9b3d4731edbb 103
WFKnight 0:9b3d4731edbb 104 /** Lifetime of CRC object
WFKnight 0:9b3d4731edbb 105 *
WFKnight 0:9b3d4731edbb 106 * @param initial_xor Inital value/seed to Xor
WFKnight 0:9b3d4731edbb 107 * @param final_xor Final Xor value
WFKnight 0:9b3d4731edbb 108 * @param reflect_data
WFKnight 0:9b3d4731edbb 109 * @param reflect_remainder
WFKnight 0:9b3d4731edbb 110 * @note Default constructor without any arguments is valid only for supported CRC polynomials. :: crc_polynomial_t
WFKnight 0:9b3d4731edbb 111 * MbedCRC <POLY_7BIT_SD, 7> ct; --- Valid POLY_7BIT_SD
WFKnight 0:9b3d4731edbb 112 * MbedCRC <0x1021, 16> ct; --- Valid POLY_16BIT_CCITT
WFKnight 0:9b3d4731edbb 113 * MbedCRC <POLY_16BIT_CCITT, 32> ct; --- Invalid, compilation error
WFKnight 0:9b3d4731edbb 114 * MbedCRC <POLY_16BIT_CCITT, 32> ct (i,f,rd,rr) Consturctor can be used for not supported polynomials
WFKnight 0:9b3d4731edbb 115 * MbedCRC<POLY_16BIT_CCITT, 16> sd(0, 0, false, false); Constructor can also be used for supported
WFKnight 0:9b3d4731edbb 116 * polynomials with different intial/final/reflect values
WFKnight 0:9b3d4731edbb 117 *
WFKnight 0:9b3d4731edbb 118 */
WFKnight 0:9b3d4731edbb 119 MbedCRC(uint32_t initial_xor, uint32_t final_xor, bool reflect_data, bool reflect_remainder) :
WFKnight 0:9b3d4731edbb 120 _initial_value(initial_xor), _final_xor(final_xor), _reflect_data(reflect_data),
WFKnight 0:9b3d4731edbb 121 _reflect_remainder(reflect_remainder), _crc_table(NULL)
WFKnight 0:9b3d4731edbb 122 {
WFKnight 0:9b3d4731edbb 123 mbed_crc_ctor();
WFKnight 0:9b3d4731edbb 124 }
WFKnight 0:9b3d4731edbb 125 MbedCRC();
WFKnight 0:9b3d4731edbb 126 virtual ~MbedCRC()
WFKnight 0:9b3d4731edbb 127 {
WFKnight 0:9b3d4731edbb 128 // Do nothing
WFKnight 0:9b3d4731edbb 129 }
WFKnight 0:9b3d4731edbb 130
WFKnight 0:9b3d4731edbb 131 /** Compute CRC for the data input
WFKnight 0:9b3d4731edbb 132 *
WFKnight 0:9b3d4731edbb 133 * @param buffer Data bytes
WFKnight 0:9b3d4731edbb 134 * @param size Size of data
WFKnight 0:9b3d4731edbb 135 * @param crc CRC is the output value
WFKnight 0:9b3d4731edbb 136 * @return 0 on success, negative error code on failure
WFKnight 0:9b3d4731edbb 137 */
WFKnight 0:9b3d4731edbb 138 int32_t compute(void *buffer, crc_data_size_t size, uint32_t *crc)
WFKnight 0:9b3d4731edbb 139 {
WFKnight 0:9b3d4731edbb 140 MBED_ASSERT(crc != NULL);
WFKnight 0:9b3d4731edbb 141 int32_t status;
WFKnight 0:9b3d4731edbb 142 if (0 != (status = compute_partial_start(crc))) {
WFKnight 0:9b3d4731edbb 143 *crc = 0;
WFKnight 0:9b3d4731edbb 144 return status;
WFKnight 0:9b3d4731edbb 145 }
WFKnight 0:9b3d4731edbb 146 if (0 != (status = compute_partial(buffer, size, crc))) {
WFKnight 0:9b3d4731edbb 147 *crc = 0;
WFKnight 0:9b3d4731edbb 148 return status;
WFKnight 0:9b3d4731edbb 149 }
WFKnight 0:9b3d4731edbb 150 if (0 != (status = compute_partial_stop(crc))) {
WFKnight 0:9b3d4731edbb 151 *crc = 0;
WFKnight 0:9b3d4731edbb 152 return status;
WFKnight 0:9b3d4731edbb 153 }
WFKnight 0:9b3d4731edbb 154 return 0;
WFKnight 0:9b3d4731edbb 155 }
WFKnight 0:9b3d4731edbb 156
WFKnight 0:9b3d4731edbb 157 /** Compute partial CRC for the data input.
WFKnight 0:9b3d4731edbb 158 *
WFKnight 0:9b3d4731edbb 159 * CRC data if not available fully, CRC can be computed in parts with available data.
WFKnight 0:9b3d4731edbb 160 * Previous CRC output should be passed as argument to the current compute_partial call.
WFKnight 0:9b3d4731edbb 161 * @pre: Call \ref compute_partial_start to start the partial CRC calculation.
WFKnight 0:9b3d4731edbb 162 * @post: Call \ref compute_partial_stop to get the final CRC value.
WFKnight 0:9b3d4731edbb 163 *
WFKnight 0:9b3d4731edbb 164 * @param buffer Data bytes
WFKnight 0:9b3d4731edbb 165 * @param size Size of data
WFKnight 0:9b3d4731edbb 166 * @param crc CRC value is intermediate CRC value filled by API.
WFKnight 0:9b3d4731edbb 167 * @return 0 on success or a negative error code on failure
WFKnight 0:9b3d4731edbb 168 * @note: CRC as output in compute_partial is not final CRC value, call @ref compute_partial_stop
WFKnight 0:9b3d4731edbb 169 * to get final correct CRC value.
WFKnight 0:9b3d4731edbb 170 */
WFKnight 0:9b3d4731edbb 171 int32_t compute_partial(void *buffer, crc_data_size_t size, uint32_t *crc)
WFKnight 0:9b3d4731edbb 172 {
WFKnight 0:9b3d4731edbb 173 switch (_mode)
WFKnight 0:9b3d4731edbb 174 {
WFKnight 0:9b3d4731edbb 175 case HARDWARE:
WFKnight 0:9b3d4731edbb 176 #ifdef DEVICE_CRC
WFKnight 0:9b3d4731edbb 177 hal_crc_compute_partial((uint8_t *)buffer, size);
WFKnight 0:9b3d4731edbb 178 #endif // DEVICE_CRC
WFKnight 0:9b3d4731edbb 179 *crc = 0;
WFKnight 0:9b3d4731edbb 180 return 0;
WFKnight 0:9b3d4731edbb 181 case TABLE:
WFKnight 0:9b3d4731edbb 182 return table_compute_partial(buffer, size, crc);
WFKnight 0:9b3d4731edbb 183 case BITWISE:
WFKnight 0:9b3d4731edbb 184 return bitwise_compute_partial(buffer, size, crc);
WFKnight 0:9b3d4731edbb 185 }
WFKnight 0:9b3d4731edbb 186
WFKnight 0:9b3d4731edbb 187 return -1;
WFKnight 0:9b3d4731edbb 188 }
WFKnight 0:9b3d4731edbb 189
WFKnight 0:9b3d4731edbb 190 /** Compute partial start, indicate start of partial computation
WFKnight 0:9b3d4731edbb 191 *
WFKnight 0:9b3d4731edbb 192 * This API should be called before performing any partial computation
WFKnight 0:9b3d4731edbb 193 * with compute_partial API.
WFKnight 0:9b3d4731edbb 194 *
WFKnight 0:9b3d4731edbb 195 * @param crc Initial CRC value set by the API
WFKnight 0:9b3d4731edbb 196 * @return 0 on success or a negative in case of failure
WFKnight 0:9b3d4731edbb 197 * @note: CRC is an out parameter and must be reused with compute_partial
WFKnight 0:9b3d4731edbb 198 * and compute_partial_stop without any modifications in application.
WFKnight 0:9b3d4731edbb 199 */
WFKnight 0:9b3d4731edbb 200 int32_t compute_partial_start(uint32_t *crc)
WFKnight 0:9b3d4731edbb 201 {
WFKnight 0:9b3d4731edbb 202 MBED_ASSERT(crc != NULL);
WFKnight 0:9b3d4731edbb 203
WFKnight 0:9b3d4731edbb 204 #ifdef DEVICE_CRC
WFKnight 0:9b3d4731edbb 205 if (_mode == HARDWARE) {
WFKnight 0:9b3d4731edbb 206 crc_mbed_config_t config;
WFKnight 0:9b3d4731edbb 207 config.polynomial = polynomial;
WFKnight 0:9b3d4731edbb 208 config.width = width;
WFKnight 0:9b3d4731edbb 209 config.initial_xor = _initial_value;
WFKnight 0:9b3d4731edbb 210 config.final_xor = _final_xor;
WFKnight 0:9b3d4731edbb 211 config.reflect_in = _reflect_data;
WFKnight 0:9b3d4731edbb 212 config.reflect_out = _reflect_remainder;
WFKnight 0:9b3d4731edbb 213
WFKnight 0:9b3d4731edbb 214 hal_crc_compute_partial_start(&config);
WFKnight 0:9b3d4731edbb 215 }
WFKnight 0:9b3d4731edbb 216 #endif // DEVICE_CRC
WFKnight 0:9b3d4731edbb 217
WFKnight 0:9b3d4731edbb 218 *crc = _initial_value;
WFKnight 0:9b3d4731edbb 219 return 0;
WFKnight 0:9b3d4731edbb 220 }
WFKnight 0:9b3d4731edbb 221
WFKnight 0:9b3d4731edbb 222 /** Get the final CRC value of partial computation.
WFKnight 0:9b3d4731edbb 223 *
WFKnight 0:9b3d4731edbb 224 * CRC value available in partial computation is not correct CRC, as some
WFKnight 0:9b3d4731edbb 225 * algorithms require remainder to be reflected and final value to be XORed
WFKnight 0:9b3d4731edbb 226 * This API is used to perform final computation to get correct CRC value.
WFKnight 0:9b3d4731edbb 227 *
WFKnight 0:9b3d4731edbb 228 * @param crc CRC result
WFKnight 0:9b3d4731edbb 229 */
WFKnight 0:9b3d4731edbb 230 int32_t compute_partial_stop(uint32_t *crc)
WFKnight 0:9b3d4731edbb 231 {
WFKnight 0:9b3d4731edbb 232 MBED_ASSERT(crc != NULL);
WFKnight 0:9b3d4731edbb 233
WFKnight 0:9b3d4731edbb 234 if (_mode == HARDWARE) {
WFKnight 0:9b3d4731edbb 235 #ifdef DEVICE_CRC
WFKnight 0:9b3d4731edbb 236 *crc = hal_crc_get_result();
WFKnight 0:9b3d4731edbb 237 return 0;
WFKnight 0:9b3d4731edbb 238 #else
WFKnight 0:9b3d4731edbb 239 return -1;
WFKnight 0:9b3d4731edbb 240 #endif
WFKnight 0:9b3d4731edbb 241 }
WFKnight 0:9b3d4731edbb 242
WFKnight 0:9b3d4731edbb 243 uint32_t p_crc = *crc;
WFKnight 0:9b3d4731edbb 244 if ((width < 8) && (NULL == _crc_table)) {
WFKnight 0:9b3d4731edbb 245 p_crc = (uint32_t)(p_crc << (8 - width));
WFKnight 0:9b3d4731edbb 246 }
WFKnight 0:9b3d4731edbb 247 *crc = (reflect_remainder(p_crc) ^ _final_xor) & get_crc_mask();
WFKnight 0:9b3d4731edbb 248 return 0;
WFKnight 0:9b3d4731edbb 249 }
WFKnight 0:9b3d4731edbb 250
WFKnight 0:9b3d4731edbb 251 /** Get the current CRC polynomial
WFKnight 0:9b3d4731edbb 252 *
WFKnight 0:9b3d4731edbb 253 * @return Polynomial value
WFKnight 0:9b3d4731edbb 254 */
WFKnight 0:9b3d4731edbb 255 uint32_t get_polynomial(void) const
WFKnight 0:9b3d4731edbb 256 {
WFKnight 0:9b3d4731edbb 257 return polynomial;
WFKnight 0:9b3d4731edbb 258 }
WFKnight 0:9b3d4731edbb 259
WFKnight 0:9b3d4731edbb 260 /** Get the current CRC width
WFKnight 0:9b3d4731edbb 261 *
WFKnight 0:9b3d4731edbb 262 * @return CRC width
WFKnight 0:9b3d4731edbb 263 */
WFKnight 0:9b3d4731edbb 264 uint8_t get_width(void) const
WFKnight 0:9b3d4731edbb 265 {
WFKnight 0:9b3d4731edbb 266 return width;
WFKnight 0:9b3d4731edbb 267 }
WFKnight 0:9b3d4731edbb 268
WFKnight 0:9b3d4731edbb 269 private:
WFKnight 0:9b3d4731edbb 270 uint32_t _initial_value;
WFKnight 0:9b3d4731edbb 271 uint32_t _final_xor;
WFKnight 0:9b3d4731edbb 272 bool _reflect_data;
WFKnight 0:9b3d4731edbb 273 bool _reflect_remainder;
WFKnight 0:9b3d4731edbb 274 uint32_t *_crc_table;
WFKnight 0:9b3d4731edbb 275 CrcMode _mode;
WFKnight 0:9b3d4731edbb 276
WFKnight 0:9b3d4731edbb 277 /** Get the current CRC data size
WFKnight 0:9b3d4731edbb 278 *
WFKnight 0:9b3d4731edbb 279 * @return CRC data size in bytes
WFKnight 0:9b3d4731edbb 280 */
WFKnight 0:9b3d4731edbb 281 uint8_t get_data_size(void) const
WFKnight 0:9b3d4731edbb 282 {
WFKnight 0:9b3d4731edbb 283 return (width <= 8 ? 1 : (width <= 16 ? 2 : 4));
WFKnight 0:9b3d4731edbb 284 }
WFKnight 0:9b3d4731edbb 285
WFKnight 0:9b3d4731edbb 286 /** Get the top bit of current CRC
WFKnight 0:9b3d4731edbb 287 *
WFKnight 0:9b3d4731edbb 288 * @return Top bit is set high for respective data width of current CRC
WFKnight 0:9b3d4731edbb 289 * Top bit for CRC width less then 8 bits will be set as 8th bit.
WFKnight 0:9b3d4731edbb 290 */
WFKnight 0:9b3d4731edbb 291 uint32_t get_top_bit(void) const
WFKnight 0:9b3d4731edbb 292 {
WFKnight 0:9b3d4731edbb 293 return (width < 8 ? (1u << 7) : (uint32_t)(1ul << (width - 1)));
WFKnight 0:9b3d4731edbb 294 }
WFKnight 0:9b3d4731edbb 295
WFKnight 0:9b3d4731edbb 296 /** Get the CRC data mask
WFKnight 0:9b3d4731edbb 297 *
WFKnight 0:9b3d4731edbb 298 * @return CRC data mask is generated based on current CRC width
WFKnight 0:9b3d4731edbb 299 */
WFKnight 0:9b3d4731edbb 300 uint32_t get_crc_mask(void) const
WFKnight 0:9b3d4731edbb 301 {
WFKnight 0:9b3d4731edbb 302 return (width < 8 ? ((1u << 8) - 1) : (uint32_t)((uint64_t)(1ull << width) - 1));
WFKnight 0:9b3d4731edbb 303 }
WFKnight 0:9b3d4731edbb 304
WFKnight 0:9b3d4731edbb 305 /** Final value of CRC is reflected
WFKnight 0:9b3d4731edbb 306 *
WFKnight 0:9b3d4731edbb 307 * @param data final crc value, which should be reflected
WFKnight 0:9b3d4731edbb 308 * @return Reflected CRC value
WFKnight 0:9b3d4731edbb 309 */
WFKnight 0:9b3d4731edbb 310 uint32_t reflect_remainder(uint32_t data) const
WFKnight 0:9b3d4731edbb 311 {
WFKnight 0:9b3d4731edbb 312 if (_reflect_remainder) {
WFKnight 0:9b3d4731edbb 313 uint32_t reflection = 0x0;
WFKnight 0:9b3d4731edbb 314 uint8_t const nBits = (width < 8 ? 8 : width);
WFKnight 0:9b3d4731edbb 315
WFKnight 0:9b3d4731edbb 316 for (uint8_t bit = 0; bit < nBits; ++bit) {
WFKnight 0:9b3d4731edbb 317 if (data & 0x01) {
WFKnight 0:9b3d4731edbb 318 reflection |= (1 << ((nBits - 1) - bit));
WFKnight 0:9b3d4731edbb 319 }
WFKnight 0:9b3d4731edbb 320 data = (data >> 1);
WFKnight 0:9b3d4731edbb 321 }
WFKnight 0:9b3d4731edbb 322 return (reflection);
WFKnight 0:9b3d4731edbb 323 } else {
WFKnight 0:9b3d4731edbb 324 return data;
WFKnight 0:9b3d4731edbb 325 }
WFKnight 0:9b3d4731edbb 326 }
WFKnight 0:9b3d4731edbb 327
WFKnight 0:9b3d4731edbb 328 /** Data bytes are reflected
WFKnight 0:9b3d4731edbb 329 *
WFKnight 0:9b3d4731edbb 330 * @param data value to be reflected
WFKnight 0:9b3d4731edbb 331 * @return Reflected data value
WFKnight 0:9b3d4731edbb 332 */
WFKnight 0:9b3d4731edbb 333 uint32_t reflect_bytes(uint32_t data) const
WFKnight 0:9b3d4731edbb 334 {
WFKnight 0:9b3d4731edbb 335 if(_reflect_data) {
WFKnight 0:9b3d4731edbb 336 uint32_t reflection = 0x0;
WFKnight 0:9b3d4731edbb 337
WFKnight 0:9b3d4731edbb 338 for (uint8_t bit = 0; bit < 8; ++bit) {
WFKnight 0:9b3d4731edbb 339 if (data & 0x01) {
WFKnight 0:9b3d4731edbb 340 reflection |= (1 << (7 - bit));
WFKnight 0:9b3d4731edbb 341 }
WFKnight 0:9b3d4731edbb 342 data = (data >> 1);
WFKnight 0:9b3d4731edbb 343 }
WFKnight 0:9b3d4731edbb 344 return (reflection);
WFKnight 0:9b3d4731edbb 345 } else {
WFKnight 0:9b3d4731edbb 346 return data;
WFKnight 0:9b3d4731edbb 347 }
WFKnight 0:9b3d4731edbb 348 }
WFKnight 0:9b3d4731edbb 349
WFKnight 0:9b3d4731edbb 350 /** Bitwise CRC computation
WFKnight 0:9b3d4731edbb 351 *
WFKnight 0:9b3d4731edbb 352 * @param buffer data buffer
WFKnight 0:9b3d4731edbb 353 * @param size size of the data
WFKnight 0:9b3d4731edbb 354 * @param crc CRC value is filled in, but the value is not the final
WFKnight 0:9b3d4731edbb 355 * @return 0 on success or a negative error code on failure
WFKnight 0:9b3d4731edbb 356 */
WFKnight 0:9b3d4731edbb 357 int32_t bitwise_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
WFKnight 0:9b3d4731edbb 358 {
WFKnight 0:9b3d4731edbb 359 MBED_ASSERT(crc != NULL);
WFKnight 0:9b3d4731edbb 360 MBED_ASSERT(buffer != NULL);
WFKnight 0:9b3d4731edbb 361
WFKnight 0:9b3d4731edbb 362 const uint8_t *data = static_cast<const uint8_t *>(buffer);
WFKnight 0:9b3d4731edbb 363 uint32_t p_crc = *crc;
WFKnight 0:9b3d4731edbb 364
WFKnight 0:9b3d4731edbb 365 if (width < 8) {
WFKnight 0:9b3d4731edbb 366 uint8_t data_byte;
WFKnight 0:9b3d4731edbb 367 for (crc_data_size_t byte = 0; byte < size; byte++) {
WFKnight 0:9b3d4731edbb 368 data_byte = reflect_bytes(data[byte]);
WFKnight 0:9b3d4731edbb 369 for (uint8_t bit = 8; bit > 0; --bit) {
WFKnight 0:9b3d4731edbb 370 p_crc <<= 1;
WFKnight 0:9b3d4731edbb 371 if (( data_byte ^ p_crc) & get_top_bit()) {
WFKnight 0:9b3d4731edbb 372 p_crc ^= polynomial;
WFKnight 0:9b3d4731edbb 373 }
WFKnight 0:9b3d4731edbb 374 data_byte <<= 1;
WFKnight 0:9b3d4731edbb 375 }
WFKnight 0:9b3d4731edbb 376 }
WFKnight 0:9b3d4731edbb 377 } else {
WFKnight 0:9b3d4731edbb 378 for (crc_data_size_t byte = 0; byte < size; byte++) {
WFKnight 0:9b3d4731edbb 379 p_crc ^= (reflect_bytes(data[byte]) << (width - 8));
WFKnight 0:9b3d4731edbb 380
WFKnight 0:9b3d4731edbb 381 // Perform modulo-2 division, a bit at a time
WFKnight 0:9b3d4731edbb 382 for (uint8_t bit = 8; bit > 0; --bit) {
WFKnight 0:9b3d4731edbb 383 if (p_crc & get_top_bit()) {
WFKnight 0:9b3d4731edbb 384 p_crc = (p_crc << 1) ^ polynomial;
WFKnight 0:9b3d4731edbb 385 } else {
WFKnight 0:9b3d4731edbb 386 p_crc = (p_crc << 1);
WFKnight 0:9b3d4731edbb 387 }
WFKnight 0:9b3d4731edbb 388 }
WFKnight 0:9b3d4731edbb 389 }
WFKnight 0:9b3d4731edbb 390 }
WFKnight 0:9b3d4731edbb 391 *crc = p_crc & get_crc_mask();
WFKnight 0:9b3d4731edbb 392 return 0;
WFKnight 0:9b3d4731edbb 393 }
WFKnight 0:9b3d4731edbb 394
WFKnight 0:9b3d4731edbb 395 /** CRC computation using ROM tables
WFKnight 0:9b3d4731edbb 396 *
WFKnight 0:9b3d4731edbb 397 * @param buffer data buffer
WFKnight 0:9b3d4731edbb 398 * @param size size of the data
WFKnight 0:9b3d4731edbb 399 * @param crc CRC value is filled in, but the value is not the final
WFKnight 0:9b3d4731edbb 400 * @return 0 on success or a negative error code on failure
WFKnight 0:9b3d4731edbb 401 */
WFKnight 0:9b3d4731edbb 402 int32_t table_compute_partial(const void *buffer, crc_data_size_t size, uint32_t *crc) const
WFKnight 0:9b3d4731edbb 403 {
WFKnight 0:9b3d4731edbb 404 MBED_ASSERT(crc != NULL);
WFKnight 0:9b3d4731edbb 405 MBED_ASSERT(buffer != NULL);
WFKnight 0:9b3d4731edbb 406
WFKnight 0:9b3d4731edbb 407 const uint8_t *data = static_cast<const uint8_t *>(buffer);
WFKnight 0:9b3d4731edbb 408 uint32_t p_crc = *crc;
WFKnight 0:9b3d4731edbb 409 uint8_t data_byte = 0;
WFKnight 0:9b3d4731edbb 410
WFKnight 0:9b3d4731edbb 411 if (width <= 8) {
WFKnight 0:9b3d4731edbb 412 uint8_t *crc_table = (uint8_t *)_crc_table;
WFKnight 0:9b3d4731edbb 413 for (crc_data_size_t byte = 0; byte < size; byte++) {
WFKnight 0:9b3d4731edbb 414 data_byte = reflect_bytes(data[byte]) ^ p_crc;
WFKnight 0:9b3d4731edbb 415 p_crc = crc_table[data_byte];
WFKnight 0:9b3d4731edbb 416 }
WFKnight 0:9b3d4731edbb 417 } else if (width <= 16) {
WFKnight 0:9b3d4731edbb 418 uint16_t *crc_table = (uint16_t *)_crc_table;
WFKnight 0:9b3d4731edbb 419 for (crc_data_size_t byte = 0; byte < size; byte++) {
WFKnight 0:9b3d4731edbb 420 data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
WFKnight 0:9b3d4731edbb 421 p_crc = crc_table[data_byte] ^ (p_crc << 8);
WFKnight 0:9b3d4731edbb 422 }
WFKnight 0:9b3d4731edbb 423 } else {
WFKnight 0:9b3d4731edbb 424 uint32_t *crc_table = (uint32_t *)_crc_table;
WFKnight 0:9b3d4731edbb 425 for (crc_data_size_t byte = 0; byte < size; byte++) {
WFKnight 0:9b3d4731edbb 426 data_byte = reflect_bytes(data[byte]) ^ (p_crc >> (width - 8));
WFKnight 0:9b3d4731edbb 427 p_crc = crc_table[data_byte] ^ (p_crc << 8);
WFKnight 0:9b3d4731edbb 428 }
WFKnight 0:9b3d4731edbb 429 }
WFKnight 0:9b3d4731edbb 430 *crc = p_crc & get_crc_mask();
WFKnight 0:9b3d4731edbb 431 return 0;
WFKnight 0:9b3d4731edbb 432 }
WFKnight 0:9b3d4731edbb 433
WFKnight 0:9b3d4731edbb 434 /** Constructor init called from all specialized cases of constructor
WFKnight 0:9b3d4731edbb 435 * Note: All construtor common code should be in this function.
WFKnight 0:9b3d4731edbb 436 */
WFKnight 0:9b3d4731edbb 437 void mbed_crc_ctor(void)
WFKnight 0:9b3d4731edbb 438 {
WFKnight 0:9b3d4731edbb 439 MBED_STATIC_ASSERT(width <= 32, "Max 32-bit CRC supported");
WFKnight 0:9b3d4731edbb 440
WFKnight 0:9b3d4731edbb 441 _mode = (_crc_table != NULL) ? TABLE : BITWISE;
WFKnight 0:9b3d4731edbb 442
WFKnight 0:9b3d4731edbb 443 #ifdef DEVICE_CRC
WFKnight 0:9b3d4731edbb 444 crc_mbed_config_t config;
WFKnight 0:9b3d4731edbb 445 config.polynomial = polynomial;
WFKnight 0:9b3d4731edbb 446 config.width = width;
WFKnight 0:9b3d4731edbb 447 config.initial_xor = _initial_value;
WFKnight 0:9b3d4731edbb 448 config.final_xor = _final_xor;
WFKnight 0:9b3d4731edbb 449 config.reflect_in = _reflect_data;
WFKnight 0:9b3d4731edbb 450 config.reflect_out = _reflect_remainder;
WFKnight 0:9b3d4731edbb 451
WFKnight 0:9b3d4731edbb 452 if (hal_crc_is_supported(&config)) {
WFKnight 0:9b3d4731edbb 453 _mode = HARDWARE;
WFKnight 0:9b3d4731edbb 454 }
WFKnight 0:9b3d4731edbb 455 #endif
WFKnight 0:9b3d4731edbb 456 }
WFKnight 0:9b3d4731edbb 457 };
WFKnight 0:9b3d4731edbb 458
WFKnight 0:9b3d4731edbb 459 #if defined ( __CC_ARM )
WFKnight 0:9b3d4731edbb 460 #elif defined ( __GNUC__ )
WFKnight 0:9b3d4731edbb 461 #pragma GCC diagnostic pop
WFKnight 0:9b3d4731edbb 462 #elif defined (__ICCARM__)
WFKnight 0:9b3d4731edbb 463 #endif
WFKnight 0:9b3d4731edbb 464
WFKnight 0:9b3d4731edbb 465 /** @}*/
WFKnight 0:9b3d4731edbb 466 } // namespace mbed
WFKnight 0:9b3d4731edbb 467
WFKnight 0:9b3d4731edbb 468 #endif