1 /** @file sys_startup.c
\r
2 * @brief Startup Source File
\r
6 * This file contains:
\r
9 * - External Functions
\r
13 * which are relevant for the Startup.
\r
16 /* (c) Texas Instruments 2009-2012, All rights reserved. */
\r
18 /* USER CODE BEGIN (0) */
\r
24 #include "sys_common.h"
\r
26 #include "sys_vim.h"
\r
27 #include "sys_core.h"
\r
28 #include "sys_selftest.h"
\r
32 /* USER CODE BEGIN (1) */
\r
36 /* Type Definitions */
\r
38 typedef void (*handler_fptr)(const uint8_t *in, uint8_t *out);
\r
40 /* USER CODE BEGIN (2) */
\r
44 /* External Functions */
\r
46 #pragma WEAK(__TI_Handler_Table_Base)
\r
47 #pragma WEAK(__TI_Handler_Table_Limit)
\r
48 #pragma WEAK(__TI_CINIT_Base)
\r
49 #pragma WEAK(__TI_CINIT_Limit)
\r
51 extern uint32_t __TI_Handler_Table_Base;
\r
52 extern uint32_t __TI_Handler_Table_Limit;
\r
53 extern uint32_t __TI_CINIT_Base;
\r
54 extern uint32_t __TI_CINIT_Limit;
\r
55 extern uint32_t __TI_PINIT_Base;
\r
56 extern uint32_t __TI_PINIT_Limit;
\r
57 extern uint32_t * __binit__;
\r
59 extern void main(void);
\r
60 extern void exit(void);
\r
62 extern void muxInit(void);
\r
64 /* USER CODE BEGIN (3) */
\r
68 /* Vim Ram Definition */
\r
70 * @brief Vim Ram Definition
\r
72 * This type is used to access the Vim Ram.
\r
74 /** @typedef vimRAM_t
\r
75 * @brief Vim Ram Type Definition
\r
77 * This type is used to access the Vim Ram.
\r
79 typedef volatile struct vimRam
\r
81 t_isrFuncPTR ISR[VIM_CHANNELS + 1];
\r
84 #define vimRAM ((vimRAM_t *)0xFFF82000U)
\r
86 static const t_isrFuncPTR s_vim_init[] =
\r
89 &esmHighInterrupt, // 0
\r
94 &phantomInterrupt, // 5
\r
99 &phantomInterrupt, // 10
\r
101 &mibspi1HighLevelInterrupt,
\r
102 &linHighLevelInterrupt,
\r
104 &adc1Group1Interrupt, // 15
\r
105 &can1HighLevelInterrupt,
\r
106 &spi2HighLevelInterrupt,
\r
109 &phantomInterrupt, // 20
\r
114 &phantomInterrupt, // 25
\r
115 &mibspi1LowLevelInterrupt,
\r
119 &spi2LowLevelInterrupt, // 30
\r
124 &can2HighLevelInterrupt, // 35
\r
126 &mibspi3HighInterruptLevel,
\r
127 &mibspi3LowLevelInterrupt,
\r
129 &phantomInterrupt, // 40
\r
134 &can3HighLevelInterrupt, // 45
\r
138 &spi4HighLevelInterrupt,
\r
139 &phantomInterrupt, // 50
\r
140 &adc2Group1Interrupt,
\r
143 &spi4LowLevelInterrupt,
\r
144 &phantomInterrupt, // 55
\r
149 &phantomInterrupt, // 60
\r
153 &sciHighLevelInterrupt,
\r
154 &phantomInterrupt, // 65
\r
159 &phantomInterrupt, // 70
\r
164 &phantomInterrupt, // 75
\r
169 &phantomInterrupt, // 80
\r
174 &phantomInterrupt, // 85
\r
179 &phantomInterrupt, // 90
\r
184 &phantomInterrupt, // 95
\r
189 &phantomInterrupt, // 100
\r
220 /* Startup Routine */
\r
222 /* USER CODE BEGIN (4) */
\r
223 /* USER CODE END */
\r
225 #pragma INTERRUPT(_c_int00, RESET)
\r
230 /* USER CODE BEGIN (5) */
\r
231 /* USER CODE END */
\r
233 /* Initialize Core Registers to avoid CCM Error */
\r
234 _coreInitRegisters_();
\r
236 /* USER CODE BEGIN (6) */
\r
237 /* USER CODE END */
\r
239 /* Initialize Stack Pointers */
\r
240 _coreInitStackPointer_();
\r
242 /* USER CODE BEGIN (7) */
\r
243 /* USER CODE END */
\r
245 /* Implement work-around for CCM-R4 issue on silicon revision A */
\r
246 if (DEVICE_ID_REV == 0x802AAD05)
\r
248 _esmCcmErrorsClear_();
\r
251 /* USER CODE BEGIN (8) */
\r
252 /* USER CODE END */
\r
254 /* Enable response to ECC errors indicated by CPU for accesses to flash */
\r
255 flashWREG->FEDACCTRL1 = 0x000A060A;
\r
257 /* Enable CPU Event Export */
\r
258 /* This allows the CPU to signal any single-bit or double-bit errors detected
\r
259 * by its ECC logic for accesses to program flash or data RAM.
\r
261 _coreEnableEventBusExport_();
\r
263 /* Enable CPU ECC checking for ATCM (flash accesses) */
\r
264 _coreEnableFlashEcc_();
\r
266 /* USER CODE BEGIN (9) */
\r
267 /* USER CODE END */
\r
269 /* Reset handler: the following instructions read from the system exception status register
\r
270 * to identify the cause of the CPU reset.
\r
273 /* check for power-on reset condition */
\r
274 if ((SYS_EXCEPTION & POWERON_RESET) != 0)
\r
276 /* USER CODE BEGIN (10) */
\r
277 /* USER CODE END */
\r
279 /* clear all reset status flags */
\r
280 SYS_EXCEPTION = 0xFFFF;
\r
282 /* USER CODE BEGIN (11) */
\r
283 /* USER CODE END */
\r
285 /* continue with normal start-up sequence */
\r
287 else if ((SYS_EXCEPTION & OSC_FAILURE_RESET) != 0)
\r
289 /* Reset caused due to oscillator failure.
\r
290 Add user code here to handle oscillator failure */
\r
292 /* USER CODE BEGIN (12) */
\r
293 /* USER CODE END */
\r
295 else if ((SYS_EXCEPTION & WATCHDOG_RESET) !=0 )
\r
297 /* Reset caused due
\r
298 * 1) windowed watchdog violation - Add user code here to handle watchdog violation.
\r
299 * 2) ICEPICK Reset - After loading code via CCS / System Reset through CCS
\r
301 /* Check the WatchDog Status register */
\r
302 if(WATCHDOG_STATUS != 0U)
\r
304 /* Add user code here to handle watchdog violation. */
\r
305 /* USER CODE BEGIN (13) */
\r
306 /* USER CODE END */
\r
308 /* Clear the Watchdog reset flag in Exception Status register */
\r
309 SYS_EXCEPTION = WATCHDOG_RESET;
\r
311 /* USER CODE BEGIN (14) */
\r
312 /* USER CODE END */
\r
316 /* Clear the ICEPICK reset flag in Exception Status register */
\r
317 SYS_EXCEPTION = ICEPICK_RESET;
\r
318 /* USER CODE BEGIN (15) */
\r
319 /* USER CODE END */
\r
322 else if ((SYS_EXCEPTION & CPU_RESET) !=0 )
\r
324 /* Reset caused due to CPU reset.
\r
325 CPU reset can be caused by CPU self-test completion, or
\r
326 by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
\r
328 /* USER CODE BEGIN (16) */
\r
329 /* USER CODE END */
\r
331 /* clear all reset status flags */
\r
332 SYS_EXCEPTION = CPU_RESET;
\r
334 /* USER CODE BEGIN (17) */
\r
335 /* USER CODE END */
\r
338 else if ((SYS_EXCEPTION & SW_RESET) != 0)
\r
340 /* Reset caused due to software reset.
\r
341 Add user code to handle software reset. */
\r
343 /* USER CODE BEGIN (18) */
\r
344 /* USER CODE END */
\r
348 /* Reset caused by nRST being driven low externally.
\r
349 Add user code to handle external reset. */
\r
351 /* USER CODE BEGIN (19) */
\r
352 /* USER CODE END */
\r
355 /* Check if there were ESM group3 errors during power-up.
\r
356 * These could occur during eFuse auto-load or during reads from flash OTP
\r
357 * during power-up. Device operation is not reliable and not recommended
\r
359 * An ESM group3 error only drives the nERROR pin low. An external circuit
\r
360 * that monitors the nERROR pin must take the appropriate action to ensure that
\r
361 * the system is placed in a safe state, as determined by the application.
\r
363 if (esmREG->ESTATUS1[2])
\r
365 /* USER CODE BEGIN (20) */
\r
366 /* USER CODE END */
\r
370 /* USER CODE BEGIN (21) */
\r
371 /* USER CODE END */
\r
373 /* Initialize System - Clock, Flash settings with Efuse self check */
\r
377 /* USER CODE BEGIN (24) */
\r
378 /* USER CODE END */
\r
380 /* Run a diagnostic check on the memory self-test controller.
\r
381 * This function chooses a RAM test algorithm and runs it on an on-chip ROM.
\r
382 * The memory self-test is expected to fail. The function ensures that the PBIST controller
\r
383 * is capable of detecting and indicating a memory self-test failure.
\r
387 /* USER CODE BEGIN (26) */
\r
388 /* USER CODE END */
\r
391 /* Run PBIST on CPU RAM.
\r
392 * The PBIST controller needs to be configured separately for single-port and dual-port SRAMs.
\r
393 * The CPU RAM is a single-port memory. The actual "RAM Group" for all on-chip SRAMs is defined in the
\r
394 * device datasheet.
\r
396 pbistRun(0x08300020, /* ESRAM Single Port PBIST */
\r
397 PBIST_March13N_SP);
\r
399 /* USER CODE BEGIN (27) */
\r
400 /* USER CODE END */
\r
402 /* Wait for PBIST for CPU RAM to be completed */
\r
403 while(!pbistIsTestCompleted());
\r
405 /* USER CODE BEGIN (28) */
\r
406 /* USER CODE END */
\r
408 /* Check if CPU RAM passed the self-test */
\r
409 if( pbistIsTestPassed() != TRUE)
\r
411 /* CPU RAM failed the self-test.
\r
412 * Need custom handler to check the memory failure
\r
413 * and to take the appropriate next step.
\r
415 if(pbistPortTestStatus(PBIST_PORT0) != TRUE)
\r
417 memoryPort0TestFailNotification(pbistREG->RGS, pbistREG->RDS, pbistREG->FSRA0, pbistREG->FSRDL0);
\r
419 else if(pbistPortTestStatus(PBIST_PORT1) != TRUE)
\r
421 memoryPort1TestFailNotification(pbistREG->RGS, pbistREG->RDS, pbistREG->FSRA1, pbistREG->FSRDL1);
\r
429 /* USER CODE BEGIN (29) */
\r
430 /* USER CODE END */
\r
432 /* Disable PBIST clocks and disable memory self-test mode */
\r
435 /* USER CODE BEGIN (30) */
\r
436 /* USER CODE END */
\r
438 /* Initialize CPU RAM.
\r
439 * This function uses the system module's hardware for auto-initialization of memories and their
\r
440 * associated protection schemes. The CPU RAM is initialized by setting bit 0 of the MSIENA register.
\r
441 * Hence the value 0x1 passed to the function.
\r
442 * This function will initialize the entire CPU RAM and the corresponding ECC locations.
\r
446 /* USER CODE BEGIN (31) */
\r
447 /* USER CODE END */
\r
449 /* Enable ECC checking for TCRAM accesses.
\r
450 * This function enables the CPU's ECC logic for accesses to B0TCM and B1TCM.
\r
452 _coreEnableRamEcc_();
\r
454 /* USER CODE BEGIN (32) */
\r
455 /* USER CODE END */
\r
457 /* Start PBIST on all dual-port memories */
\r
458 pbistRun( 0x00000000 /* EMAC Dual Port PBIST */
\r
459 | 0x00000000 /* USB Dual Port PBIST for RMx / Reserved for TMS570x */
\r
460 | 0x00000800 /* DMA Dual Port PBIST */
\r
461 | 0x00000200 /* VIM Dual Port PBIST */
\r
462 | 0x00000040 /* MIBSPI1 Dual Port PBIST */
\r
463 | 0x00000080 /* MIBSPI3 Dual Port PBIST */
\r
464 | 0x00000100 /* MIBSPI5 Dual Port PBIST */
\r
465 | 0x00000004 /* CAN1 Dual Port PBIST */
\r
466 | 0x00000008 /* CAN2 Dual Port PBIST */
\r
467 | 0x00000010 /* CAN3 Dual Port PBIST */
\r
468 | 0x00000400 /* ADC1 Dual Port PBIST */
\r
469 | 0x00020000 /* ADC2 Dual Port PBIST */
\r
470 | 0x00001000 /* HET1 Dual Port PBIST */
\r
471 | 0x00040000 /* HET2 Dual Port PBIST */
\r
472 | 0x00002000 /* HTU1 Dual Port PBIST */
\r
473 | 0x00080000 /* HTU2 Dual Port PBIST */
\r
474 | 0x00004000 /* RTP Dual Port PBIST */
\r
475 | 0x00000000 /* FTU Dual Port PBIST for TMS570x / Reserved for RMx */
\r
476 | 0x00008000 /* FRAY Dual Port PBIST for TMS570x / Reserved for RMx */
\r
477 , PBIST_March13N_DP);
\r
479 /* USER CODE BEGIN (33) */
\r
480 /* USER CODE END */
\r
483 /* Test the CPU ECC mechanism for RAM accesses.
\r
484 * The checkBxRAMECC functions cause deliberate single-bit and double-bit errors in TCRAM accesses
\r
485 * by corrupting 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit error
\r
486 * in the ECC causes a data abort exception. The data abort handler is written to look for
\r
487 * deliberately caused exception and to return the code execution to the instruction
\r
488 * following the one that caused the abort.
\r
491 tcram1REG->RAMCTRL &= ~(0x00000100); /* disable writes to ECC RAM */
\r
492 tcram2REG->RAMCTRL &= ~(0x00000100);
\r
495 tcram1REG->RAMCTRL &= ~(0x00000100); /* disable writes to ECC RAM */
\r
496 tcram2REG->RAMCTRL &= ~(0x00000100);
\r
498 /* USER CODE BEGIN (34) */
\r
499 /* USER CODE END */
\r
502 /* Test the CPU ECC mechanism for Flash accesses.
\r
503 * The checkFlashECC function uses the flash interface module's diagnostic mode 7
\r
504 * to create single-bit and double-bit errors in CPU accesses to the flash. A double-bit
\r
505 * error on reading from flash causes a data abort exception.
\r
506 * The data abort handler is written to look for deliberately caused exception and
\r
507 * to return the code execution to the instruction following the one that was aborted.
\r
511 flashWREG->FDIAGCTRL = 0x000A0007; /* disable flash diagnostic mode */
\r
513 /* USER CODE BEGIN (35) */
\r
514 /* USER CODE END */
\r
516 /* USER CODE BEGIN (36) */
\r
517 /* USER CODE END */
\r
519 /* Wait for PBIST for CPU RAM to be completed */
\r
520 while(!pbistIsTestCompleted());
\r
522 /* USER CODE BEGIN (37) */
\r
523 /* USER CODE END */
\r
525 /* Check if CPU RAM passed the self-test */
\r
526 if( pbistIsTestPassed() != TRUE)
\r
529 /* USER CODE BEGIN (38) */
\r
530 /* USER CODE END */
\r
532 /* CPU RAM failed the self-test.
\r
533 * Need custom handler to check the memory failure
\r
534 * and to take the appropriate next step.
\r
536 if(pbistPortTestStatus(PBIST_PORT0) != TRUE)
\r
538 memoryPort0TestFailNotification(pbistREG->RGS, pbistREG->RDS, pbistREG->FSRA0, pbistREG->FSRDL0);
\r
540 else if(pbistPortTestStatus(PBIST_PORT1) != TRUE)
\r
542 memoryPort1TestFailNotification(pbistREG->RGS, pbistREG->RDS, pbistREG->FSRA1, pbistREG->FSRDL1);
\r
550 /* USER CODE BEGIN (39) */
\r
551 /* USER CODE END */
\r
553 /* Disable PBIST clocks and disable memory self-test mode */
\r
557 /* USER CODE BEGIN (45) */
\r
558 /* USER CODE END */
\r
560 /* Release the MibSPI1 modules from local reset.
\r
561 * This will cause the MibSPI1 RAMs to get initialized along with the parity memory.
\r
563 mibspiREG1->GCR0 = 0x1;
\r
565 /* Release the MibSPI3 modules from local reset.
\r
566 * This will cause the MibSPI3 RAMs to get initialized along with the parity memory.
\r
568 mibspiREG3->GCR0 = 0x1;
\r
570 /* Release the MibSPI5 modules from local reset.
\r
571 * This will cause the MibSPI5 RAMs to get initialized along with the parity memory.
\r
573 mibspiREG5->GCR0 = 0x1;
\r
575 /* USER CODE BEGIN (46) */
\r
576 /* USER CODE END */
\r
578 /* Initialize all on-chip SRAMs except for MibSPIx RAMs
\r
579 * The MibSPIx modules have their own auto-initialization mechanism which is triggered
\r
580 * as soon as the modules are brought out of local reset.
\r
582 /* The system module auto-init will hang on the MibSPI RAM if the module is still in local reset.
\r
584 _memoryInit_( 1 << 1 /* DMA Memory Init */
\r
585 | 1 << 2 /* VIM Memory Init */
\r
586 | 1 << 5 /* CAN1 Memory Init */
\r
587 | 1 << 6 /* CAN2 Memory Init */
\r
588 | 1 << 10 /* CAN3 Memory Init */
\r
589 | 1 << 8 /* ADC1 Memory Init */
\r
590 | 1 << 14 /* ADC2 Memory Init */
\r
591 | 1 << 3 /* HET1 Memory Init */
\r
592 | 1 << 4 /* HTU1 Memory Init */
\r
593 | 1 << 15 /* HET2 Memory Init */
\r
594 | 1 << 16 /* HTU2 Memory Init */
\r
595 | 0 << 13); /* Reserved for RMx Family / FTU Memory Init for TMS570x Family */
\r
597 /* Test the parity protection mechanism for peripheral RAMs
\r
598 * The following memories have parity protection that needs to be checked:
\r
599 * VIM, DMA, ADC1, ADC2, NHET1, NHET2, HTU1, HTU2, FlexRay, FTU,
\r
600 * MibSPI1, MibSPI3, MibSPI5, DCAN1, DCAN2, DCAN3 based on user selection
\r
603 /* USER CODE BEGIN (47) */
\r
604 /* USER CODE END */
\r
608 /* USER CODE BEGIN (48) */
\r
609 /* USER CODE END */
\r
613 /* USER CODE BEGIN (49) */
\r
614 /* USER CODE END */
\r
618 /* USER CODE BEGIN (50) */
\r
619 /* USER CODE END */
\r
623 /* USER CODE BEGIN (51) */
\r
624 /* USER CODE END */
\r
628 /* USER CODE BEGIN (52) */
\r
629 /* USER CODE END */
\r
633 /* USER CODE BEGIN (53) */
\r
634 /* USER CODE END */
\r
638 /* USER CODE BEGIN (54) */
\r
639 /* USER CODE END */
\r
643 /* USER CODE BEGIN (55) */
\r
644 /* USER CODE END */
\r
648 /* USER CODE BEGIN (56) */
\r
649 /* USER CODE END */
\r
653 /* USER CODE BEGIN (57) */
\r
654 /* USER CODE END */
\r
659 /* USER CODE BEGIN (58) */
\r
660 /* USER CODE END */
\r
662 while (mibspiREG1->BUFINIT); /* wait for MibSPI1 RAM to complete initialization */
\r
663 while (mibspiREG3->BUFINIT); /* wait for MibSPI3 RAM to complete initialization */
\r
664 while (mibspiREG5->BUFINIT); /* wait for MibSPI5 RAM to complete initialization */
\r
666 /* USER CODE BEGIN (59) */
\r
667 /* USER CODE END */
\r
669 mibspi1ParityCheck();
\r
671 /* USER CODE BEGIN (60) */
\r
672 /* USER CODE END */
\r
674 mibspi3ParityCheck();
\r
676 /* USER CODE BEGIN (61) */
\r
677 /* USER CODE END */
\r
679 mibspi5ParityCheck();
\r
682 /* USER CODE BEGIN (62) */
\r
683 /* USER CODE END */
\r
686 /* USER CODE BEGIN (63) */
\r
687 /* USER CODE END */
\r
690 /* Initialize VIM table */
\r
694 for (i = 0; i < (VIM_CHANNELS + 1); i++)
\r
696 vimRAM->ISR[i] = s_vim_init[i];
\r
700 /* set IRQ/FIQ priorities */
\r
701 vimREG->FIRQPR0 = SYS_FIQ
\r
732 | (SYS_IRQ << 31U);
\r
734 vimREG->FIRQPR1 = SYS_IRQ
\r
765 | (SYS_IRQ << 31U);
\r
768 vimREG->FIRQPR2 = SYS_IRQ
\r
781 | (SYS_FIQ << 13U) // EMAC
\r
783 | (SYS_FIQ << 15U) // EMAC
\r
799 | (SYS_IRQ << 31U);
\r
801 vimREG->FIRQPR3 = SYS_IRQ
\r
832 | (SYS_IRQ << 31U);
\r
835 /* enable interrupts */
\r
836 vimREG->REQMASKSET0 = 1U
\r
869 vimREG->REQMASKSET1 = 0U
\r
902 vimREG->REQMASKSET2 = 1U
\r
915 | (1U << 13U) // EMACCore0TxIsr
\r
917 | (1U << 15U) // EMACCore0RxIsr
\r
935 vimREG->REQMASKSET3 = 0U
\r
968 /* USER CODE BEGIN (64) */
\r
969 /* USER CODE END */
\r
971 /* Configure system response to error conditions signaled to the ESM group1 */
\r
972 /* This function can be configured from the ESM tab of HALCoGen */
\r
975 /* initalise copy table */
\r
976 if ((uint32_t *)&__binit__ != (uint32_t *)0xFFFFFFFFU)
\r
978 extern void copy_in(void *binit);
\r
979 copy_in((void *)&__binit__);
\r
982 /* initalise the C global variables */
\r
983 if (&__TI_Handler_Table_Base < &__TI_Handler_Table_Limit)
\r
985 uint8_t **tablePtr = (uint8_t **)&__TI_CINIT_Base;
\r
986 uint8_t **tableLimit = (uint8_t **)&__TI_CINIT_Limit;
\r
988 while (tablePtr < tableLimit)
\r
990 uint8_t *loadAdr = *tablePtr++;
\r
991 uint8_t *runAdr = *tablePtr++;
\r
992 uint8_t idx = *loadAdr++;
\r
993 handler_fptr handler = (handler_fptr)(&__TI_Handler_Table_Base)[idx];
\r
995 (*handler)((const uint8_t *)loadAdr, runAdr);
\r
999 /* initalise contructors */
\r
1000 if (__TI_PINIT_Base < __TI_PINIT_Limit)
\r
1002 void (**p0)() = (void *)__TI_PINIT_Base;
\r
1004 while ((uint32_t)p0 < __TI_PINIT_Limit)
\r
1006 void (*p)() = *p0++;
\r
1011 /* USER CODE BEGIN (65) */
\r
1012 /* USER CODE END */
\r
1014 /* call the application */
\r
1017 /* USER CODE BEGIN (66) */
\r
1018 /* USER CODE END */
\r
1021 /* USER CODE BEGIN (67) */
\r
1022 /* USER CODE END */
\r
1025 /* USER CODE BEGIN (68) */
\r
1026 /* USER CODE END */
\r