Skip to content

Commit a4c40fd

Browse files
stevew817Cruz Monrreal II
authored andcommitted
Add implementation for CRC API
1 parent d7c925d commit a4c40fd

File tree

2 files changed

+153
-6
lines changed

2 files changed

+153
-6
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/***************************************************************************//**
2+
* @file crc_api.c
3+
*******************************************************************************
4+
* @section License
5+
* <b>(C) Copyright 2018 Silicon Labs, http://www.silabs.com</b>
6+
*******************************************************************************
7+
*
8+
* SPDX-License-Identifier: Apache-2.0
9+
*
10+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
11+
* not use this file except in compliance with the License.
12+
* You may obtain a copy of the License at
13+
*
14+
* http://www.apache.org/licenses/LICENSE-2.0
15+
*
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
18+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*
22+
******************************************************************************/
23+
24+
#include "device.h"
25+
#include "clocking.h"
26+
#include <stdio.h>
27+
28+
#if DEVICE_CRC
29+
#include "mbed_assert.h"
30+
#include "crc_api.h"
31+
#include "em_cmu.h"
32+
33+
#if defined(GPCRC_PRESENT) && (GPCRC_COUNT > 0)
34+
#include "em_gpcrc.h"
35+
36+
static bool revOutput = false;
37+
static uint32_t final_xor;
38+
39+
bool hal_crc_is_supported(const crc_mbed_config_t *config)
40+
{
41+
//GPCRC supports any 16-bit poly, but only the CCITT 32-bit poly
42+
if (config == NULL) {
43+
return false;
44+
}
45+
46+
if (config->width == 16) {
47+
return true;
48+
} else if (config->width == 32) {
49+
if (config->polynomial == POLY_32BIT_ANSI) {
50+
return true;
51+
} else {
52+
return false;
53+
}
54+
} else {
55+
return false;
56+
}
57+
}
58+
59+
void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
60+
{
61+
if (!hal_crc_is_supported(config)) {
62+
return;
63+
}
64+
65+
CMU_ClockEnable(cmuClock_GPCRC, true);
66+
GPCRC_Reset(GPCRC);
67+
68+
GPCRC_Init_TypeDef crc_init;
69+
70+
crc_init.autoInit = false;
71+
crc_init.enable = true;
72+
crc_init.crcPoly = config->polynomial;
73+
74+
// GPCRC operates on bit-reversed inputs and outputs vs the standard
75+
// defined by the mbed API. Emlib does the reversal on the poly, but
76+
// not on the initial value.
77+
if (config->width == 16) {
78+
crc_init.initValue = __RBIT(config->initial_xor) >> 16;
79+
} else {
80+
crc_init.initValue = __RBIT(config->initial_xor);
81+
}
82+
83+
// GPCRC operates on bit-reversed inputs and outputs vs the standard
84+
// defined by the mbed API, so reflect_in/out needs to be negated.
85+
if (config->reflect_in) {
86+
crc_init.reverseByteOrder = false;
87+
crc_init.reverseBits = false;
88+
} else {
89+
crc_init.reverseByteOrder = true;
90+
crc_init.reverseBits = true;
91+
}
92+
93+
// Disable byte mode to be able to run a faster U32 input version
94+
crc_init.enableByteMode = false;
95+
96+
// GPCRC does not support hardware output bit-reversal, nor finalisation.
97+
// Since the mbed API does not pass the config struct when fetching the
98+
// CRC calculation result, we need to keep track of these locally.
99+
revOutput = config->reflect_out;
100+
final_xor = config->final_xor;
101+
102+
GPCRC_Init(GPCRC, &crc_init);
103+
GPCRC_Start(GPCRC);
104+
}
105+
106+
void hal_crc_compute_partial(const uint8_t *data, const size_t size)
107+
{
108+
if (data == NULL || size <= 0) {
109+
return;
110+
}
111+
112+
if (((uint32_t)data & 0x3) != 0 || size < 4) {
113+
// Unaligned or very small input, run a bytewise CRC
114+
for (size_t i = 0; i < size; i++) {
115+
GPCRC_InputU8(GPCRC, data[i]);
116+
}
117+
} else {
118+
// Aligned input, run 32-bit inputs as long as possible to make go faster.
119+
size_t i = 0;
120+
for (; i < (size & (~0x3)); i+=4) {
121+
GPCRC_InputU32(GPCRC, *((uint32_t*)(&data[i])));
122+
}
123+
for (; i < size; i++) {
124+
GPCRC_InputU8(GPCRC, data[i]);
125+
}
126+
}
127+
}
128+
129+
uint32_t hal_crc_get_result(void)
130+
{
131+
uint32_t result;
132+
133+
// GPCRC operates on bit-reversed inputs and outputs vs the standard
134+
// defined by the mbed API.
135+
if (!revOutput) {
136+
result = GPCRC_DataReadBitReversed(GPCRC);
137+
} else {
138+
result = GPCRC_DataRead(GPCRC);
139+
}
140+
141+
GPCRC_Enable(GPCRC, false);
142+
143+
return result ^ final_xor;
144+
}
145+
146+
#endif //GPCRC_PRESENT
147+
#endif //DEVICE_CRC

targets/targets.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3255,7 +3255,7 @@
32553255
},
32563256
"EFM32PG_STK3401": {
32573257
"inherits": ["EFM32PG1B100F256GM32"],
3258-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
3258+
"device_has": ["ANALOGIN", "CRC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
32593259
"forced_reset_timeout": 2,
32603260
"config": {
32613261
"hf_clock_src": {
@@ -3318,7 +3318,7 @@
33183318
},
33193319
"EFR32MG1_BRD4150": {
33203320
"inherits": ["EFR32MG1P132F256GM48"],
3321-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
3321+
"device_has": ["ANALOGIN", "CRC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
33223322
"forced_reset_timeout": 2,
33233323
"config": {
33243324
"hf_clock_src": {
@@ -3361,7 +3361,7 @@
33613361
},
33623362
"TB_SENSE_1": {
33633363
"inherits": ["EFR32MG1P233F256GM48"],
3364-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
3364+
"device_has": ["ANALOGIN", "CRC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "FLASH"],
33653365
"forced_reset_timeout": 5,
33663366
"config": {
33673367
"hf_clock_src": {
@@ -3409,7 +3409,7 @@
34093409
},
34103410
"EFM32PG12_STK3402": {
34113411
"inherits": ["EFM32PG12B500F1024GL125"],
3412-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
3412+
"device_has": ["ANALOGIN", "CRC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
34133413
"forced_reset_timeout": 2,
34143414
"config": {
34153415
"hf_clock_src": {
@@ -3463,7 +3463,7 @@
34633463
"TB_SENSE_12": {
34643464
"inherits": ["EFR32MG12P332F1024GL125"],
34653465
"device_name": "EFR32MG12P332F1024GL125",
3466-
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
3466+
"device_has": ["ANALOGIN", "CRC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
34673467
"forced_reset_timeout": 5,
34683468
"config": {
34693469
"hf_clock_src": {
@@ -3512,7 +3512,7 @@
35123512
"EFM32GG11_STK3701": {
35133513
"inherits": ["EFM32GG11B820F2048GL192"],
35143514
"device_name": "EFM32GG11B820F2048GL192",
3515-
"device_has": ["ANALOGIN", "EMAC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
3515+
"device_has": ["ANALOGIN", "CRC", "EMAC", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "LPTICKER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_ASYNCH", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "USTICKER", "TRNG", "FLASH"],
35163516
"forced_reset_timeout": 5,
35173517
"config": {
35183518
"hf_clock_src": {

0 commit comments

Comments
 (0)