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
- Committer:
- AnnaBridge
- Date:
- 2018-11-08
- Revision:
- 188:bcfe06ba3d64
- Parent:
- 187:0387e8f68319
File content as of revision 188:bcfe06ba3d64:
/***************************************************************************//** * @file crc_api.c ******************************************************************************* * @section License * <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b> ******************************************************************************* * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include "device.h" #include "clocking.h" #include <stdio.h> #if DEVICE_CRC #include "mbed_assert.h" #include "crc_api.h" #include "em_cmu.h" #if defined(GPCRC_PRESENT) && (GPCRC_COUNT > 0) #include "em_gpcrc.h" static bool revOutput = false; static bool enableWordInput = false; static uint32_t final_xor; bool hal_crc_is_supported(const crc_mbed_config_t *config) { //GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly if (config == NULL) { return false; } if (config->width == 16) { return true; } else if (config->width == 32) { if (config->polynomial == POLY_32BIT_ANSI) { return true; } else { return false; } } else { return false; } } void hal_crc_compute_partial_start(const crc_mbed_config_t *config) { if (!hal_crc_is_supported(config)) { return; } CMU_ClockEnable(cmuClock_GPCRC, true); GPCRC_Reset(GPCRC); GPCRC_Init_TypeDef crc_init; crc_init.autoInit = false; crc_init.enable = true; crc_init.crcPoly = config->polynomial; // GPCRC operates on bit-reversed inputs and outputs vs the standard // defined by the mbed API. Emlib does the reversal on the poly, but // not on the initial value. if (config->width == 16) { enableWordInput = false; crc_init.initValue = __RBIT(config->initial_xor) >> 16; } else { enableWordInput = true; crc_init.initValue = __RBIT(config->initial_xor); } // GPCRC operates on bit-reversed inputs and outputs vs the standard // defined by the mbed API, so reflect_in/out needs to be negated. if (config->reflect_in) { crc_init.reverseBits = false; } else { crc_init.reverseBits = true; } // Input is little-endian crc_init.reverseByteOrder = false; // Disable byte mode to be able to run a faster U32 input version crc_init.enableByteMode = false; // GPCRC does not support hardware output bit-reversal, nor finalisation. // Since the mbed API does not pass the config struct when fetching the // CRC calculation result, we need to keep track of these locally. revOutput = config->reflect_out; final_xor = config->final_xor; GPCRC_Init(GPCRC, &crc_init); GPCRC_Start(GPCRC); } void hal_crc_compute_partial(const uint8_t *data, const size_t size) { if (data == NULL || size <= 0) { return; } if (!enableWordInput || size < sizeof(uint32_t)) { // Input to a non-word-sized poly, or too small data size for a word input for (size_t i = 0; i < size; i++) { GPCRC_InputU8(GPCRC, data[i]); } } else { size_t i = 0; // If input is unaligned, take off as many bytes as needed to align while (((uint32_t)(data + i) & 0x3) != 0) { GPCRC_InputU8(GPCRC, data[i]); i++; } // If enough input remaining to do word-sized writes, do so while ((size - i) >= sizeof(uint32_t)) { GPCRC_InputU32(GPCRC, *((uint32_t*)(&data[i]))); i += sizeof(uint32_t); } // Do byte input to pick off the last remaining bytes while (i < size) { GPCRC_InputU8(GPCRC, data[i]); i++; } } } uint32_t hal_crc_get_result(void) { uint32_t result; // GPCRC operates on bit-reversed inputs and outputs vs the standard // defined by the mbed API. if (!revOutput) { result = GPCRC_DataReadBitReversed(GPCRC); } else { result = GPCRC_DataRead(GPCRC); } GPCRC_Enable(GPCRC, false); return result ^ final_xor; } #endif //GPCRC_PRESENT #endif //DEVICE_CRC