mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_Silicon_Labs/TARGET_EFM32/crc_api.c@189:f392fc9709a3, 2019-02-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Wed Feb 20 22:31:08 2019 +0000
- Revision:
- 189:f392fc9709a3
- Parent:
- 188:bcfe06ba3d64
mbed library release version 165
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AnnaBridge | 187:0387e8f68319 | 1 | /***************************************************************************//** |
AnnaBridge | 187:0387e8f68319 | 2 | * @file crc_api.c |
AnnaBridge | 187:0387e8f68319 | 3 | ******************************************************************************* |
AnnaBridge | 187:0387e8f68319 | 4 | * @section License |
AnnaBridge | 187:0387e8f68319 | 5 | * <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b> |
AnnaBridge | 187:0387e8f68319 | 6 | ******************************************************************************* |
AnnaBridge | 187:0387e8f68319 | 7 | * |
AnnaBridge | 187:0387e8f68319 | 8 | * SPDX-License-Identifier: Apache-2.0 |
AnnaBridge | 187:0387e8f68319 | 9 | * |
AnnaBridge | 187:0387e8f68319 | 10 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
AnnaBridge | 187:0387e8f68319 | 11 | * not use this file except in compliance with the License. |
AnnaBridge | 187:0387e8f68319 | 12 | * You may obtain a copy of the License at |
AnnaBridge | 187:0387e8f68319 | 13 | * |
AnnaBridge | 187:0387e8f68319 | 14 | * http://www.apache.org/licenses/LICENSE-2.0 |
AnnaBridge | 187:0387e8f68319 | 15 | * |
AnnaBridge | 187:0387e8f68319 | 16 | * Unless required by applicable law or agreed to in writing, software |
AnnaBridge | 187:0387e8f68319 | 17 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
AnnaBridge | 187:0387e8f68319 | 18 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
AnnaBridge | 187:0387e8f68319 | 19 | * See the License for the specific language governing permissions and |
AnnaBridge | 187:0387e8f68319 | 20 | * limitations under the License. |
AnnaBridge | 187:0387e8f68319 | 21 | * |
AnnaBridge | 187:0387e8f68319 | 22 | ******************************************************************************/ |
AnnaBridge | 187:0387e8f68319 | 23 | |
AnnaBridge | 187:0387e8f68319 | 24 | #include "device.h" |
AnnaBridge | 187:0387e8f68319 | 25 | #include "clocking.h" |
AnnaBridge | 187:0387e8f68319 | 26 | #include <stdio.h> |
AnnaBridge | 187:0387e8f68319 | 27 | |
AnnaBridge | 187:0387e8f68319 | 28 | #if DEVICE_CRC |
AnnaBridge | 187:0387e8f68319 | 29 | #include "mbed_assert.h" |
AnnaBridge | 187:0387e8f68319 | 30 | #include "crc_api.h" |
AnnaBridge | 187:0387e8f68319 | 31 | #include "em_cmu.h" |
AnnaBridge | 187:0387e8f68319 | 32 | |
AnnaBridge | 187:0387e8f68319 | 33 | #if defined(GPCRC_PRESENT) && (GPCRC_COUNT > 0) |
AnnaBridge | 187:0387e8f68319 | 34 | #include "em_gpcrc.h" |
AnnaBridge | 187:0387e8f68319 | 35 | |
AnnaBridge | 187:0387e8f68319 | 36 | static bool revOutput = false; |
AnnaBridge | 188:bcfe06ba3d64 | 37 | static bool enableWordInput = false; |
AnnaBridge | 187:0387e8f68319 | 38 | static uint32_t final_xor; |
AnnaBridge | 187:0387e8f68319 | 39 | |
AnnaBridge | 187:0387e8f68319 | 40 | bool hal_crc_is_supported(const crc_mbed_config_t *config) |
AnnaBridge | 187:0387e8f68319 | 41 | { |
AnnaBridge | 187:0387e8f68319 | 42 | //GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly |
AnnaBridge | 187:0387e8f68319 | 43 | if (config == NULL) { |
AnnaBridge | 187:0387e8f68319 | 44 | return false; |
AnnaBridge | 187:0387e8f68319 | 45 | } |
AnnaBridge | 187:0387e8f68319 | 46 | |
AnnaBridge | 187:0387e8f68319 | 47 | if (config->width == 16) { |
AnnaBridge | 187:0387e8f68319 | 48 | return true; |
AnnaBridge | 187:0387e8f68319 | 49 | } else if (config->width == 32) { |
AnnaBridge | 187:0387e8f68319 | 50 | if (config->polynomial == POLY_32BIT_ANSI) { |
AnnaBridge | 187:0387e8f68319 | 51 | return true; |
AnnaBridge | 187:0387e8f68319 | 52 | } else { |
AnnaBridge | 187:0387e8f68319 | 53 | return false; |
AnnaBridge | 187:0387e8f68319 | 54 | } |
AnnaBridge | 187:0387e8f68319 | 55 | } else { |
AnnaBridge | 187:0387e8f68319 | 56 | return false; |
AnnaBridge | 187:0387e8f68319 | 57 | } |
AnnaBridge | 187:0387e8f68319 | 58 | } |
AnnaBridge | 187:0387e8f68319 | 59 | |
AnnaBridge | 187:0387e8f68319 | 60 | void hal_crc_compute_partial_start(const crc_mbed_config_t *config) |
AnnaBridge | 187:0387e8f68319 | 61 | { |
AnnaBridge | 187:0387e8f68319 | 62 | if (!hal_crc_is_supported(config)) { |
AnnaBridge | 187:0387e8f68319 | 63 | return; |
AnnaBridge | 187:0387e8f68319 | 64 | } |
AnnaBridge | 187:0387e8f68319 | 65 | |
AnnaBridge | 187:0387e8f68319 | 66 | CMU_ClockEnable(cmuClock_GPCRC, true); |
AnnaBridge | 187:0387e8f68319 | 67 | GPCRC_Reset(GPCRC); |
AnnaBridge | 187:0387e8f68319 | 68 | |
AnnaBridge | 187:0387e8f68319 | 69 | GPCRC_Init_TypeDef crc_init; |
AnnaBridge | 187:0387e8f68319 | 70 | |
AnnaBridge | 187:0387e8f68319 | 71 | crc_init.autoInit = false; |
AnnaBridge | 187:0387e8f68319 | 72 | crc_init.enable = true; |
AnnaBridge | 187:0387e8f68319 | 73 | crc_init.crcPoly = config->polynomial; |
AnnaBridge | 187:0387e8f68319 | 74 | |
AnnaBridge | 187:0387e8f68319 | 75 | // GPCRC operates on bit-reversed inputs and outputs vs the standard |
AnnaBridge | 187:0387e8f68319 | 76 | // defined by the mbed API. Emlib does the reversal on the poly, but |
AnnaBridge | 187:0387e8f68319 | 77 | // not on the initial value. |
AnnaBridge | 187:0387e8f68319 | 78 | if (config->width == 16) { |
AnnaBridge | 188:bcfe06ba3d64 | 79 | enableWordInput = false; |
AnnaBridge | 187:0387e8f68319 | 80 | crc_init.initValue = __RBIT(config->initial_xor) >> 16; |
AnnaBridge | 187:0387e8f68319 | 81 | } else { |
AnnaBridge | 188:bcfe06ba3d64 | 82 | enableWordInput = true; |
AnnaBridge | 187:0387e8f68319 | 83 | crc_init.initValue = __RBIT(config->initial_xor); |
AnnaBridge | 187:0387e8f68319 | 84 | } |
AnnaBridge | 187:0387e8f68319 | 85 | |
AnnaBridge | 187:0387e8f68319 | 86 | // GPCRC operates on bit-reversed inputs and outputs vs the standard |
AnnaBridge | 187:0387e8f68319 | 87 | // defined by the mbed API, so reflect_in/out needs to be negated. |
AnnaBridge | 187:0387e8f68319 | 88 | if (config->reflect_in) { |
AnnaBridge | 187:0387e8f68319 | 89 | crc_init.reverseBits = false; |
AnnaBridge | 187:0387e8f68319 | 90 | } else { |
AnnaBridge | 187:0387e8f68319 | 91 | crc_init.reverseBits = true; |
AnnaBridge | 187:0387e8f68319 | 92 | } |
AnnaBridge | 187:0387e8f68319 | 93 | |
AnnaBridge | 188:bcfe06ba3d64 | 94 | // Input is little-endian |
AnnaBridge | 188:bcfe06ba3d64 | 95 | crc_init.reverseByteOrder = false; |
AnnaBridge | 188:bcfe06ba3d64 | 96 | |
AnnaBridge | 187:0387e8f68319 | 97 | // Disable byte mode to be able to run a faster U32 input version |
AnnaBridge | 187:0387e8f68319 | 98 | crc_init.enableByteMode = false; |
AnnaBridge | 187:0387e8f68319 | 99 | |
AnnaBridge | 187:0387e8f68319 | 100 | // GPCRC does not support hardware output bit-reversal, nor finalisation. |
AnnaBridge | 187:0387e8f68319 | 101 | // Since the mbed API does not pass the config struct when fetching the |
AnnaBridge | 187:0387e8f68319 | 102 | // CRC calculation result, we need to keep track of these locally. |
AnnaBridge | 187:0387e8f68319 | 103 | revOutput = config->reflect_out; |
AnnaBridge | 187:0387e8f68319 | 104 | final_xor = config->final_xor; |
AnnaBridge | 187:0387e8f68319 | 105 | |
AnnaBridge | 187:0387e8f68319 | 106 | GPCRC_Init(GPCRC, &crc_init); |
AnnaBridge | 187:0387e8f68319 | 107 | GPCRC_Start(GPCRC); |
AnnaBridge | 187:0387e8f68319 | 108 | } |
AnnaBridge | 187:0387e8f68319 | 109 | |
AnnaBridge | 187:0387e8f68319 | 110 | void hal_crc_compute_partial(const uint8_t *data, const size_t size) |
AnnaBridge | 187:0387e8f68319 | 111 | { |
AnnaBridge | 187:0387e8f68319 | 112 | if (data == NULL || size <= 0) { |
AnnaBridge | 187:0387e8f68319 | 113 | return; |
AnnaBridge | 187:0387e8f68319 | 114 | } |
AnnaBridge | 187:0387e8f68319 | 115 | |
AnnaBridge | 188:bcfe06ba3d64 | 116 | if (!enableWordInput || size < sizeof(uint32_t)) { |
AnnaBridge | 188:bcfe06ba3d64 | 117 | // Input to a non-word-sized poly, or too small data size for a word input |
AnnaBridge | 187:0387e8f68319 | 118 | for (size_t i = 0; i < size; i++) { |
AnnaBridge | 187:0387e8f68319 | 119 | GPCRC_InputU8(GPCRC, data[i]); |
AnnaBridge | 187:0387e8f68319 | 120 | } |
AnnaBridge | 187:0387e8f68319 | 121 | } else { |
AnnaBridge | 187:0387e8f68319 | 122 | size_t i = 0; |
AnnaBridge | 188:bcfe06ba3d64 | 123 | |
AnnaBridge | 188:bcfe06ba3d64 | 124 | // If input is unaligned, take off as many bytes as needed to align |
AnnaBridge | 188:bcfe06ba3d64 | 125 | while (((uint32_t)(data + i) & 0x3) != 0) { |
AnnaBridge | 188:bcfe06ba3d64 | 126 | GPCRC_InputU8(GPCRC, data[i]); |
AnnaBridge | 188:bcfe06ba3d64 | 127 | i++; |
AnnaBridge | 188:bcfe06ba3d64 | 128 | } |
AnnaBridge | 188:bcfe06ba3d64 | 129 | |
AnnaBridge | 188:bcfe06ba3d64 | 130 | // If enough input remaining to do word-sized writes, do so |
AnnaBridge | 188:bcfe06ba3d64 | 131 | while ((size - i) >= sizeof(uint32_t)) { |
AnnaBridge | 187:0387e8f68319 | 132 | GPCRC_InputU32(GPCRC, *((uint32_t*)(&data[i]))); |
AnnaBridge | 188:bcfe06ba3d64 | 133 | i += sizeof(uint32_t); |
AnnaBridge | 187:0387e8f68319 | 134 | } |
AnnaBridge | 188:bcfe06ba3d64 | 135 | |
AnnaBridge | 188:bcfe06ba3d64 | 136 | // Do byte input to pick off the last remaining bytes |
AnnaBridge | 188:bcfe06ba3d64 | 137 | while (i < size) { |
AnnaBridge | 187:0387e8f68319 | 138 | GPCRC_InputU8(GPCRC, data[i]); |
AnnaBridge | 188:bcfe06ba3d64 | 139 | i++; |
AnnaBridge | 187:0387e8f68319 | 140 | } |
AnnaBridge | 187:0387e8f68319 | 141 | } |
AnnaBridge | 187:0387e8f68319 | 142 | } |
AnnaBridge | 187:0387e8f68319 | 143 | |
AnnaBridge | 187:0387e8f68319 | 144 | uint32_t hal_crc_get_result(void) |
AnnaBridge | 187:0387e8f68319 | 145 | { |
AnnaBridge | 187:0387e8f68319 | 146 | uint32_t result; |
AnnaBridge | 187:0387e8f68319 | 147 | |
AnnaBridge | 187:0387e8f68319 | 148 | // GPCRC operates on bit-reversed inputs and outputs vs the standard |
AnnaBridge | 187:0387e8f68319 | 149 | // defined by the mbed API. |
AnnaBridge | 187:0387e8f68319 | 150 | if (!revOutput) { |
AnnaBridge | 187:0387e8f68319 | 151 | result = GPCRC_DataReadBitReversed(GPCRC); |
AnnaBridge | 187:0387e8f68319 | 152 | } else { |
AnnaBridge | 187:0387e8f68319 | 153 | result = GPCRC_DataRead(GPCRC); |
AnnaBridge | 187:0387e8f68319 | 154 | } |
AnnaBridge | 187:0387e8f68319 | 155 | |
AnnaBridge | 187:0387e8f68319 | 156 | GPCRC_Enable(GPCRC, false); |
AnnaBridge | 187:0387e8f68319 | 157 | |
AnnaBridge | 187:0387e8f68319 | 158 | return result ^ final_xor; |
AnnaBridge | 187:0387e8f68319 | 159 | } |
AnnaBridge | 187:0387e8f68319 | 160 | |
AnnaBridge | 187:0387e8f68319 | 161 | #endif //GPCRC_PRESENT |
AnnaBridge | 187:0387e8f68319 | 162 | #endif //DEVICE_CRC |