Bar Logo 4kW dsPIC33C PSFB DC-DC DA (Part-No. )
 
Content
     
Loading...
Searching...
No Matches
crc.c
1
17/*
18© [2025] Microchip Technology Inc. and its subsidiaries.
19
20 Subject to your compliance with these terms, you may use Microchip
21 software and any derivatives exclusively with Microchip products.
22 You are responsible for complying with 3rd party license terms
23 applicable to your use of 3rd party software (including open source
24 software) that may accompany Microchip software. SOFTWARE IS ?AS IS.?
25 NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS
26 SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT,
27 MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
28 WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
29 INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY
30 KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF
31 MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE
32 FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP?S
33 TOTAL LIABILITY ON ALL CLAIMS RELATED TO THE SOFTWARE WILL NOT
34 EXCEED AMOUNT OF FEES, IF ANY, YOU PAID DIRECTLY TO MICROCHIP FOR
35 THIS SOFTWARE.
36*/
37
38// Section: Included Files
39
40#include <stddef.h>
41#include "../crc.h"
42
43// Section: File specific functions
44
45static void (*CRC_EventHandler)(void) = NULL;
46// Section: Driver Interface
47
48const struct CRC_INTERFACE CRC = {
49 .Initialize = &CRC_Initialize,
50 .Deinitialize = &CRC_Deinitialize,
51 .SeedSet = &CRC_SeedSet,
52 .CalculateBufferStart = &CRC_CalculateBufferStart,
53 .CalculateProgramStart = &CRC_CalculateProgramStart,
54 .CalculationIsDone = &CRC_CalculationIsDone,
55 .CalculationResultGet = &CRC_CalculationResultGet,
56 .CalculationResultRawGet = &CRC_CalculationResultRawGet,
57 .CalculationResultReverseGet = &CRC_CalculationResultReverseGet,
58 .CalculationResultXORGet = &CRC_CalculationResultXORGet,
59 .EventCallbackRegister = &CRC_EventCallbackRegister,
60 .Tasks = &CRC_Tasks
61};
62// Section: Structure Declarations
63
64struct CRC_OBJ
65{
66 uint8_t dataWidth;
67 uint8_t polyWidth;
69 bool program;
70 uint32_t remainingSize;
71 union
72 {
73 uint8_t *data8bit;
74 uint16_t *data16bit;
75 uint32_t *data32bit;
76 void *data;
77 uint32_t program;
78 } ptr;
79};
80
81// Section: Private Data
82
83static struct CRC_OBJ crcObj;
84
86{
87 // reset the module
88 CRCCONL = 0;
89 CRCCONH = 0;
90 CRCXORH = 0;
91 CRCXORL = 0;
92 CRCWDATH = 0;
93 CRCWDATL = 0;
94
95 // initials the module - it will not be enabled until the end of the function
96 // MOD Legacy; LENDIAN Start with LSb; CRCISEL Interrupt on shift complete and results ready; VWORD 0x0; SIDL disabled; CRCGO CRC is turned off; CRCMPT disabled; CRCEN disabled; CRCFUL disabled;
97 CRCCONL = 0x8;
98 // PLEN 16; DWIDTH 16;
99 CRCCONH = 0xF0F;
100
102
103 // enable module
104 CRCCONLbits.CRCEN = 1;
105
106 // some polynomial
107 CRCXORL = 0x8005;
108 CRCXORH = 0x0;
109
110 // some seed
111 CRCWDATL = 0x0;
112 CRCWDATH = 0x0;
113
114 // set module state
115 crcObj.remainingSize = 0;
116 crcObj.state = CRC_STATE_CALCULATE;
117
118 crcObj.polyWidth = CRCCONHbits.PLEN + 1;
119}
120
122{
123
124 CRCCONL = 0x40;
125 CRCCONH = 0x0;
126 CRCXORL = 0x0;
127 CRCXORH = 0x0;
128 CRCWDATL = 0x0;
129 CRCWDATH = 0x0;
130}
131
132// Section: Private CRC Driver Functions
133
134static bool CRC_ProgramTask(void)
135{
136 uint16_t size;
137 uint16_t tempTbl;
138 uint16_t lowWord;
139 uint16_t highWord;
140 bool status = false;
141
142 size = (uint16_t)0xFFFE - (uint16_t)(crcObj.ptr.program & (uint16_t)0xFFFF);
143 tempTbl = TBLPAG;
144
145 CRCCONLbits.CRCGO = false;
146 IFS3bits.CRCIF = false;
147
148 TBLPAG = (uint16_t)(crcObj.ptr.program >> 16);
149
150 while((!CRCCONLbits.CRCFUL) && (crcObj.remainingSize) && (size))
151 {
152 lowWord = __builtin_tblrdl((uint16_t)(crcObj.ptr.program & (uint16_t)0xFFFF));
153 crcObj.ptr.program++;
154 highWord = __builtin_tblrdh((uint16_t)(crcObj.ptr.program & (uint16_t)0xFFFF));
155 crcObj.ptr.program++;
156
157 CRCDATL = lowWord;
158 CRCDATH = highWord;
159
160 crcObj.remainingSize -= (uint32_t)3;
161 size -= (uint16_t)2;
162 }
163
164 TBLPAG = tempTbl;
165
166 CRCCONLbits.CRCGO = true;
167
168 if(crcObj.remainingSize == (uint32_t)0)
169 {
170 status = true;
171
172 }
173
174 return status;
175}
176
177static bool CRC_BufferTask(void)
178{
179 bool status = false;
180
181 if(CRCCONLbits.CRCFUL != 0U)
182 {
183 status = false;
184 }
185 else
186 {
187 IFS3bits.CRCIF = false;
188
189 if(crcObj.dataWidth <= (uint8_t)8)
190 {
191 while((!CRCCONLbits.CRCFUL) && (crcObj.remainingSize))
192 {
193 *((uint8_t *)&CRCDATL) = *crcObj.ptr.data8bit;
194 crcObj.ptr.data8bit++;
195 crcObj.remainingSize--;
196 }
197 }
198 else if(crcObj.dataWidth <= (uint8_t)16)
199 {
200 while((!CRCCONLbits.CRCFUL) && (crcObj.remainingSize))
201 {
202 CRCDATL = *crcObj.ptr.data16bit;
203 crcObj.ptr.data16bit++;
204 crcObj.remainingSize -= (uint32_t)2;
205 }
206 }
207 else
208 {
209 while((!CRCCONLbits.CRCFUL) && (crcObj.remainingSize))
210 {
211 CRCDATL = *crcObj.ptr.data16bit;
212 crcObj.ptr.data16bit++;
213 CRCDATH = *crcObj.ptr.data16bit;
214 crcObj.ptr.data16bit++;
215 crcObj.remainingSize -= (uint32_t)4;
216 }
217 }
218
219 CRCCONLbits.CRCGO = true;
220
221 if(crcObj.remainingSize == (uint32_t)0)
222 {
223 status = true;
224 }
225 }
226
227 return status;
228}
229
230static bool CRC_FlushTask(void)
231{
232 bool status = false;
233
234 if(IFS3bits.CRCIF != 0U)
235 {
236
237 CRCCONLbits.CRCGO = false;
238 IFS3bits.CRCIF = false;
239
240 CRCCONHbits.DWIDTH = crcObj.polyWidth - (uint8_t)1;
241
242 if(crcObj.polyWidth <= (uint8_t)8)
243 {
244 *((uint8_t *)&CRCDATL) = 0;
245 }
246 else if(crcObj.polyWidth <= (uint8_t)16)
247 {
248 CRCDATL = 0;
249 }
250 else
251 {
252 CRCDATL = 0;
253 CRCDATH = 0;
254 }
255
256 CRCCONLbits.CRCGO = true;
257
258 status = true;
259 }
260
261 return status;
262}
263
264static bool CRC_CleanUpTask(void)
265{
266 bool status = false;
267
268 if(IFS3bits.CRCIF != 0U)
269 {
270
271 CRCCONHbits.DWIDTH = crcObj.dataWidth - (uint8_t)1;
272 CRCCONLbits.CRCGO = false;
273 IFS3bits.CRCIF = false;
274
275 status = true;
276 }
277
278 return status;
279}
280
281static uint32_t CRC_ReverseValue(uint32_t crc)
282{
283 uint32_t mask;
284 uint32_t reverse;
285 uint32_t crctemp = crc;
286
287 mask = 1;
288 mask <<= (crcObj.polyWidth - (uint8_t)1);
289 reverse = 0;
290
291 while(crctemp != 0U)
292 {
293 if((crctemp & (uint32_t)0x01) != 0U)
294 {
295 reverse |= mask;
296
297 }
298
299 mask >>= 1;
300 crctemp >>= 1;
301 }
302
303 return reverse;
304}
305
306static uint32_t CRC_PolynomialMask(void)
307{
308 uint32_t mask = 0;
309 uint32_t idx;
310
311 for(idx = 0; idx < crcObj.polyWidth; idx++)
312 {
313 mask <<= 1;
314 mask |= 1;
315 }
316
317 return mask;
318}
319
320// Section: CRC Module APIs
321
322void CRC_SeedSet(uint32_t seed, enum CRC_SEED_METHOD seedMethod, enum CRC_SEED_DIRECTION seedDirection)
323{
324 uint8_t direction = CRCCONLbits.LENDIAN;
325 uint8_t dataWidth = CRCCONHbits.DWIDTH;
326
327
328 if(seedMethod == CRC_SEED_METHOD_INDIRECT)
329 {
330 CRCWDATL = (uint16_t)seed;
331 CRCWDATH = (uint16_t)(seed >> 16);
332 }
333 else
334 {
335
336 CRCCONHbits.DWIDTH = CRCCONHbits.PLEN;
337 CRCCONLbits.LENDIAN = seedDirection;
338
339 if(crcObj.polyWidth <= (uint8_t)8)
340 {
341 *((uint8_t *)&CRCDATL) = (uint8_t)seed;
342 }
343 else if(crcObj.polyWidth <= (uint8_t)16)
344 {
345 CRCDATL = (uint16_t)seed;
346 }
347 else
348 {
349 CRCDATL = (uint16_t)seed;
350 CRCDATH = (uint16_t)(seed >> 16);
351 }
352
353 // Run the seed through the shift register
354 IFS3bits.CRCIF = false;
355
356 CRCCONLbits.CRCGO = true;
357 while(1){
358 if(IFS3bits.CRCIF == true){
359 break;
360 }
361
362 }
363
364 CRCCONLbits.CRCGO = false;
365
366 CRCCONLbits.LENDIAN = direction;
367 IFS3bits.CRCIF = false;
368 CRCCONHbits.DWIDTH = dataWidth;
369 }
370
371}
372
373void CRC_CalculateBufferStart(void *buffer, uint32_t sizeBytes)
374{
375 crcObj.dataWidth = CRCCONHbits.DWIDTH + 1;
376 crcObj.polyWidth = CRCCONHbits.PLEN + 1;
377 crcObj.remainingSize = sizeBytes;
378 crcObj.ptr.data = buffer;
379 crcObj.state = CRC_STATE_CALCULATE;
380 crcObj.program = false;
381
382 CRCCONLbits.CRCGO = true;
383}
384
385void CRC_CalculateProgramStart(uint32_t startAddr, uint32_t sizeBytes)
386{
387 crcObj.dataWidth = CRCCONHbits.DWIDTH + 1;
388 crcObj.polyWidth = CRCCONHbits.PLEN + 1;
389 crcObj.remainingSize = sizeBytes;
390 if(startAddr % 2 == 0)
391 {
392 crcObj.ptr.program = startAddr;
393 }
394 else
395 {
396 crcObj.ptr.program = startAddr - 1;
397 }
398 crcObj.state = CRC_STATE_CALCULATE;
399 crcObj.program = true;
400
401 CRCCONHbits.DWIDTH = 32 - 1;
402
403 CRCCONLbits.CRCGO = true;
404}
405
406void CRC_EventCallbackRegister(void (*handler)(void))
407{
408 if(NULL != handler)
409 {
410 CRC_EventHandler = handler;
411 }
412}
413
414void __attribute__ ((weak)) CRC_EventCallback ( void )
415{
416
417}
418
419
421{
422 return crcObj.state == CRC_STATE_DONE;
423}
424
426{
427 uint32_t result;
428
429 if(crcObj.polyWidth <= (uint8_t)8)
430 {
431 result = (uint32_t)CRCWDATL & (uint16_t)0xFF;
432 }
433 else if(crcObj.polyWidth <= (uint8_t)16)
434 {
435 result = (uint32_t)CRCWDATL;
436 }
437 else
438 {
439 result = (uint32_t)CRCWDATH;
440 result <<= 16;
441 result |= (uint32_t)CRCWDATL;
442 }
443
444 return result;
445}
446
448{
449 uint32_t result;
450
452
453 return CRC_ReverseValue(result);
454}
455
456uint32_t CRC_CalculationResultXORGet(uint32_t xorValue)
457{
458 uint32_t result;
459
461
462 result ^= xorValue;
463
464 return result & CRC_PolynomialMask();
465}
466
467uint32_t CRC_CalculationResultGet(bool reverse, uint32_t xorValue)
468{
469 uint32_t result;
470
472
473 if(reverse)
474 {
476 }
477 else
478 {
480 }
481
482 result ^= xorValue;
483
484 return result & CRC_PolynomialMask();
485}
486
487void CRC_Tasks(void)
488{
489 switch(crcObj.state)
490 {
492 if(crcObj.program)
493 {
494 if(CRC_ProgramTask())
495 {
496 crcObj.state = CRC_STATE_FLUSH;
497 }
498 }
499 else
500 {
501 if(CRC_BufferTask())
502 {
503 crcObj.state = CRC_STATE_FLUSH;
504 }
505 }
506 break;
507
508 case CRC_STATE_FLUSH:
509 if(CRC_FlushTask())
510 {
511 crcObj.state = CRC_STATE_CLEANUP;
512 }
513 break;
514
516 if(CRC_CleanUpTask())
517 {
518 crcObj.state = CRC_STATE_DONE;
519 }
520 break;
521
522 case CRC_STATE_DONE:
523 break;
524
525 default:
526 CRCCONL = 0;
527 CRCCONH = 0;
528 break;
529 }
530
531 if(IFS3bits.CRCIF != 0U)
532 {
533 if(NULL != CRC_EventHandler)
534 {
535 (*CRC_EventHandler)();
536 }
537 }
538}
539
This is the generated driver header file for the CRC driver.
@ CRC_SEED_METHOD_INDIRECT
Definition crc_types.h:68
@ CRC_STATE_CLEANUP
Definition crc_types.h:52
@ CRC_STATE_DONE
Definition crc_types.h:53
@ CRC_STATE_FLUSH
Definition crc_types.h:51
@ CRC_STATE_CALCULATE
Definition crc_types.h:50
size_t status
Definition uart1.c:99
void __attribute__((__interrupt__, auto_psv))
Executes the power converter control loop.
Definition main.c:101
const struct CRC_INTERFACE CRC
Structure object of type CRC_INTERFACE with the custom name given by the user in the Melody Driver Us...
Definition crc.c:48
void CRC_Initialize(void)
Initializes the CRC module. This function sets the polynomial and data width; data and seed shift; up...
Definition crc.c:85
uint32_t CRC_CalculationResultRawGet(void)
Gets the CRC raw result if the calculation is done.
Definition crc.c:425
void CRC_EventCallbackRegister(void(*handler)(void))
This function can be used to override default callback and to define custom callback for CRC Event ev...
Definition crc.c:406
uint32_t CRC_CalculationResultGet(bool reverse, uint32_t xorValue)
Gets the CRC result if the calculation is done.
Definition crc.c:467
void CRC_SeedSet(uint32_t seed, enum CRC_SEED_METHOD seedMethod, enum CRC_SEED_DIRECTION seedDirection)
Sets the CRC seed with method and direction.
Definition crc.c:322
void CRC_CalculateBufferStart(void *buffer, uint32_t sizeBytes)
CRC module calculation on a buffer in data space.
Definition crc.c:373
CRC_SEED_DIRECTION
Defines the CRC calculation seed direction in direct method CRC_SeedSet.
Definition crc_types.h:77
void CRC_Tasks(void)
This function cycles through the CRC calculations. This function will load the CRC module FIFO with...
Definition crc.c:487
void CRC_EventCallback(void)
This is the default callback with weak attribute. The user can override and implement the default cal...
void CRC_Deinitialize(void)
Deinitializes CRC to POR values.
Definition crc.c:121
uint32_t CRC_CalculationResultXORGet(uint32_t xorValue)
Gets the CRC XOR'd value of the result if the calculation is done.
Definition crc.c:456
CRC_SEED_METHOD
Defines the CRC calculation seed method CRC_SeedSet. The direct method refers to the seed being place...
Definition crc_types.h:66
uint32_t CRC_CalculationResultReverseGet(void)
Gets the CRC reversed value of result if the calculation is done.
Definition crc.c:447
void CRC_CalculateProgramStart(uint32_t startAddr, uint32_t sizeBytes)
Starts the CRC calculation on a buffer in program space.
Definition crc.c:385
bool CRC_CalculationIsDone(void)
Returns the CRC calculation complete status
Definition crc.c:420
CRC_STATE
Defines the CRC calculation states.
Definition crc_types.h:49
Structure containing the function pointers of CRC driver.
Definition crc.c:65
uint32_t program
Definition crc.c:77
uint32_t * data32bit
Definition crc.c:75
uint32_t remainingSize
Definition crc.c:70
uint16_t * data16bit
Definition crc.c:74
uint8_t dataWidth
Definition crc.c:66
void * data
Definition crc.c:76
enum CRC_STATE state
Definition crc.c:68
union CRC_OBJ::@0 ptr
uint8_t * data8bit
Definition crc.c:73
bool program
Definition crc.c:69
uint8_t polyWidth
Definition crc.c:67