]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/sys/sys_selftest.c
Get rid of "last line of file ends without a newline" warning
[pes-rpp/rpp-lib.git] / rpp / src / sys / sys_selftest.c
1 /** @file sys_selftest.c
2 *   @brief Selftest Source File
3 *   @date 15.Mar.2012
4 *   @version 03.01.00
5 *
6 *   This file contains:
7 *   - Selftest API's
8 */
9
10 /* (c) Texas Instruments 2009-2012, All rights reserved. */
11
12 #include "sys/sys_selftest.h"
13
14 /** @fn void ccmSelfCheck(void)
15 *   @brief CCM module self check Driver
16 *
17 *   This function self checks the CCM module.
18 */
19 void ccmSelfCheck(void)
20 {
21     /* Run a diagnostic check on the CCM-R4F module */
22     /* This step ensures that the CCM-R4F can actually indicate an error */
23
24     /* Configure CCM in self-test mode */
25     CCMKEYR = 0x6;
26     /* Wait for CCM self-test to complete */
27     while ((CCMSR & 0x100) != 0x100);
28
29     /* Check if there was an error during the self-test */
30     if ((CCMSR & 0x1) == 0x1)
31     {
32         /* STE is set */
33         ccmFail(0);
34     }
35     else
36     {
37         /* Check CCM-R4 self-test error flag by itself (without compare error) */
38
39         /* Configure CCM in self-test error-forcing mode */
40         CCMKEYR = 0xF;
41         if ((esmREG->ESTATUS1[0] & 0x80000000) != 0x80000000)
42         {
43             /* ESM flag is not set */
44             ccmFail(1);
45         }
46         else
47         {
48             /* clear ESM group1 channel 31 flag */
49             esmREG->ESTATUS1[0] = 0x80000000;
50
51             /* Configure CCM in error-forcing mode */
52             CCMKEYR = 0x9;
53
54             /* check if compare error flag is set */
55             if ((esmREG->ESTATUS1[1] & 0x4) != 0x4)
56             {
57                 /* ESM flag is not set */
58                 ccmFail(2);
59             }
60             else
61             {
62                 /* clear ESM group2 channel 2 flag */
63                 esmREG->ESTATUS1[1] = 0x4;
64
65                 /* clear ESM group2 shadow status flag */
66                 esmREG->ESTATUS5EMU = 0x4;
67
68                 /* ESM self-test error needs to also be cleared */
69                 esmREG->ESTATUS1[0] = 0x80000000;
70
71                 /* Clear CCM-R4 CMPE flag */
72                 CCMSR = 0x00010000;
73
74                 /* Return CCM-R4 to lock-step mode */
75                 CCMKEYR = 0x0;
76
77                 /* The nERROR pin will become inactive once the LTC counter expires */
78                 esmREG->KEY = 0x5;
79             }
80         }
81     }
82 }
83
84 /** @fn void ccmFail(unsigned int x)
85 *   @brief CCM module fail service routine
86 *
87 *   This function is called if CCM module selftest fail.
88 */
89 void ccmFail(unsigned int x)
90 {
91     if (x == 0)
92     {
93         /* CCM-R4 is not able to flag a compare error in self-test mode.
94          * Lock-step operation cannot be verified.
95          */
96     }
97     else if (x == 1)
98     {
99         /* CCM-R4 self-test error flag is not set in ESM register.
100          * Could be due to a connection issue inside the part.
101          */
102     }
103     else if (x == 2)
104     {
105         /* CCM-R4 compare error flag is not set in ESM.
106          * Lock-step operation cannot be verified.
107          */
108     }
109 }
110
111 /** @fn void memoryInit(unsigned int ram)
112 *   @brief Memory Initialization Driver
113 *
114 *   This function is called to perform Memory initialization of selected RAM's.
115 */
116 void memoryInit(unsigned int ram)
117 {
118     /* Enable Memory Hardware Initialization */
119     systemREG1->MINITGCR = 0xA;
120
121     /* Enable Memory Hardware Initialization for selected RAM's */
122     systemREG1->MSINENA  = ram;
123
124     /* Wait until Memory Hardware Initialization complete */
125     while( systemREG1->MSTCGSTAT & 0x00000100 != 0x100);
126
127     /* Disable Memory Hardware Initialization */
128     systemREG1->MINITGCR = 0x5;
129 }
130
131 /** @fn void stcSelfCheck(void)
132 *   @brief STC module self check Driver
133 *
134 *   This function is called to perform STC module self check.
135 */
136 void stcSelfCheck(void)
137 {
138     volatile int i = 0;
139
140     /* Run a diagnostic check on the CPU self-test controller */
141     /* First set up the STC clock divider as STC is only supported up to 90MHz */
142
143     /* STC clock is now normal mode CPU clock frequency/2 = 180MHz/2 */
144     systemREG2->STCCLKDIV = 0x01000000;
145
146     /* Select one test interval, restart self-test next time, 0x00010001 */
147     stcREG->STCGCR0 = 0x00010001;
148
149     /* Enable comparator self-check and stuck-at-0 fault insertion in CPU, 0x1A */
150     stcREG->STCSCSCR = 0x1A;
151
152     /* Maximum time-out period */
153     stcREG->STCTPR = 0xFFFFFFFF;
154
155     /* wait for 16 VBUS clock cycles at least */
156     for (i=0; i<16; i++);
157
158     /* Enable self-test */
159     stcREG->STCGCR1 = 0xA;
160
161     /* wait for 16 VBUS clock cycles at least */
162     for (i=0; i<16; i++);
163
164     /* Idle the CPU so that the self-test can start */
165     _gotoCPUIdle_();
166
167 }
168
169 /** @fn void cpuSelfTest(unsigned int no_of_intervals, unsigned int max_timeout, boolean_t restart_test)
170 *   @brief CPU self test Driver
171 *   @param[in] no_of_intervals - Number of Test Intervals to be
172 *   @param[in] max_timeout     - Maximun Timeout to complete selected test Intervals
173 *   @param[in] restart_test    - Restart the test from Interval 0 or Continue from where it stopped.
174 *
175 *   This function is called to perfrom CPU self test using STC module.
176 */
177 void cpuSelfTest(unsigned int no_of_intervals, unsigned int max_timeout, boolean_t restart_test)
178 {
179     volatile int i = 0;
180
181     /* Run specified no of test intervals starting from interval 0 */
182     /* Start test from interval 0 or continue the test. */
183     stcREG->STCGCR0 = no_of_intervals << 16
184                     | (unsigned int) restart_test;
185
186     /* Configure Maximum time-out period */
187     stcREG->STCTPR = max_timeout;
188
189     /* wait for 16 VBUS clock cycles at least */
190     for (i=0; i<16; i++);
191
192     /* Enable self-test */
193     stcREG->STCGCR1 = 0xA;
194
195     /* Idle the CPU so that the self-test can start */
196
197     _gotoCPUIdle_();
198
199 }
200
201 /** @fn void pbistSelfCheck(void)
202 *   @brief PBIST self test Driver
203 *
204 *   This function is called to perfrom PBIST self test.
205 */
206 void pbistSelfCheck(void)
207 {
208     volatile uint32_t i = 0U;
209     uint32_t PBIST_FSRF0, PBIST_FSRF1, PBIST_wait_done_loop = 0U;
210     /* Run a diagnostic check on the memory self-test controller */
211     /* First set up the PBIST ROM clock as this clock frequency is limited to 90MHz */
212
213     /* Disable PBIST clocks and ROM clock */
214     pbistREG->PACT = 0x0U;
215
216     /* PBIST ROM clock frequency = HCLK frequency /2 */
217     /* Disable memory self controller */
218     systemREG1->MSTGCR = 0x00000105U;
219
220     /* Disable Memory Initialization controller */
221     systemREG1->MINITGCR = 0x5U;
222
223     /* Enable memory self controller */
224     systemREG1->MSTGCR = 0x0000010AU;
225
226     /* Clear PBIST Done */
227     systemREG1->MSTCGSTAT = 0x1U;
228
229     /* Enable PBIST controller */
230     systemREG1->MSINENA = 0x1U;
231
232     /* wait for 32 VBUS clock cycles at least, based on HCLK to VCLK ratio */
233         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
234         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
235     for (i=0U; i<(32U + (32U * 1U)); i++){ /* Wait */ }
236
237     /* Enable PBIST clocks and ROM clock */
238     pbistREG->PACT = 0x3U;
239
240     /* CPU control of PBIST */
241     pbistREG->DLR = 0x10U;
242
243     /* Custom always fail algo, this will not use the ROM and just set a fail */
244     pbistREG->RAMT         = 0x00002000U;
245     *(volatile uint32_t *)0xFFFFE400U = 0x4C000001U;
246     *(volatile uint32_t *)0xFFFFE440U = 0x00000075U;
247     *(volatile uint32_t *)0xFFFFE404U = 0x4C000002U;
248     *(volatile uint32_t *)0xFFFFE444U = 0x00000075U;
249     *(volatile uint32_t *)0xFFFFE408U = 0x4C000003U;
250     *(volatile uint32_t *)0xFFFFE448U = 0x00000075U;
251     *(volatile uint32_t *)0xFFFFE40CU = 0x4C000004U;
252     *(volatile uint32_t *)0xFFFFE44CU = 0x00000075U;
253     *(volatile uint32_t *)0xFFFFE410U = 0x4C000005U;
254     *(volatile uint32_t *)0xFFFFE450U = 0x00000075U;
255     *(volatile uint32_t *)0xFFFFE414U = 0x4C000006U;
256     *(volatile uint32_t *)0xFFFFE454U = 0x00000075U;
257     *(volatile uint32_t *)0xFFFFE418U = 0x00000000U;
258     *(volatile uint32_t *)0xFFFFE458U = 0x00000001U;
259
260     /* PBIST_RUN */
261     pbistREG->rsvd1[1U]    = 1U;
262
263     /* wait until memory self-test done is indicated */
264     /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
265     while ((systemREG1->MSTCGSTAT & 0x1U) != 0x1U)
266     {
267         PBIST_wait_done_loop++;
268     }/* Wait */
269
270     /* Check for the failure */
271     PBIST_FSRF0 = pbistREG->FSRF0;
272     PBIST_FSRF1 = pbistREG->FSRF1;
273     if (((PBIST_FSRF0 & 0x1U) != 0x1U) && ((PBIST_FSRF1 & 0x1U) != 0x1U))
274     {
275         /* No failure was indicated even if the always fail algorithm was run*/
276         pbistSelfCheckFail();
277     }
278     else
279     {
280         /* Check that the algorithm executed in the expected amount of time. */
281         /* This time is dependent on the ROMCLKDIV selected above            */
282         if (PBIST_wait_done_loop >= 2U)
283         {
284             pbistSelfCheckFail();
285         }
286
287         /* Disable PBIST clocks and ROM clock */
288         pbistREG->PACT = 0x0U;
289
290         /* Disable PBIST */
291         systemREG1->MSTGCR &= 0xFFFFFFF0U;
292         systemREG1->MSTGCR |= 0x5U;
293     }
294 }
295
296 /** @fn void pbistSelfCheckFail(void)
297 *   @brief PBIST self test Driver failure service routine
298 *
299 *   This function is called on PBIST self test failure.
300 */
301 void pbistSelfCheckFail(void)
302 {
303     /* The PBIST controller is not capable of reporting a failure.
304      * PBIST cannot be used to verify memory integrity.
305      * Need custom handler here.
306      */
307 }
308
309 /** @fn void pbistRun(unsigned int raminfoL, unsigned int algomask)
310 *   @brief CPU self test Driver
311 *   @param[in] raminfoL   - Select the list of RAM to be tested.
312 *   @param[in] algomask   - Select the list of Algorithm to be run.
313 *
314 *   This function performs Memory Built-in Self test using PBIST module.
315 */
316 void pbistRun(unsigned int raminfoL, unsigned int algomask)
317 {
318     volatile int i = 0;
319
320     /* PBIST ROM clock frequency = HCLK frequency /2 */
321     /* Disable memory self controller */
322     systemREG1->MSTGCR |= 0x00000105;
323
324     /* Disable Memory Initialization controller */
325     systemREG1->MINITGCR = 0x5U;
326
327     /* Enable PBIST controller */
328     systemREG1->MSINENA = 0x1;
329
330     /* clear MSTGENA field */
331     systemREG1->MSTGCR = 0x0000010AU;
332
333     /* Enable memory self controller */
334     systemREG1->MSTGCR = 0x0000010AU;
335
336     /* software loop to wait at least 32 VCLK cycles */
337     for (i=0U; i<(32U + (32U * 1U)); i++) ;
338
339     /* Enable PBIST clocks and ROM clock */
340     pbistREG->PACT = 0x3;
341
342     /* Select all algorithms to be tested */
343     pbistREG->ALGO = algomask;
344
345     /* Select RAM groups */
346     pbistREG->RINFOL = raminfoL;
347
348     /* Select all RAM groups */
349     pbistREG->RINFOU = 0x00000000;
350
351     /* ROM contents will not override RINFOx settings */
352     pbistREG->OVER = 0x0;
353
354     /* Algorithm code is loaded from ROM */
355     pbistREG->ROM = 0x3;
356
357     /* Start PBIST */
358     pbistREG->DLR = 0x14;
359 }
360
361 /** @fn void pbistStop(void)
362 *   @brief Routine to stop PBIST test enabled.
363 *
364 *   This function is called to stop PBIST after test is performed.
365 */
366 void pbistStop(void)
367 {
368     /* disable pbist clocks and ROM clock */
369     pbistREG->PACT = 0x0;
370     systemREG1->MSTGCR &= ~(0xF);
371     systemREG1->MSTGCR |= 0x5;
372 }
373
374 /** @fn boolean_t pbistIsTestCompleted(void)
375 *   @brief Checks to see if the PBIST test is completed.
376 *   @return 1 if PBIST test completed, otherwise 0.
377 *
378 *   Checks to see if the PBIST test is completed.
379 */
380 boolean_t pbistIsTestCompleted(void)
381 {
382     return ((systemREG1->MSTCGSTAT & 0x1) != 0);
383 }
384
385 /** @fn boolean_t pbistIsTestPassed(void)
386 *   @brief Checks to see if the PBIST test is completed sucessfully.
387 *   @return 1 if PBIST test passed, otherwise 0.
388 *
389 *   Checks to see if the PBIST test is completed sucessfully.
390 */
391 boolean_t pbistIsTestPassed(void)
392 {
393     return  ((pbistREG->FSRF0 || pbistREG->FSRF1) == 0);
394 }
395
396 /** @fn boolean_t pbistPortTestStatus(uint32_t port)
397 *   @brief Checks to see if the PBIST Port test is completed sucessfully.
398 *   @param[in] port   - Select the port to get the status.
399 *   @return 1 if PBIST Port test completed sucessfully, otherwise 0.
400 *
401 *   Checks to see if the selected PBIST Port test is completed sucessfully.
402 */
403 boolean_t pbistPortTestStatus(uint32_t port)
404 {
405     boolean_t status;
406
407     if(port == PBIST_PORT0)
408     {
409       status =  (pbistREG->FSRF0 == 0);
410     }
411     else
412     {
413       status =  (pbistREG->FSRF1 == 0);
414     }
415
416     return  status;
417 }
418
419 /* SourceId : SELFTEST_SourceId_042 */
420 /* DesignId : SELFTEST_DesignId_011 */
421 /* Requirements : HL_SR401 */
422 void pbistFail(void)
423 {
424         uint32_t PBIST_RAMT, PBIST_FSRA0, PBIST_FSRDL0, PBIST_FSRA1, PBIST_FSRDL1;
425     /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
426     PBIST_RAMT = pbistREG->RAMT;
427     PBIST_FSRA0 = pbistREG->FSRA0;
428     PBIST_FSRDL0 = pbistREG->FSRDL0;
429     PBIST_FSRA1 = pbistREG->FSRA1;
430     PBIST_FSRDL1 = pbistREG->FSRDL1;
431
432     if(pbistPortTestStatus((uint32_t)PBIST_PORT0) != TRUE)
433     {
434         memoryPort0TestFailNotification((uint32_t)((PBIST_RAMT & 0xFF000000U) >> 24U), (uint32_t)((PBIST_RAMT & 0x00FF0000U) >> 16U),(uint32_t)PBIST_FSRA0, (uint32_t)PBIST_FSRDL0);
435     }
436     else if(pbistPortTestStatus((uint32_t)PBIST_PORT1) != TRUE)
437     {
438         memoryPort1TestFailNotification((uint32_t)((PBIST_RAMT & 0xFF000000U) >> 24U), (uint32_t)((PBIST_RAMT & 0x00FF0000U) >> 16U), (uint32_t)PBIST_FSRA1, (uint32_t)PBIST_FSRDL1);
439     }
440     else
441     {
442         for(;;)
443         {
444         }/* Wait */
445
446     }
447 }
448
449
450 /** @fn void efcCheck(void)
451 *   @brief EFUSE module self check Driver
452 *   @return Returns 0 if no error was detected during autoload and Stuck At Zero Test passed
453 *                   1 if no error was detected during autoload but Stuck At Zero Test failed
454 *                   2 if there was a single-bit error detected during autoload
455 *                   3 if some other error occurred during autoload
456 *
457 *   This function self checks the EFSUE module.
458 */
459 uint32_t efcCheck(void)
460 {
461     unsigned int efcStatus = 0;
462
463     /* read the EFC Error Status Register */
464     efcStatus = efcREG->ERROR;
465     uint32_t status;
466
467     if (efcStatus == 0x0)
468     {
469         /* run stuck-at-zero test and check if it passed */
470         if (efcStuckZeroTest())
471         {
472             /* start EFC ECC logic self-test */
473             efcSelfTest();
474             status = 0U;
475         }
476         else
477         {
478             /* EFC output is stuck-at-zero, device operation unreliable */
479             efcClass2Error();
480             status = 1U;
481         }
482     }
483     /* EFC Error Register is not zero */
484     else
485     {
486         /* one-bit error detected during autoload */
487         if (efcStatus == 0x15)
488         {
489             /* start EFC ECC logic self-test */
490             efcSelfTest();
491             status = 2U;
492         }
493         else
494         {
495             /* Some other EFC error was detected */
496             efcClass2Error();
497             status = 3U;
498         }
499     }
500     return status;
501 }
502
503 /** @fn boolean_t efcStuckZeroTest(void)
504 *   @brief Checks to see if the EFUSE Stuck at zero test is completed sucessfully.
505 *   @return 1 if EFUSE Stuck at zero test completed, otherwise 0.
506 *
507 *   Checks to see if the EFUSE Stuck at zero test is completed sucessfully.
508 */
509 boolean_t efcStuckZeroTest(void)
510 {
511     boolean_t result = FALSE;
512     unsigned int error_checks = EFC_INSTRUCTION_INFO_EN  |
513                                 EFC_INSTRUCTION_ERROR_EN |
514                                 EFC_AUTOLOAD_ERROR_EN    |
515                                 EFC_SELF_TEST_ERROR_EN   ;
516
517     /* configure the output enable for auto load error , instruction info,
518        instruction error, and self test error using boundary register
519        and drive values one across all the errors */
520     efcREG->BOUNDARY = (OUTPUT_ENABLE | error_checks);
521
522     /* Read from the pin register. This register holds the current values
523        of above errors. This value should be 0x5c00.If not at least one of
524        the above errors is stuck at 0. */
525     if ((efcREG->PINS & 0x5C00) == 0x5C00)
526     {
527         /* check if the ESM group1 channels 40 is set and group3 channel 2 is set */
528         if (((esmREG->ESTATUS4[0] & 0x200) == 0x200) & ((esmREG->ESTATUS1[2] & 0x2) == 0x2))
529         {
530            /* stuck-at-zero test passed */
531            result = TRUE;
532         }
533     }
534
535     /* put the pins back low */
536     efcREG->BOUNDARY = OUTPUT_ENABLE;
537
538     /* clear group1 flags */
539     esmREG->ESTATUS4[0] = 0x300;
540
541     /* clear group3 flag */
542     esmREG->ESTATUS1[2] = 0x2;
543
544     /* The nERROR pin will become inactive once the LTC counter expires */
545     esmREG->KEY = 0x5;
546
547     return result;
548 }
549
550 /** @fn void efcSelfTest(void)
551 *   @brief EFUSE module self check Driver
552 *
553 *   This function self checks the EFSUE module.
554 */
555 void efcSelfTest(void)
556 {
557     /* configure self-test cycles */
558     efcREG->SELF_TEST_CYCLES = 0x258;
559
560     /* configure self-test signature */
561     efcREG->SELF_TEST_SIGN = 0x5362F97F;
562
563     /* configure boundary register to start ECC self-test */
564     efcREG->BOUNDARY = 0x0000200F;
565 }
566
567 /** @fn boolean_t checkefcSelfTest(void)
568 *   @brief EFUSE module self check Driver
569 *
570 *   This function self checks the EFSUE module.
571 */
572 boolean_t checkefcSelfTest(void)
573 {
574     boolean_t result = FALSE;
575
576     /* wait until EFC self-test is done */
577     while(!(efcREG->PINS & EFC_SELF_TEST_DONE));
578
579     /* check if EFC self-test error occurred */
580     if (!(efcREG->PINS & EFC_SELF_TEST_ERROR) & !(efcREG->ERROR & SELF_TEST_ERROR))
581     {
582         /* check if EFC self-test error is set */
583         if ((esmREG->ESTATUS4[0] & 0x100) != 0x100)
584         {
585             result = TRUE;
586         }
587     }
588     return result;
589 }
590
591 /** @fn void efcClass1Error(void)
592 *   @brief EFUSE Class1 Error service routine
593 *
594 *   This function is called if EFC ECC logic self-test.
595 */
596 void efcClass1Error(void)
597 {
598     /* Autoload error was detected during device power-up, and device operation is not reliable. */
599     while(1);
600 }
601
602 /** @fn void efcClass2Error(void)
603 *   @brief EFUSE Class2 Error service routine
604 *
605 *   This function is called if EFC output is stuck-at-zero.
606 */
607 void efcClass2Error(void)
608 {
609     /* The ECC logic inside the eFuse controller is not operational. Device operation is not reliable. */
610 }
611
612 /** @fn void fmcBus2Check(void)
613 *   @brief Self Check Flash Bus2 Interface
614 *
615 *   This function self checks Flash Bus2 Interface
616 */
617 void fmcBus2Check(void)
618 {
619     /* enable ECC logic inside FMC */
620     flashWREG->FEDACCTRL1 = 0x000A060A;
621
622     if (esmREG->ESTATUS1[0] & 0x40)
623     {
624         /* a 1-bit error was detected during flash OTP read by flash module
625            run a self-check on ECC logic inside FMC */
626
627         /* clear ESM group1 channel 6 flag */
628         esmREG->ESTATUS1[0] = 0x40;
629
630         fmcECCcheck();
631     }
632
633     /* no 2-bit or 1-bit error detected during power-up */
634     else
635     {
636         fmcECCcheck();
637     }
638 }
639
640 /** @fn void fmcECCcheck(void)
641 *   @brief Check Flash ECC Single Bit and multi Bit errors detection logic.
642 *
643 *   This function Checks Flash ECC Single Bit and multi Bit errors detection logic.
644 */
645 void fmcECCcheck(void)
646 {
647     volatile unsigned int otpread;
648     volatile unsigned int temp;
649
650     /* read location with deliberate 1-bit error */
651     otpread = flash1bitError;
652     if (esmREG->ESTATUS1[0] & 0x40)
653     {
654         /* 1-bit failure was indicated and corrected */
655         flashWREG->FEDACSTATUS = 0x00010006;
656
657         /* clear ESM group1 channel 6 flag */
658         esmREG->ESTATUS1[0] = 0x40;
659
660         /* read location with deliberate 2-bit error */
661         otpread = flash2bitError;
662         if (esmREG->ESTATUS1[2] & 0x80)
663         {
664             /* 2-bit failure was detected correctly */
665             temp = flashWREG->FUNCERRADD;
666             flashWREG->FEDACSTATUS = 0x00020100;
667
668             /* clear ESM group3 channel 7 */
669             esmREG->ESTATUS1[2] = 0x80;
670
671             /* The nERROR pin will become inactive once the LTC counter expires */
672             esmREG->KEY = 0x5;
673
674         }
675         else
676         {
677             /* ECC logic inside FMC cannot detect 2-bit error */
678             fmcClass2Error();
679         }
680     }
681     else
682     {
683         /* ECC logic inside FMC cannot detect 1-bit error */
684         fmcClass2Error();
685     }
686 }
687
688 /** @fn void fmcClass1Error(void)
689 *   @brief Flash Multi bit ECC error service routine detected during reset configuration.
690 *
691 *   This function is called if Flash Multi bit ECC error detected during reset configuration.
692 */
693 void fmcClass1Error(void)
694 {
695     /* there was a multi-bit error detected during the reset configuration word read from the OTP */
696     /* This affects the device power domains, endianness, and exception handling ISA */
697     /* Device operation is not reliable. */
698     while(1);
699 }
700
701 /** @fn void fmcClass2Error(void)
702 *   @brief Flash OTP or EEPROM read Multi bit ECC error service routine
703 *
704 *   This function is called if Flash OTP or EEPROM read Multi bit ECC error detected.
705 */
706 void fmcClass2Error(void)
707 {
708     /* The ECC logic inside FMC used to protect against 1-bit and 2-bit errors in OTP and EEPROM banks */
709     /* is not operational. Device operation is not reliable. */
710     while(1);
711 }
712
713 /** @fn void checkB0RAMECC(void)
714 *   @brief Check TCRAM1 ECC error detection logic.
715 *
716 *   This function checks TCRAM1 ECC error detection logic.
717 */
718 void checkB0RAMECC(void)
719 {
720     volatile unsigned int ramread = 0;
721
722     /* enable writes to ECC RAM, enable ECC error response */
723     tcram1REG->RAMCTRL = 0x0005010A;
724     tcram2REG->RAMCTRL = 0x0005010A;
725
726     /* the first 1-bit error will cause an error response */
727     tcram1REG->RAMTHRESHOLD = 0x1;
728     tcram2REG->RAMTHRESHOLD = 0x1;
729
730     /* allow SERR to be reported to ESM */
731     tcram1REG->RAMINTCTRL = 0x1;
732     tcram2REG->RAMINTCTRL = 0x1;
733
734     /* cause a 1-bit ECC error */
735     tcramA1bitError ^= 0x1;
736
737     /* disable writes to ECC RAM */
738     tcram1REG->RAMCTRL = 0x0005000A;
739     tcram2REG->RAMCTRL = 0x0005000A;
740
741     /* read from location with 1-bit ECC error */
742     ramread = tcramA1bit;
743
744     /* SERR not set in TCRAM1 or TCRAM2 modules */
745     if (!((tcram1REG->RAMERRSTATUS & 1) || (tcram2REG->RAMERRSTATUS & 1)))
746     {
747         /* TCRAM module does not reflect 1-bit error reported by CPU */
748         tcramClass2Error();
749     }
750     else
751     {
752         /* clear SERR flag */
753         tcram1REG->RAMERRSTATUS = 0x1;
754         tcram2REG->RAMERRSTATUS = 0x1;
755
756         /* clear status flags for ESM group1 channels 26 and 28 */
757         esmREG->ESTATUS1[0] = 0x14000000;
758     }
759
760     /* enable writes to ECC RAM, enable ECC error response */
761     tcram1REG->RAMCTRL = 0x0005010A;
762     tcram2REG->RAMCTRL = 0x0005010A;
763
764     /* cause a 2-bit ECC error */
765     tcramA2bitError ^= 0x3;
766     ramread = tcram1REG->RAMCTRL;
767     ramread = tcram2REG->RAMCTRL;
768
769     /* read from location with 2-bit ECC error this will cause a data abort to be generated */
770     ramread = tcramA2bit;
771 }
772
773 /** @fn void checkB1RAMECC(void)
774 *   @brief Check TCRAM2 ECC error detection logic.
775 *
776 *   This function checks TCRAM2 ECC error detection logic.
777 */
778 void checkB1RAMECC(void)
779 {
780     volatile unsigned int ramread = 0;
781
782     /* enable writes to ECC RAM, enable ECC error response */
783     tcram1REG->RAMCTRL = 0x0005010A;
784     tcram2REG->RAMCTRL = 0x0005010A;
785
786     /* the first 1-bit error will cause an error response */
787     tcram1REG->RAMTHRESHOLD = 0x1;
788     tcram2REG->RAMTHRESHOLD = 0x1;
789
790     /* allow SERR to be reported to ESM */
791     tcram1REG->RAMINTCTRL = 0x1;
792     tcram2REG->RAMINTCTRL = 0x1;
793
794     /* cause a 1-bit ECC error */
795     tcramB1bitError ^= 0x1;
796
797     /* disable writes to ECC RAM */
798     tcram1REG->RAMCTRL = 0x0005000A;
799     tcram2REG->RAMCTRL = 0x0005000A;
800
801     /* read from location with 1-bit ECC error */
802     ramread = tcramB1bit;
803
804     /* SERR not set in TCRAM1 or TCRAM2 modules */
805     if (!((tcram1REG->RAMERRSTATUS & 1) || (tcram2REG->RAMERRSTATUS & 1)))
806     {
807         /* TCRAM module does not reflect 1-bit error reported by CPU */
808         tcramClass2Error();
809     }
810     else
811     {
812         /* clear SERR flag */
813         tcram1REG->RAMERRSTATUS = 0x1;
814         tcram2REG->RAMERRSTATUS = 0x1;
815
816         /* clear status flags for ESM group1 channels 26 and 28 */
817         esmREG->ESTATUS1[0] = 0x14000000;
818     }
819
820     /* enable writes to ECC RAM, enable ECC error response */
821     tcram1REG->RAMCTRL = 0x0005010A;
822     tcram2REG->RAMCTRL = 0x0005010A;
823
824     /* cause a 2-bit ECC error */
825     tcramB2bitError ^= 0x3;
826
827     /* disable writes to ECC RAM */
828     tcram1REG->RAMCTRL = 0x0005000A;
829     tcram2REG->RAMCTRL = 0x0005000A;
830 }
831
832 /** @fn void tcramClass1Error(void)
833 *   @brief Error service routine called if TCRAM module cannot capture 2-bit error.
834 *
835 *   Error service routine called if TCRAM module cannot respond to 2-bit error.
836 */
837 void tcramClass1Error(void)
838 {
839     /* TCRAM module is not capable of responding to 2-bit error indicated by CPU.
840      * Device operation is not reliable and not recommended.
841      */
842     while(1);
843 }
844
845 /** @fn void tcramClass2Error(void)
846 *   @brief Error service routine called if TCRAM module cannot capture 1-bit error.
847 *
848 *   Error service routine called if TCRAM module cannot respond to 1-bit error.
849 */
850 void tcramClass2Error(void)
851 {
852     /* TCRAM module is not capable of responding to 1-bit error indicated by CPU.
853      * Device operation is possible, but is prone to future multi-bit errors not being detected.
854      * Need custom handler here instead of the infinite loop.
855      */
856     while(1);
857 }
858
859 /** @fn void checkFlashECC(void)
860 *   @brief Check Flash ECC error detection logic.
861 *
862 *   This function checks Flash ECC error detection logic.
863 */
864 void checkFlashECC(void)
865 {
866     /* Routine to check operation of ECC logic inside CPU for accesses to program flash */
867     volatile unsigned int flashread = 0;
868
869     /* Flash Module ECC Response enabled */
870     flashWREG->FEDACCTRL1 = 0x000A060A;
871
872     /* Enable diagnostic mode and select diag mode 7 */
873     flashWREG->FDIAGCTRL = 0x00050007;
874
875     /* Select ECC diagnostic mode, single-bit to be corrupted */
876     flashWREG->FPAROVR = 0x00005401;
877
878     /* Set the trigger for the diagnostic mode */
879     flashWREG->FDIAGCTRL |= 0x01000000;
880
881     /* read a flash location from the mirrored memory map */
882     flashread = flashBadECC;
883
884     /* disable diagnostic mode */
885     flashWREG->FDIAGCTRL = 0x000A0007;
886
887     /* this will have caused a single-bit error to be generated and corrected by CPU */
888     /* single-bit error not captured in flash module */
889     if (!(flashWREG->FEDACSTATUS & 0x2))
890     {
891         flashClass2Error();
892     }
893     else
894     {
895         /* clear single-bit error flag */
896         flashWREG->FEDACSTATUS = 0x2;
897
898         /* clear ESM flag */
899         esmREG->ESTATUS1[0] = 0x40;
900
901         /* Enable diagnostic mode and select diag mode 7 */
902         flashWREG->FDIAGCTRL = 0x00050007;
903
904         /* Select ECC diagnostic mode, two bits of ECC to be corrupted */
905         flashWREG->FPAROVR = 0x00005A03;
906
907         /* Set the trigger for the diagnostic mode */
908         flashWREG->FDIAGCTRL |= 0x01000000;
909
910         /* read from flash location from mirrored memory map this will cause a data abort */
911         flashread = flashBadECC;
912     }
913
914 }
915
916 /** @fn void flashClass1Error(void)
917 *   @brief Error service routine called if Flash module cannot capture 2-bit error.
918 *
919 *   Error service routine called if Flash module cannot capture 2-bit error.
920 */
921 void flashClass1Error(void)
922 {
923     /* Flash module not able to capture 2-bit error from CPU.
924      * Device operation not reliable.
925      */
926     while(1);
927
928 }
929
930 /** @fn void flashClass2Error(void)
931 *   @brief Error service routine called if Flash module cannot capture 1-bit error.
932 *
933 *   Error service routine called if Flash module cannot capture 1-bit error.
934 */
935 void flashClass2Error(void)
936 {
937     /* Flash module not able to capture 1-bit error from CPU.
938      * Device operation possible if this weakness in diagnostic is okay.
939      */
940 }
941
942 /** @fn void custom_dabort(void)
943 *   @brief Custom Data abort routine for the application.
944 *
945 *   Custom Data abort routine for the application.
946 */
947 void custom_dabort(void)
948 {
949     /* Need custom data abort handler here.
950      * This data abort is not caused due to diagnostic checks of flash and TCRAM ECC logic.
951      */
952 }
953
954 /** @fn void stcSelfCheckFail(void)
955 *   @brief STC Self test check fail service routine
956 *
957 *   This function is called if STC Self test check fail.
958 */
959 void stcSelfCheckFail(void)
960 {
961     /* CPU self-test controller's own self-test failed.
962      * It is not possible to verify that STC is capable of indicating a CPU self-test error.
963      * It is not recommended to continue operation.
964      */
965     while(1);
966 }
967
968 /** @fn void cpuSelfTestFail(void)
969 *   @brief CPU Self test check fail service routine
970 *
971 *   This function is called if CPU Self test check fail.
972 */
973 void cpuSelfTestFail(void)
974 {
975     /* CPU self-test has failed.
976      * CPU operation is not reliable.
977      */
978     while(1);
979 }
980
981
982 /** @fn void vimParityCheck(void)
983 *   @brief Routine to check VIM RAM parity error detection and signaling mechanism
984 *
985 *   Routine to check VIM RAM parity error detection and signaling mechanism
986 */
987 void vimParityCheck(void)
988 {
989     volatile unsigned int vimramread = 0;
990
991     /* Enable parity checking and parity test mode */
992     VIM_PARCTL = 0x0000010A;
993
994     /* flip a bit in the VIM RAM parity location */
995     VIMRAMPARLOC ^= 0x1;
996
997     /* disable parity test mode */
998     VIM_PARCTL = 0x0000000A;
999
1000     /* cause parity error */
1001     vimramread = VIMRAMLOC;
1002
1003     /* check if ESM group1 channel 15 is flagged */
1004     if (!(esmREG->ESTATUS1[0] & 0x8000))
1005     {
1006         /* VIM RAM parity error was not flagged to ESM. */
1007         /* Need custom routine to handle this failure instead of the infinite loop. */
1008         while(1);
1009     }
1010     else
1011     {
1012         /* clear VIM RAM parity error flag in VIM */
1013         VIM_PARFLG = 0x1;
1014
1015         /* clear ESM group1 channel 15 flag */
1016         esmREG->ESTATUS1[0] = 0x8000;
1017     }
1018 }
1019
1020 /** @fn void dmaParityCheck(void)
1021 *   @brief Routine to check DMA control packet RAM parity error detection and signaling mechanism
1022 *
1023 *   Routine to check DMA control packet RAM parity error detection and signaling mechanism
1024 */
1025 void dmaParityCheck(void)
1026 {
1027     volatile unsigned int dmaread = 0;
1028
1029     /* Enable parity checking and parity test mode */
1030     DMA_PARCR = 0x0000010A;
1031
1032     /* Flip a bit in DMA RAM parity location */
1033     DMARAMPARLOC ^= 0x1;
1034
1035     /* Disable parity test mode */
1036     DMA_PARCR = 0x0000000A;
1037
1038     /* Cause parity error */
1039     dmaread = DMARAMLOC;
1040
1041     /* Check if ESM group1 channel 3 is flagged */
1042     if (!(esmREG->ESTATUS1[0] & 0x8))
1043     {
1044         /* DMA RAM parity error was not flagged to ESM. */
1045         /* Need custom routine to handle this failure instead of the infinite loop. */
1046         while(1);
1047     }
1048     else
1049     {
1050         /* clear DMA parity error flag in DMA */
1051         DMA_PARADDR = 0x01000000;
1052
1053         /* clear ESM group1 channel 3 flag */
1054         esmREG->ESTATUS1[0] = 0x8;
1055     }
1056
1057 }
1058
1059 /** @fn void het1ParityCheck(void)
1060 *   @brief Routine to check HET1 RAM parity error detection and signaling mechanism
1061 *
1062 *   Routine to check HET1 RAM parity error detection and signaling mechanism
1063 */
1064 void het1ParityCheck(void)
1065 {
1066     volatile unsigned int nhetread = 0;
1067
1068     /* Set TEST mode and enable parity checking */
1069     hetREG1->PCREG = 0x0000010A;
1070
1071     /* flip parity bit */
1072     NHET1RAMPARLOC ^= 0x1;
1073
1074     /* Disable TEST mode */
1075     hetREG1->PCREG = 0x0000000A;
1076
1077     /* read to cause parity error */
1078     nhetread = NHET1RAMLOC;
1079
1080     /* check if ESM group1 channel 7 is flagged */
1081     if (!(esmREG->ESTATUS1[0] & 0x80))
1082     {
1083         /* NHET1 RAM parity error was not flagged to ESM. */
1084         /* Need custom routine to handle this failure instead of the infinite loop. */
1085         while(1);
1086     }
1087     else
1088     {
1089         /* clear ESM group1 channel 7 flag */
1090         esmREG->ESTATUS1[0] = 0x80;
1091     }
1092 }
1093
1094 /** @fn void htu1ParityCheck(void)
1095 *   @brief Routine to check HTU1 RAM parity error detection and signaling mechanism
1096 *
1097 *   Routine to check HTU1 RAM parity error detection and signaling mechanism
1098 */
1099 void htu1ParityCheck(void)
1100 {
1101     volatile unsigned int hturead = 0;
1102     /* Enable parity and TEST mode */
1103     htuREG1->PCR = 0x0000010A;
1104
1105     /* flip parity bit */
1106     HTU1PARLOC ^= 0x1;
1107
1108     /* Disable parity RAM test mode */
1109     htuREG1->PCR = 0x0000000A;
1110
1111     /* read to cause parity error */
1112     hturead = HTU1RAMLOC;
1113
1114     /* check if ESM group1 channel 8 is flagged */
1115     if (!(esmREG->ESTATUS1[0] & 0x100))
1116     {
1117         /* HTU1 RAM parity error was not flagged to ESM. */
1118         /* Need custom routine to handle this failure instead of the infinite loop. */
1119         while(1);
1120     }
1121     else
1122     {
1123         /* Clear HTU parity error flag */
1124         htuREG1->PAR = 0x00010000;
1125         esmREG->ESTATUS1[0] = 0x100;
1126     }
1127 }
1128
1129 /** @fn void het2ParityCheck(void)
1130 *   @brief Routine to check HET2 RAM parity error detection and signaling mechanism
1131 *
1132 *   Routine to check HET2 RAM parity error detection and signaling mechanism
1133 */
1134 void het2ParityCheck(void)
1135 {
1136     volatile unsigned int nhetread = 0;
1137
1138     /* Set TEST mode and enable parity checking */
1139     hetREG2->PCREG = 0x0000010A;
1140
1141     /* flip parity bit */
1142     NHET2RAMPARLOC ^= 0x1;
1143
1144     /* Disable TEST mode */
1145     hetREG2->PCREG = 0x0000000A;
1146
1147     /* read to cause parity error */
1148     nhetread = NHET2RAMLOC;
1149
1150     /* check if ESM group1 channel 7 or 34 is flagged */
1151     if (!(esmREG->ESTATUS1[0] & 0x80) && !(esmREG->ESTATUS4[0] & 0x4))
1152     {
1153         /* NHET2 RAM parity error was not flagged to ESM. */
1154         /* Need custom routine to handle this failure instead of the infinite loop. */
1155         while(1);
1156     }
1157     else
1158     {
1159         /* clear ESM group1 channel 7 flag */
1160         esmREG->ESTATUS1[0] = 0x80;
1161
1162         /* clear ESM group1 channel 34 flag */
1163         esmREG->ESTATUS4[0] = 0x4;
1164     }
1165 }
1166
1167 /** @fn void htu2ParityCheck(void)
1168 *   @brief Routine to check HTU2 RAM parity error detection and signaling mechanism
1169 *
1170 *   Routine to check HTU2 RAM parity error detection and signaling mechanism
1171 */
1172 void htu2ParityCheck(void)
1173 {
1174     volatile unsigned int hturead = 0;
1175
1176     /* Enable parity and TEST mode */
1177     htuREG2->PCR = 0x0000010A;
1178
1179     /* flip parity bit */
1180     HTU2PARLOC ^= 0x1;
1181
1182     /* Disable parity RAM test mode */
1183     htuREG2->PCR = 0x0000000A;
1184
1185     /* read to cause parity error */
1186     hturead = HTU2RAMLOC;
1187
1188     /* check if ESM group1 channel 8 is flagged */
1189     if (!(esmREG->ESTATUS1[0] & 0x100))
1190     {
1191         /* HTU2 RAM parity error was not flagged to ESM. */
1192         /* Need custom routine to handle this failure instead of the infinite loop. */
1193         while(1);
1194     }
1195     else
1196     {
1197         /* Clear HTU parity error flag */
1198         htuREG2->PAR = 0x00010000;
1199         esmREG->ESTATUS1[0] = 0x100;
1200     }
1201 }
1202
1203 /** @fn void adc1ParityCheck(void)
1204 *   @brief Routine to check ADC1 RAM parity error detection and signaling mechanism
1205 *
1206 *   Routine to check ADC1 RAM parity error detection and signaling mechanism
1207 */
1208 void adc1ParityCheck(void)
1209 {
1210     volatile unsigned int adcramread = 0;
1211
1212     /* Set the TEST bit in the PARCR and enable parity checking */
1213     adcREG1->PARCR = 0x10A;
1214
1215     /* Invert the parity bits inside the ADC1 RAM's first location */
1216     adcPARRAM1 = ~(adcPARRAM1);
1217
1218     /* clear the TEST bit */
1219     adcREG1->PARCR = 0x00A;
1220
1221     /* This read is expected to trigger a parity error */
1222     adcramread = adcRAM1;
1223
1224     /* Check for ESM group1 channel 19 to be flagged */
1225     if (!(esmREG->ESTATUS1[0] & 0x80000))
1226     {
1227         /* no ADC1 RAM parity error was flagged to ESM */
1228         /* Need custom routine to handle this failure instead of the infinite loop */
1229         while(1);
1230     }
1231     else
1232     {
1233         /* clear ADC1 RAM parity error flag */
1234         esmREG->ESTATUS1[0] = 0x80000;
1235     }
1236 }
1237
1238 /** @fn void adc2ParityCheck(void)
1239 *   @brief Routine to check ADC2 RAM parity error detection and signaling mechanism
1240 *
1241 *   Routine to check ADC2 RAM parity error detection and signaling mechanism
1242 */
1243 void adc2ParityCheck(void)
1244 {
1245     volatile unsigned int adcramread = 0;
1246
1247     /* Set the TEST bit in the PARCR and enable parity checking */
1248     adcREG2->PARCR = 0x10A;
1249
1250     /* Invert the parity bits inside the ADC2 RAM's first location */
1251     adcPARRAM2 = ~(adcPARRAM2);
1252
1253     /* clear the TEST bit */
1254     adcREG2->PARCR = 0x00A;
1255
1256     /* This read is expected to trigger a parity error */
1257     adcramread = adcRAM2;
1258
1259     /* Check for ESM group1 channel 1 to be flagged */
1260     if (!(esmREG->ESTATUS1[0] & 0x2))
1261     {
1262         /* no ADC2 RAM parity error was flagged to ESM */
1263         /* Need custom routine to handle this failure instead of the infinite loop */
1264         while(1);
1265     }
1266     else
1267     {
1268         /* clear ADC2 RAM parity error flag */
1269         esmREG->ESTATUS1[0] = 0x2;
1270     }
1271 }
1272
1273 /** @fn void can1ParityCheck(void)
1274 *   @brief Routine to check CAN1 RAM parity error detection and signaling mechanism
1275 *
1276 *   Routine to check CAN1 RAM parity error detection and signaling mechanism
1277 */
1278 void can1ParityCheck(void)
1279 {
1280     volatile unsigned int canread = 0;
1281
1282     /* Disable parity, init mode, TEST mode */
1283     canREG1->CTL = 0x00001481;
1284
1285     /* Enable RAM Direct Access mode */
1286     canREG1->TEST = 0x00000200;
1287
1288     /* flip the parity bit */
1289     canPARRAM1 ^= 0x00001000;
1290
1291     /* Enable parity, disable init, still TEST mode */
1292     canREG1->CTL = 0x00002880;
1293
1294     /* Read location with parity error */
1295     canread = canRAM1;
1296
1297     /* check if ESM group1 channel 21 is flagged */
1298     if (!(esmREG->ESTATUS1[0] & 0x00200000))
1299     {
1300         /* No DCAN1 RAM parity error was flagged to ESM */
1301         /* Need custom routine to handle this failure instead of the infinite loop */
1302         while(1);
1303     }
1304     else
1305     {
1306         /* clear ESM group1 channel 21 flag */
1307         esmREG->ESTATUS1[0] = 0x00200000;
1308
1309         /* disable TEST mode */
1310         canREG1->CTL = 0x00002800;
1311     }
1312 }
1313
1314 /** @fn void can2ParityCheck(void)
1315 *   @brief Routine to check CAN2 RAM parity error detection and signaling mechanism
1316 *
1317 *   Routine to check CAN2 RAM parity error detection and signaling mechanism
1318 */
1319 void can2ParityCheck(void)
1320 {
1321     volatile unsigned int canread = 0;
1322
1323     /* Disable parity, init mode, TEST mode */
1324     canREG2->CTL = 0x00001481;
1325
1326     /* Enable RAM Direct Access mode */
1327     canREG2->TEST = 0x00000200;
1328
1329     /* flip the parity bit */
1330     canPARRAM2 ^= 0x00001000;
1331
1332     /* Enable parity, disable init, still TEST mode */
1333     canREG2->CTL = 0x00002880;
1334
1335     /* Read location with parity error */
1336     canread = canRAM2;
1337
1338     /* check if ESM group1 channel 23 is flagged */
1339     if (!(esmREG->ESTATUS1[0] & 0x00800000))
1340     {
1341         /* No DCAN2 RAM parity error was flagged to ESM */
1342         /* Need custom routine to handle this failure instead of the infinite loop */
1343         while(1);
1344     }
1345     else
1346     {
1347         /* clear ESM group1 channel 23 flag */
1348         esmREG->ESTATUS1[0] = 0x00800000;
1349
1350         /* disable TEST mode */
1351         canREG2->CTL = 0x00002800;
1352     }
1353 }
1354
1355 /** @fn void can3ParityCheck(void)
1356 *   @brief Routine to check CAN3 RAM parity error detection and signaling mechanism
1357 *
1358 *   Routine to check CAN3 RAM parity error detection and signaling mechanism
1359 */
1360 void can3ParityCheck(void)
1361 {
1362     volatile unsigned int canread = 0;
1363
1364     /* Disable parity, init mode, TEST mode */
1365     canREG3->CTL = 0x00001481;
1366
1367     /* Enable RAM Direct Access mode */
1368     canREG3->TEST = 0x00000200;
1369
1370     /* flip the parity bit */
1371     canPARRAM3 ^= 0x00001000;
1372
1373     /* Enable parity, disable init, still TEST mode */
1374     canREG3->CTL = 0x00002880;
1375
1376     /* Read location with parity error */
1377     canread = canRAM3;
1378
1379     /* check if ESM group1 channel 22 is flagged */
1380     if (!(esmREG->ESTATUS1[0] & 0x00400000))
1381     {
1382         /* No DCAN3 RAM parity error was flagged to ESM */
1383         /* Need custom routine to handle this failure instead of the infinite loop */
1384         while(1);
1385     }
1386     else
1387     {
1388         /* clear ESM group1 channel 22 flag */
1389         esmREG->ESTATUS1[0] = 0x00400000;
1390
1391         /* disable TEST mode */
1392         canREG3->CTL = 0x00002800;
1393     }
1394 }
1395
1396 /** @fn void mibspi1ParityCheck(void)
1397 *   @brief Routine to check MIBSPI1 RAM parity error detection and signaling mechanism
1398 *
1399 *   Routine to check MIBSPI1 RAM parity error detection and signaling mechanism
1400 */
1401 void mibspi1ParityCheck(void)
1402 {
1403     volatile unsigned int spiread = 0;
1404
1405     /* enable multi-buffered mode */
1406     mibspiREG1->MIBSPIE = 0x1;
1407
1408     /* enable parity error detection */
1409     mibspiREG1->EDEN = 0xA;
1410
1411     /* enable parity test mode */
1412     mibspiREG1->PTESTEN = 1;
1413
1414     /* flip bit 0 of the parity location */
1415     mibspiPARRAM1 ^= 0x1;
1416
1417     /* disable parity test mode */
1418     mibspiREG1->PTESTEN = 0;
1419
1420     /* read from MibSPI1 RAM to cause parity error */
1421     spiread = *(unsigned int *) mibspiRAM1;
1422
1423     /* check if ESM group1 channel 17 is flagged */
1424     if (!(esmREG->ESTATUS1[0] & 0x20000))
1425     {
1426         /* No MibSPI1 RAM parity error was flagged to ESM. */
1427         /* Need custom routine to handle this failure instead of the infinite loop */
1428         while(1);
1429     }
1430     else
1431     {
1432         /* clear parity error flags */
1433         mibspiREG1->UERRSTAT = 0x3;
1434
1435         /* clear ESM group1 channel 17 flag */
1436         esmREG->ESTATUS1[0] = 0x20000;
1437
1438         /* enable parity test mode */
1439         mibspiREG1->PTESTEN = 1;
1440
1441         /* Revert back to correct data, flip bit 0 of the parity location */
1442         mibspiPARRAM1 ^= 0x1;
1443
1444         /* disable parity test mode */
1445         mibspiREG1->PTESTEN = 0;
1446     }
1447 }
1448
1449 /** @fn void mibspi3ParityCheck(void)
1450 *   @brief Routine to check MIBSPI3 RAM parity error detection and signaling mechanism
1451 *
1452 *   Routine to check MIBSPI3 RAM parity error detection and signaling mechanism
1453 */
1454 void mibspi3ParityCheck(void)
1455 {
1456     volatile unsigned int spiread = 0;
1457
1458     /* enable multi-buffered mode */
1459     mibspiREG3->MIBSPIE = 0x1;
1460
1461     /* enable parity test mode */
1462     mibspiREG3->PTESTEN = 1;
1463
1464     /* flip bit 0 of the parity location */
1465     mibspiPARRAM3 ^= 0x1;
1466
1467     /* enable parity error detection */
1468     mibspiREG3->EDEN = 0xA;
1469
1470     /* disable parity test mode */
1471     mibspiREG3->PTESTEN = 0;
1472
1473     /* read from MibSPI3 RAM to cause parity error */
1474     spiread = *(unsigned int *) mibspiRAM3;
1475
1476     /* check if ESM group1 channel 18 is flagged */
1477     if (!(esmREG->ESTATUS1[0] & 0x40000))
1478     {
1479         /* No MibSPI3 RAM parity error was flagged to ESM. */
1480         /* Need custom routine to handle this failure instead of the infinite loop */
1481         while(1);
1482     }
1483     else
1484     {
1485         /* clear parity error flags */
1486         mibspiREG3->UERRSTAT = 0x3;
1487
1488         /* clear ESM group1 channel 18 flag */
1489         esmREG->ESTATUS1[0] = 0x40000;
1490
1491         /* enable parity test mode */
1492         mibspiREG3->PTESTEN = 1;
1493
1494         /* Revert back to correct data, flip bit 0 of the parity location */
1495         mibspiPARRAM3 ^= 0x1;
1496
1497         /* disable parity test mode */
1498         mibspiREG3->PTESTEN = 0;
1499     }
1500 }
1501
1502 /** @fn void mibspi5ParityCheck(void)
1503 *   @brief Routine to check MIBSPI5 RAM parity error detection and signaling mechanism
1504 *
1505 *   Routine to check MIBSPI5 RAM parity error detection and signaling mechanism
1506 */
1507 void mibspi5ParityCheck(void)
1508 {
1509     volatile unsigned int spiread = 0;
1510
1511     /* enable multi-buffered mode */
1512     mibspiREG5->MIBSPIE = 0x1;
1513
1514     /* enable parity test mode */
1515     mibspiREG5->PTESTEN = 1;
1516
1517     /* flip bit 0 of the parity location */
1518     mibspiPARRAM5 ^= 0x1;
1519
1520     /* enable parity error detection */
1521     mibspiREG5->EDEN = 0xA;
1522
1523     /* disable parity test mode */
1524     mibspiREG5->PTESTEN = 0;
1525
1526     /* read from MibSPI5 RAM to cause parity error */
1527     spiread = *(unsigned int *) mibspiRAM5;
1528
1529     /* check if ESM group1 channel 24 is flagged */
1530     if (!(esmREG->ESTATUS1[0] & 0x01000000))
1531     {
1532         /* No MibSPI5 RAM parity error was flagged to ESM. */
1533         /* Need custom routine to handle this failure instead of the infinite loop */
1534         while(1);
1535     }
1536     else
1537     {
1538         /* clear parity error flags */
1539         mibspiREG5->UERRSTAT = 0x3;
1540
1541         /* clear ESM group1 channel 24 flag */
1542         esmREG->ESTATUS1[0] = 0x01000000;
1543
1544         /* enable parity test mode */
1545         mibspiREG5->PTESTEN = 1;
1546
1547         /* Revert back to correct data, flip bit 0 of the parity location */
1548         mibspiPARRAM5 ^= 0x1;
1549
1550         /* disable parity test mode */
1551         mibspiREG5->PTESTEN = 0;
1552     }
1553 }
1554
1555 /** @fn void errata_PBIST_4(void)
1556 *   @brief Workaround for the Errata PBIST#4.
1557 *
1558 *   This function is workaround for Errata PBIST#4.
1559 *   This function is designed to initialize the ROMs using the PBIST controller.
1560 *   The CPU will configure the PBIST controller to test the PBIST ROM and STC ROM.
1561 *   This function should be called at startup after system init before using the ROMs.
1562 */
1563 void errata_PBIST_4(void)
1564 {
1565     volatile uint32_t i = 0U;
1566     uint8_t ROM_count;
1567     int32_t PBIST_wait_done_loop;
1568     uint32_t pmuCalibration, pmuCount;
1569
1570     /* PMU calibration */
1571     _pmuEnableCountersGlobal_();
1572     _pmuResetCounters_();
1573     _pmuStartCounters_(pmuCYCLE_COUNTER);
1574     _pmuStopCounters_(pmuCYCLE_COUNTER);
1575     pmuCalibration=_pmuGetCycleCount_();
1576
1577     /* ROM_init Setup using special reserved registers as part of errata fix */
1578     /* (Only to be used in this function) */
1579     *(volatile uint32_t *)0xFFFF0400U = 0x0000000AU;
1580     *(volatile uint32_t *)0xFFFF040CU = 0x0000EE0AU;
1581
1582     /* Loop for Executing PBIST ROM and STC ROM */
1583     for (ROM_count = 0U; ROM_count < 2U; ROM_count++)
1584     {
1585         PBIST_wait_done_loop = 0;
1586
1587         /* Disable PBIST clocks and ROM clock */
1588         pbistREG->PACT = 0x0U;
1589
1590         /* PBIST Clocks did not disable */
1591         if(pbistREG->PACT != 0x0U )
1592         {
1593                 pbistSelfCheckFail();
1594         }
1595         else
1596         {
1597             /* PBIST ROM clock frequency = HCLK frequency /2 */
1598             /* Disable memory self controller */
1599             systemREG1->MSTGCR = 0x00000105U;
1600
1601             /* Disable Memory Initialization controller */
1602             systemREG1->MINITGCR = 0x5U;
1603
1604             /* Enable memory self controller */
1605             systemREG1->MSTGCR = 0x0000010AU;
1606
1607             /* Clear PBIST Done */
1608             systemREG1->MSTCGSTAT = 0x1U;
1609
1610             /* Enable PBIST controller */
1611             systemREG1->MSINENA = 0x1U;
1612
1613                         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
1614                 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Wait for few clock cycles (Value of i not used)" */
1615             /* wait for 32 VBUS clock cycles at least, based on HCLK to VCLK ratio */
1616             for (i=0U; i<(32U + (32U * 1U)); i++){ /* Wait */ }
1617
1618             /* Enable PBIST clocks and ROM clock */
1619             pbistREG->PACT = 0x3U;
1620
1621             /* CPU control of PBIST */
1622             pbistREG->DLR = 0x10U;
1623
1624             /* Load PBIST ALGO to initialize the ROMs */
1625             *(volatile uint32_t *)0xFFFFE400U = 0x00000001U;
1626             *(volatile uint32_t *)0xFFFFE440U = 0x00000025U;
1627             *(volatile uint32_t *)0xFFFFE404U = 0x62400001U;
1628             *(volatile uint32_t *)0xFFFFE444U = 0x00000004U;
1629             *(volatile uint32_t *)0xFFFFE408U = 0x00068003U;
1630             *(volatile uint32_t *)0xFFFFE448U = 0x00000000U;
1631             *(volatile uint32_t *)0xFFFFE40CU = 0x00000004U;
1632             *(volatile uint32_t *)0xFFFFE44CU = 0x00006860U;
1633             *(volatile uint32_t *)0xFFFFE410U = 0x00000000U;
1634             *(volatile uint32_t *)0xFFFFE450U = 0x00000001U;
1635             *(volatile uint32_t *)0xFFFFE540U = 0x000003E8U;
1636             *(volatile uint32_t *)0xFFFFE550U = 0x00000001U;
1637             *(volatile uint32_t *)0xFFFFE530U = 0x00000000U;
1638
1639                         /* SELECT ROM */
1640             if (ROM_count == 1U)
1641             {
1642                 /* SELECT PBIST ROM */
1643                 *(volatile uint32_t *)0xFFFFE520U = 0x00000002U;
1644                 *(volatile uint32_t *)0xFFFFE524U = 0x00000000U;
1645                 pbistREG->RAMT                  = 0x01002008U;
1646             }
1647             else
1648             {
1649                 /* SELECT STC ROM */
1650                 *(volatile uint32_t *)0xFFFFE520U = 0xFFF0007CU;
1651                 *(volatile uint32_t *)0xFFFFE524U = 0x0A63FFFFU;
1652                 pbistREG->RAMT                  = 0x02002008U;
1653             }
1654
1655             /*  Setup using special reserved registers as part of errata fix */
1656             /*      (Only to be used in this function) */
1657             pbistREG->rsvd1[4U]    = 1U;
1658             pbistREG->rsvd1[0U]    = 3U;
1659
1660             /* Start PMU counter */
1661                         _pmuResetCounters_();
1662             _pmuStartCounters_(pmuCYCLE_COUNTER);
1663
1664             /* PBIST_RUN */
1665             pbistREG->rsvd1[1U]    = 1U;
1666
1667             /* wait until memory self-test done is indicated */
1668             /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
1669             while ((systemREG1->MSTCGSTAT & 0x1U) != 0x1U)
1670             {
1671             }/* Wait */
1672
1673                         /* Stop PMU counter */
1674             _pmuStopCounters_(pmuCYCLE_COUNTER);
1675
1676                         /* Get CPU cycle count */
1677             pmuCount =_pmuGetCycleCount_();
1678
1679                         /* Calculate PBIST test complete time in ROM Clock */
1680                         /* 2 - Divide value ( Default is 2 in HALCoGen) */
1681                         /* 1000 = 0x3E8 - Test Loop count in ROM Algorithm */
1682                         pmuCount = pmuCount - pmuCalibration;
1683             PBIST_wait_done_loop = ((int32_t)pmuCount/2) - 1000;
1684
1685             /* Check PBIST status results (Address, Status, Count, etc...) */
1686             if ((pbistREG->FSRA0 | pbistREG->FSRA1 | pbistREG->FSRDL0 | pbistREG->rsvd3 |
1687                  pbistREG->FSRDL1 | pbistREG->rsvd4[0U] | pbistREG->rsvd4[1U]) != 0U)
1688             {
1689                 /* PBIST Failure for the Algorithm chosen above */
1690                 pbistSelfCheckFail();
1691             }
1692
1693             /* Check that the algorithm executed in the expected amount of time. */
1694             /* This time is dependent on the ROMCLKDIV selected */
1695             if ((PBIST_wait_done_loop <= 20) || (PBIST_wait_done_loop >= 200) )
1696             {
1697                 pbistSelfCheckFail();
1698             }
1699
1700             /* Disable PBIST clocks and ROM clock */
1701             pbistREG->PACT = 0x0U;
1702
1703             /* Disable PBIST */
1704             systemREG1->MSTGCR &= 0xFFFFFFF0U;
1705             systemREG1->MSTGCR |= 0x5U;
1706         }
1707     } /* ROM Loop */
1708
1709     /* ROM restore default setup */
1710     /* (must be completed before continuing) */
1711     *(volatile uint32_t *)0xFFFF040CU = 0x0000AA0AU;
1712     *(volatile uint32_t *)0xFFFF040CU = 0x0000AA05U;
1713         *(volatile uint32_t *)0xFFFF0400U = 0x00000005U;
1714
1715         _pmuDisableCountersGlobal_();
1716 }
1717
1718 /** @fn void enableParity(void)
1719 *   @brief Enable peripheral RAM parity
1720 *
1721 *   This function enables RAM parity for all peripherals for which RAM parity check is enabled.
1722 *   This function is called before memoryInit in the startup
1723 *
1724 */
1725 #pragma WEAK(enableParity)
1726 void enableParity(void)
1727 {
1728     DMA_PARCR = 0xAU;                      /* Enable DMA RAM parity */
1729     VIM_PARCTL = 0xAU;                     /* Enable VIM RAM parity */
1730     canREG1->CTL = (uint32_t)0xAU << 10U;    /* Enable CAN1 RAM parity */
1731     canREG2->CTL = (uint32_t)0xAU << 10U;    /* Enable CAN2 RAM parity */
1732     canREG3->CTL = (uint32_t)0xAU << 10U;    /* Enable CAN3 RAM parity */
1733     adcREG1->PARCR = 0xAU;                 /* Enable ADC1 RAM parity */
1734     adcREG2->PARCR = 0xAU;                 /* Enable ADC2 RAM parity */
1735     hetREG1->PCREG = 0xAU;                   /* Enable HET1 RAM parity */
1736     htuREG1->PCR = 0xAU;                   /* Enable HTU1 RAM parity */
1737     hetREG2->PCREG = 0xAU;                   /* Enable HET2 RAM parity */
1738     htuREG2->PCR = 0xAU;                   /* Enable HTU2 RAM parity */
1739 }
1740
1741 /** @fn void disableParity(void)
1742 *   @brief Disable peripheral RAM parity
1743 *
1744 *   This function disables RAM parity for all peripherals for which RAM parity check is enabled.
1745 *   This function is called after memoryInit in the startup
1746 *
1747 */
1748 #pragma WEAK(disableParity)
1749 void disableParity(void)
1750 {
1751     DMA_PARCR = 0x5U;                      /* Disable DMA RAM parity */
1752     VIM_PARCTL = 0x5U;                     /* Disable VIM RAM parity */
1753     canREG1->CTL = (uint32_t)0x5U << 10U;    /* Disable CAN1 RAM parity */
1754     canREG2->CTL = (uint32_t)0x5U << 10U;    /* Disable CAN2 RAM parity */
1755     canREG3->CTL = (uint32_t)0x5U << 10U;    /* Disable CAN3 RAM parity */
1756     adcREG1->PARCR = 0x5U;                 /* Disable ADC1 RAM parity */
1757     adcREG2->PARCR = 0x5U;                 /* Disable ADC2 RAM parity */
1758     hetREG1->PCREG = 0x5U;                   /* Disable HET1 RAM parity */
1759     htuREG1->PCR = 0x5U;                   /* Disable HTU1 RAM parity */
1760     hetREG2->PCREG = 0x5U;                   /* Disable HET2 RAM parity */
1761     htuREG2->PCR = 0x5U;                   /* Disable HTU2 RAM parity */
1762 }