34
34
#include "em_gpcrc.h"
35
35
36
36
static bool revOutput = false;
37
+ static bool enableWordInput = false;
37
38
static uint32_t final_xor ;
38
39
39
40
bool hal_crc_is_supported (const crc_mbed_config_t * config )
@@ -75,21 +76,24 @@ void hal_crc_compute_partial_start(const crc_mbed_config_t *config)
75
76
// defined by the mbed API. Emlib does the reversal on the poly, but
76
77
// not on the initial value.
77
78
if (config -> width == 16 ) {
79
+ enableWordInput = false;
78
80
crc_init .initValue = __RBIT (config -> initial_xor ) >> 16 ;
79
81
} else {
82
+ enableWordInput = true;
80
83
crc_init .initValue = __RBIT (config -> initial_xor );
81
84
}
82
85
83
86
// GPCRC operates on bit-reversed inputs and outputs vs the standard
84
87
// defined by the mbed API, so reflect_in/out needs to be negated.
85
88
if (config -> reflect_in ) {
86
- crc_init .reverseByteOrder = false;
87
89
crc_init .reverseBits = false;
88
90
} else {
89
- crc_init .reverseByteOrder = true;
90
91
crc_init .reverseBits = true;
91
92
}
92
93
94
+ // Input is little-endian
95
+ crc_init .reverseByteOrder = false;
96
+
93
97
// Disable byte mode to be able to run a faster U32 input version
94
98
crc_init .enableByteMode = false;
95
99
@@ -109,17 +113,28 @@ void hal_crc_compute_partial(const uint8_t *data, const size_t size)
109
113
return ;
110
114
}
111
115
112
- if ((( uint32_t ) data & 0x3 ) != 0 || size < 4 ) {
113
- // Unaligned or very small input, run a bytewise CRC
116
+ if (! enableWordInput || size < 4 ) {
117
+ // Input to a non-word-sized poly, or too small data size for a word input
114
118
for (size_t i = 0 ; i < size ; i ++ ) {
115
119
GPCRC_InputU8 (GPCRC , data [i ]);
116
120
}
117
121
} else {
118
- // Aligned input, run 32-bit inputs as long as possible to make go faster.
119
122
size_t i = 0 ;
120
- for (; i < (size & (~0x3 )); i += 4 ) {
123
+
124
+ // If input is unaligned, take off as many bytes as needed to align
125
+ if (((uint32_t )data & 0x3 ) != 0 ) {
126
+ for (; i < (sizeof (uint32_t ) - ((uint32_t )data & 0x3 )); i ++ ) {
127
+ GPCRC_InputU8 (GPCRC , data [i ]);
128
+ }
129
+ }
130
+
131
+ // If enough input remaining to do word-sized writes, do so
132
+ while ((size - i ) >= sizeof (uint32_t )) {
121
133
GPCRC_InputU32 (GPCRC , * ((uint32_t * )(& data [i ])));
134
+ i += 4 ;
122
135
}
136
+
137
+ // Do byte input to pick off the last remaining bytes
123
138
for (; i < size ; i ++ ) {
124
139
GPCRC_InputU8 (GPCRC , data [i ]);
125
140
}
0 commit comments