mbed library sources. Supersedes mbed-src.

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

Committer:
AnnaBridge
Date:
Thu Sep 06 13:40:20 2018 +0100
Revision:
187:0387e8f68319
Child:
188:bcfe06ba3d64
mbed-dev library. Release version 163

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 187:0387e8f68319 37 static uint32_t final_xor;
AnnaBridge 187:0387e8f68319 38
AnnaBridge 187:0387e8f68319 39 bool hal_crc_is_supported(const crc_mbed_config_t *config)
AnnaBridge 187:0387e8f68319 40 {
AnnaBridge 187:0387e8f68319 41 //GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly
AnnaBridge 187:0387e8f68319 42 if (config == NULL) {
AnnaBridge 187:0387e8f68319 43 return false;
AnnaBridge 187:0387e8f68319 44 }
AnnaBridge 187:0387e8f68319 45
AnnaBridge 187:0387e8f68319 46 if (config->width == 16) {
AnnaBridge 187:0387e8f68319 47 return true;
AnnaBridge 187:0387e8f68319 48 } else if (config->width == 32) {
AnnaBridge 187:0387e8f68319 49 if (config->polynomial == POLY_32BIT_ANSI) {
AnnaBridge 187:0387e8f68319 50 return true;
AnnaBridge 187:0387e8f68319 51 } else {
AnnaBridge 187:0387e8f68319 52 return false;
AnnaBridge 187:0387e8f68319 53 }
AnnaBridge 187:0387e8f68319 54 } else {
AnnaBridge 187:0387e8f68319 55 return false;
AnnaBridge 187:0387e8f68319 56 }
AnnaBridge 187:0387e8f68319 57 }
AnnaBridge 187:0387e8f68319 58
AnnaBridge 187:0387e8f68319 59 void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
AnnaBridge 187:0387e8f68319 60 {
AnnaBridge 187:0387e8f68319 61 if (!hal_crc_is_supported(config)) {
AnnaBridge 187:0387e8f68319 62 return;
AnnaBridge 187:0387e8f68319 63 }
AnnaBridge 187:0387e8f68319 64
AnnaBridge 187:0387e8f68319 65 CMU_ClockEnable(cmuClock_GPCRC, true);
AnnaBridge 187:0387e8f68319 66 GPCRC_Reset(GPCRC);
AnnaBridge 187:0387e8f68319 67
AnnaBridge 187:0387e8f68319 68 GPCRC_Init_TypeDef crc_init;
AnnaBridge 187:0387e8f68319 69
AnnaBridge 187:0387e8f68319 70 crc_init.autoInit = false;
AnnaBridge 187:0387e8f68319 71 crc_init.enable = true;
AnnaBridge 187:0387e8f68319 72 crc_init.crcPoly = config->polynomial;
AnnaBridge 187:0387e8f68319 73
AnnaBridge 187:0387e8f68319 74 // GPCRC operates on bit-reversed inputs and outputs vs the standard
AnnaBridge 187:0387e8f68319 75 // defined by the mbed API. Emlib does the reversal on the poly, but
AnnaBridge 187:0387e8f68319 76 // not on the initial value.
AnnaBridge 187:0387e8f68319 77 if (config->width == 16) {
AnnaBridge 187:0387e8f68319 78 crc_init.initValue = __RBIT(config->initial_xor) >> 16;
AnnaBridge 187:0387e8f68319 79 } else {
AnnaBridge 187:0387e8f68319 80 crc_init.initValue = __RBIT(config->initial_xor);
AnnaBridge 187:0387e8f68319 81 }
AnnaBridge 187:0387e8f68319 82
AnnaBridge 187:0387e8f68319 83 // GPCRC operates on bit-reversed inputs and outputs vs the standard
AnnaBridge 187:0387e8f68319 84 // defined by the mbed API, so reflect_in/out needs to be negated.
AnnaBridge 187:0387e8f68319 85 if (config->reflect_in) {
AnnaBridge 187:0387e8f68319 86 crc_init.reverseByteOrder = false;
AnnaBridge 187:0387e8f68319 87 crc_init.reverseBits = false;
AnnaBridge 187:0387e8f68319 88 } else {
AnnaBridge 187:0387e8f68319 89 crc_init.reverseByteOrder = true;
AnnaBridge 187:0387e8f68319 90 crc_init.reverseBits = true;
AnnaBridge 187:0387e8f68319 91 }
AnnaBridge 187:0387e8f68319 92
AnnaBridge 187:0387e8f68319 93 // Disable byte mode to be able to run a faster U32 input version
AnnaBridge 187:0387e8f68319 94 crc_init.enableByteMode = false;
AnnaBridge 187:0387e8f68319 95
AnnaBridge 187:0387e8f68319 96 // GPCRC does not support hardware output bit-reversal, nor finalisation.
AnnaBridge 187:0387e8f68319 97 // Since the mbed API does not pass the config struct when fetching the
AnnaBridge 187:0387e8f68319 98 // CRC calculation result, we need to keep track of these locally.
AnnaBridge 187:0387e8f68319 99 revOutput = config->reflect_out;
AnnaBridge 187:0387e8f68319 100 final_xor = config->final_xor;
AnnaBridge 187:0387e8f68319 101
AnnaBridge 187:0387e8f68319 102 GPCRC_Init(GPCRC, &crc_init);
AnnaBridge 187:0387e8f68319 103 GPCRC_Start(GPCRC);
AnnaBridge 187:0387e8f68319 104 }
AnnaBridge 187:0387e8f68319 105
AnnaBridge 187:0387e8f68319 106 void hal_crc_compute_partial(const uint8_t *data, const size_t size)
AnnaBridge 187:0387e8f68319 107 {
AnnaBridge 187:0387e8f68319 108 if (data == NULL || size <= 0) {
AnnaBridge 187:0387e8f68319 109 return;
AnnaBridge 187:0387e8f68319 110 }
AnnaBridge 187:0387e8f68319 111
AnnaBridge 187:0387e8f68319 112 if (((uint32_t)data & 0x3) != 0 || size < 4) {
AnnaBridge 187:0387e8f68319 113 // Unaligned or very small input, run a bytewise CRC
AnnaBridge 187:0387e8f68319 114 for (size_t i = 0; i < size; i++) {
AnnaBridge 187:0387e8f68319 115 GPCRC_InputU8(GPCRC, data[i]);
AnnaBridge 187:0387e8f68319 116 }
AnnaBridge 187:0387e8f68319 117 } else {
AnnaBridge 187:0387e8f68319 118 // Aligned input, run 32-bit inputs as long as possible to make go faster.
AnnaBridge 187:0387e8f68319 119 size_t i = 0;
AnnaBridge 187:0387e8f68319 120 for (; i < (size & (~0x3)); i+=4) {
AnnaBridge 187:0387e8f68319 121 GPCRC_InputU32(GPCRC, *((uint32_t*)(&data[i])));
AnnaBridge 187:0387e8f68319 122 }
AnnaBridge 187:0387e8f68319 123 for (; i < size; i++) {
AnnaBridge 187:0387e8f68319 124 GPCRC_InputU8(GPCRC, data[i]);
AnnaBridge 187:0387e8f68319 125 }
AnnaBridge 187:0387e8f68319 126 }
AnnaBridge 187:0387e8f68319 127 }
AnnaBridge 187:0387e8f68319 128
AnnaBridge 187:0387e8f68319 129 uint32_t hal_crc_get_result(void)
AnnaBridge 187:0387e8f68319 130 {
AnnaBridge 187:0387e8f68319 131 uint32_t result;
AnnaBridge 187:0387e8f68319 132
AnnaBridge 187:0387e8f68319 133 // GPCRC operates on bit-reversed inputs and outputs vs the standard
AnnaBridge 187:0387e8f68319 134 // defined by the mbed API.
AnnaBridge 187:0387e8f68319 135 if (!revOutput) {
AnnaBridge 187:0387e8f68319 136 result = GPCRC_DataReadBitReversed(GPCRC);
AnnaBridge 187:0387e8f68319 137 } else {
AnnaBridge 187:0387e8f68319 138 result = GPCRC_DataRead(GPCRC);
AnnaBridge 187:0387e8f68319 139 }
AnnaBridge 187:0387e8f68319 140
AnnaBridge 187:0387e8f68319 141 GPCRC_Enable(GPCRC, false);
AnnaBridge 187:0387e8f68319 142
AnnaBridge 187:0387e8f68319 143 return result ^ final_xor;
AnnaBridge 187:0387e8f68319 144 }
AnnaBridge 187:0387e8f68319 145
AnnaBridge 187:0387e8f68319 146 #endif //GPCRC_PRESENT
AnnaBridge 187:0387e8f68319 147 #endif //DEVICE_CRC