mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

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?

UserRevisionLine numberNew 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