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,19 +113,30 @@ 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 < sizeof ( uint32_t ) ) {
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
+ while (((uint32_t )(data + i ) & 0x3 ) != 0 ) {
126
+ GPCRC_InputU8 (GPCRC , data [i ]);
127
+ i ++ ;
128
+ }
129
+
130
+ // If enough input remaining to do word-sized writes, do so
131
+ while ((size - i ) >= sizeof (uint32_t )) {
121
132
GPCRC_InputU32 (GPCRC , * ((uint32_t * )(& data [i ])));
133
+ i += sizeof (uint32_t );
122
134
}
123
- for (; i < size ; i ++ ) {
135
+
136
+ // Do byte input to pick off the last remaining bytes
137
+ while (i < size ) {
124
138
GPCRC_InputU8 (GPCRC , data [i ]);
139
+ i ++ ;
125
140
}
126
141
}
127
142
}
0 commit comments