Device.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include "BMS_Master.h"
  2. extern uint32_t __IVPR_VALUE; /* Interrupt Vector Prefix value from link file*/
  3. extern uint32_t IntcIsrVectorTable[];
  4. #define CHIPVERSION F1
  5. void init_Device()
  6. {
  7. //--INIT-----------------------------------------------
  8. // (1) Disable Watchdog --------------------------
  9. disableWatchdog(); /* Disable watchdog */
  10. // -----------------------------------------------
  11. INTC_InstallINTCInterruptHandler(&ISR_Timer_OS,59,10); //irq(PIT0) = 59
  12. INTC_InitINTCInterrupts();
  13. Asm_initIrqVectors();
  14. INTC.PSR[4].R = 2; /* Software interrupt 4 IRQ priority = 2 */
  15. INTC.CPR_PRC0.B.PRI = 1; /* Single Core: Lower INTC's current priority */
  16. /* (2) - Configure modes and activate all clock for all peripherals */
  17. initMODE();
  18. /* (3) - Configure system clock dividers for 120Mhz Fsys */
  19. CGM.Z0_DCR.B.DIV = 0x1; /* Z0 clock divider to divide by 2 */
  20. CGM.FLASH_DCR.B.DIV = 0x1; /* Flash register interface /2 (default) */
  21. ECSM.MUDCR.B.RAM_WS=0x1; /* RAM Wait states to divide by 2 */
  22. /* (4) - Set system clock to 120MHz based on 40Mhz XTAL */
  23. setPLL(); /* Also enables CLKOUT On PA[0] */
  24. initINTC();
  25. }
  26. /* ----------------------------- */
  27. /* Initialize Modes */
  28. /* ----------------------------- */
  29. void initMODE()
  30. {
  31. ME.MER.R = 0x000025FF; /* Enable all modes */
  32. ME.RUNPC[0].R = 0x000000FE; /* Enable all peripherals in all modes */
  33. /* Enable system clock for all peripherals assuming 120MHz system clock */
  34. CGM.SC_DC0.R = 0x83; /* Max 32MHz. Closest is 30MHz, Div+1=4 */
  35. CGM.SC_DC1.R = 0x81; /* Max 64MHz. Closest is 60MHz, Div+1=2 */
  36. CGM.SC_DC2.R = 0x81; /* Max 64MHz. Closest is 60MHz, Div+1=2 */
  37. /* Re-enter DRUN mode to update the clock configuration */
  38. ME.MCTL.R = 0x30005AF0; /* DRUN Mode & Key */
  39. ME.MCTL.R = 0x3000A50F; /* DRUN Mode & Key */
  40. while (ME.IS.B.I_MTC != 1) {} /* Wait Until transition completed */
  41. ME.IS.B.I_MTC = 1; /* Clear flag */
  42. //CAN
  43. ME.RUNPC[1].R = 0x00000018; /* Peri. Cfg. 1 settings: only run in DRUN & RUN0 mode */
  44. ME.PCTL[16].R = 0x01; /* MPC56xxB/P/S FlexCAN0:select ME.RUNPC[1] */
  45. // ME.PCTL[17].R = 0x01; /* MPC56xxB/S FlexCAN1: select ME.RUNPC[1] */
  46. ME.PCTL[68].R = 0x01; /* MPC56xxB/S SIUL: select ME.RUNPC[1] */
  47. ME.PCTL[91].R = 0x01; /* MPC56xxB/S RTC/API: select ME.RUNPC[1] */
  48. ME.PCTL[92].R = 0x01; /* MPC56xxB/S PIT_RTI: select ME.RUNPC[1] */
  49. ME.PCTL[4].R = 0x01; /* MPC56xxB/S DSPI0: select ME.RUNPC[1] */
  50. ME.PCTL[5].R = 0x01; /* MPC56xxB/S DSPI1: select ME.RUNPC[1] */
  51. ME.PCTL[48].R = 0x01; /* MPC56xxB/S LINFLEX0: select ME.RUNPC[1] */
  52. ME.PCTL[49].R = 0x01; /* MPC56xxB/S LINFLEX1: select ME.RUNPC[1] */
  53. }
  54. void init_Mode_and_Clock()
  55. {
  56. //--PLL--
  57. //Nur einstellen, wenn PLL nicht Sysclk
  58. //F_vco = F_xtal * NDIV/(IDIF+1) = 256...512
  59. //F_PLL_outclk = F_vco / 2^(ODIF+1)
  60. CGM.FMPLL_CR.B.IDF= 3; /* Divide by 4 */
  61. CGM.FMPLL_CR.B.ODF= 1; /* Divide by 4 */
  62. CGM.FMPLL_CR.B.NDIV=48; /* Multiply 48 */
  63. /* Switch on external osc in DRUN mode */
  64. ME.DRUN.B.FXOSC0ON=1;
  65. //Set PLL to Soure in DRUN
  66. ME.DRUN.B.SYSCLK=4;
  67. ME.MCTL.R = 0x30005AF0; /* Mode & Key */
  68. ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
  69. while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
  70. /* Error trap - if current mode is not DRUM (eg safe mode), then loop */
  71. while(ME.GS.B.S_CURRENTMODE != 3) {}
  72. /* Wait for external OSC to stabilize */
  73. while(ME.GS.B.S_FXOSC != 1) {}
  74. // wait for PLL to lock
  75. while(CGM.FMPLL_CR.B.S_LOCK==0) {}
  76. /* Enable CLKOUT pin so clock frequency can be verified */
  77. CGM.OC_EN.B.EN=1; /* Enable Output clock */
  78. CGM.OCDS_SC.R =0x23; /* And seclect output as system clock / 4 */
  79. SIU.PCR[0].R = 0x0A04; /* PA0 ALT2 function (Clkout), MAX SRC */
  80. }
  81. /* ----------------------------- */
  82. /* PLL to 120Mhz (40Mhz xtal) */
  83. /* ----------------------------- */
  84. void setPLL()
  85. {
  86. /* Note - in example code below the flow is: */
  87. /* Switch on osc, change mode and wait for osc ON */
  88. /* Configure and enable PLL, change mode and wait for PLL to lock */
  89. /* Set clock source as PLL, change mode and check clock is PLL */
  90. /* */
  91. /* However, do not actually have to do all 3 mode changes. Can */
  92. /* switch on osc, enable PLL and Set PLL as clock source THEN do a */
  93. /* single mode change. The ME module must be smart enough to look */
  94. /* at which bits are set and see if it's a valid combination of */
  95. /* bits. However, if there is an issue, there is no way of seeing */
  96. /* what caused the problem! */
  97. #ifdef EVALBOARD
  98. /* Switch on external osc in DRUN mode */
  99. ME.DRUN.B.FXOSC0ON=1;
  100. #else
  101. //MasterBoard
  102. CGM.FXOSC_CTL.B.OSCBYP=1;
  103. ME.DRUN.B.FXOSC0ON=1;
  104. #endif
  105. /* Re-Enter DRUN mode (mode=0x3) to activate change */
  106. ME.MCTL.R = 0x30005AF0; /* Mode & Key */
  107. ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
  108. while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
  109. /* Error trap - if current mode is not DRUM (eg in safe mode), then loop */
  110. while(ME.GS.B.S_CURRENTMODE != 3) {}
  111. /* Wait for external OSC to stabilize */
  112. while(ME.GS.B.S_FXOSC != 1) {}
  113. /* Select External OSC as the FMPLL Reference Clock Source */
  114. #if CHIPVERSION == F1
  115. CGM.AC0_SC.B.SELCTL = 0x0;
  116. #elif CHIPVERSION == F0
  117. CGM.AC0_SC.B.SELCTL = 0x1;
  118. #else
  119. #error Device.c: Keine gültige Cipversion ausgewählt
  120. #endif
  121. /* Configure PLL for 120MHz with 40MHz xtal */
  122. /* PLL frequency = (40 * NDIV) / (IDF * ODF) */
  123. /* VCO (PLL * ODF) must be between 256 and 512MHz */
  124. /* */
  125. /* For 120Mhz Output: */
  126. /* ODF deliviers are 2, 4, 8, 16. /4 gives VCO of 480 (in range) */
  127. /* With ODF = 2, NDIV = 12xIDF. Chose IDF =5, therefore NDIV = 60 */
  128. CGM.FMPLL_CR.B.IDF=0x4; /* Divide by 5 */
  129. CGM.FMPLL_CR.B.ODF=0x1; /* Divide by 4 */
  130. CGM.FMPLL_CR.B.NDIV=60; /* Divide by 60 */
  131. /* Enable PLL in DRUN mode. */
  132. ME.DRUN.B.FMPLLON = 1;
  133. /* Re-Enter DRUN mode (mode=0x3) to activate change */
  134. ME.MCTL.R = 0x30005AF0; /* Mode & Key */
  135. ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
  136. while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
  137. /* Error trap - if current mode is not DRUM (eg safe mode), then loop */
  138. while(ME.GS.B.S_CURRENTMODE != 3) {}
  139. /* wait for PLL to lock (will not lock until re-enter DRUN mode */
  140. while(CGM.FMPLL_CR.B.S_LOCK==0) {}
  141. /* Finally set system clock to be PLL in DRUN mode */
  142. ME.DRUN.B.SYSCLK=0x4;
  143. /* Re-Enter DRUN mode (mode=0x3) to activate change */
  144. // Application Code
  145. // Getting started with the MPC564xB/C Microcontroller, Rev. 0, 12/2010
  146. // 20 Freescale Semiconductor, Inc.
  147. ME.MCTL.R = 0x30005AF0; /* Mode & Key */
  148. ME.MCTL.R = 0x3000A50F; /* Mode & Key inverted */
  149. while(ME.GS.B.S_MTRANS == 1) {} /* Wait for mode transition complete */
  150. /* Error trap - if current mode is not DRUM (eg safe mode), then loop */
  151. while(ME.GS.B.S_CURRENTMODE != 3) {}
  152. /* Final check - ensure ME_GS reports clock as system PLL (0x4) */
  153. while(ME.GS.B.S_SYSCLK != 4) {} /* fail if stuck here */
  154. /* Enable CLKOUT pin so clock frequency can be verified */
  155. CGM.OC_EN.B.EN=1; /* Enable Output clock */
  156. CGM.OCDS_SC.R =0x23; /* And seclect output as system clock / 4 */
  157. SIU.PCR[0].R = 0x0A04; /* PA0 ALT2 function (Clkout), MAX SRC */
  158. }
  159. void disableWatchdog()
  160. {
  161. SWT.SR.R = 0x0000c520; /* Write keys to clear soft lock bit */
  162. SWT.SR.R = 0x0000d928;
  163. SWT.CR.R = 0x8000010A; /* Clear watchdog enable (WEN) */
  164. }
  165. void initINTC()
  166. {
  167. INTC.MCR.B.HVEN_PRC0 = 1; /* 0 -> SW vector mode */
  168. INTC.MCR.B.VTES_PRC0 = 0; /* Single core: Use default vector table 4B offsets */
  169. INTC.IACKR_PRC0.R = 2; /* MPC555x: INTC ISR table base */
  170. INTC.PSR[59].R = 4; /* PIT 0 interrupt vector with priority 1 */
  171. INTC.PSR[0].R = 3; /* Software interrupt 0 IRQ priority = 2 */
  172. INTC.PSR[1].R = 2; /* Software interrupt 1 IRQ priority = 2 */
  173. INTC.PSR[2].R = 1; /* Software interrupt 2 IRQ priority = 2 */
  174. }
  175. void enableIrq()
  176. {
  177. INTC.CPR_PRC0.B.PRI = 0; /* Single Core: Lower INTC's current priority */
  178. asm(" wrteei 1"); /* Enable external interrupts */
  179. }
  180. void Asm_initIrqVectors( void )
  181. {
  182. asm(" lis r3, __IVPR_VALUE@h"); /* IVPR value is passed from link file */
  183. asm(" ori r3, r3, __IVPR_VALUE@l");
  184. asm(" mtivpr r3");
  185. asm(" li r3, 0x40");
  186. asm(" mtivor4 r3");
  187. }