startup.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. Initialisation functions for exception handlers, PLL and MAM
  3. Partially copied from Jim Lynch's tutorial
  4. */
  5. /**********************************************************
  6. Header files
  7. **********************************************************/
  8. #include "startup.h"
  9. #define MAMCR *(volatile unsigned int *)0xE01FC000
  10. #define MAMTIM *(volatile unsigned int *)0xE01FC004
  11. #define PLLCON *(volatile unsigned int *)0xE01FC080
  12. #define PLLCFG *(volatile unsigned int *)0xE01FC084
  13. #define PLLSTAT *(volatile unsigned int *)0xE01FC088
  14. #define PLLFEED *(volatile unsigned int *)0xE01FC08C
  15. #define VPBDIV *(volatile unsigned int *)0xE01FC100
  16. void IRQ_Routine(void) __attribute__ ((interrupt("IRQ")));
  17. void FIQ_Routine(void) __attribute__ ((interrupt("FIQ")));
  18. void SWI_Routine(void) __attribute__ ((interrupt("SWI")));
  19. void UNDEF_Routine(void) __attribute__ ((interrupt("UNDEF")));
  20. /* Stubs for various interrupts (may be replaced later) */
  21. /* ---------------------------------------------------- */
  22. void IRQ_Routine(void)
  23. {
  24. while (1);
  25. }
  26. void FIQ_Routine(void)
  27. {
  28. while (1);
  29. }
  30. void SWI_Routine(void)
  31. {
  32. while (1);
  33. }
  34. void UNDEF_Routine(void)
  35. {
  36. while (1);
  37. }
  38. /**********************************************************
  39. Initialize
  40. **********************************************************/
  41. #define PLOCK 0x400
  42. static void feed(void)
  43. {
  44. PLLFEED = 0xAA;
  45. PLLFEED = 0x55;
  46. } void Initialize(void)
  47. {
  48. // Setting the Phased Lock Loop (PLL)
  49. // ----------------------------------
  50. //
  51. // Olimex LPC-P2148 has a 12.0000 mhz crystal
  52. //
  53. // We'd like the LPC2148 to run at 60 mhz (has to be an even multiple of crystal)
  54. //
  55. // According to the Philips LPC2148 manual: M = cclk / Fosc where: M = PLL multiplier (bits 0-4 of PLLCFG)
  56. // cclk = 60000000 hz
  57. // Fosc = 12000000 hz
  58. //
  59. // Solving: M = 60000000 / 12000000 = 5
  60. //
  61. // Note: M - 1 must be entered into bits 0-4 of PLLCFG (assign 4 to these bits)
  62. //
  63. //
  64. // The Current Controlled Oscilator (CCO) must operate in the range 156 mhz to 320 mhz
  65. //
  66. // According to the Philips LPC2148 manual: Fcco = cclk * 2 * P where: Fcco = CCO frequency
  67. // cclk = 60000000 hz
  68. // P = PLL divisor (bits 5-6 of PLLCFG)
  69. //
  70. // Solving: Fcco = 60000000 * 2 * P
  71. // P = 2 (trial value)
  72. // Fcco = 60000000 * 2 * 2
  73. // Fcc0 = 240000000 hz (good choice for P since it's within the 156 mhz to 320 mhz range)
  74. //
  75. // From Table 22 (page 34) of Philips LPC2148 manual P = 2, PLLCFG bits 5-6 = 1 (assign 1 to these bits)
  76. //
  77. // Finally: PLLCFG = 0 01 00100 = 0x24
  78. //
  79. // Final note: to load PLLCFG register, we must use the 0xAA followed 0x55 write sequence to the PLLFEED register
  80. // this is done in the short function feed() below
  81. //
  82. // Setting Multiplier and Divider values
  83. PLLCFG = 0x24;
  84. feed();
  85. // Enabling the PLL */
  86. PLLCON = 0x1;
  87. feed();
  88. // Wait for the PLL to lock to set frequency
  89. while (!(PLLSTAT & PLOCK));
  90. // Connect the PLL as the clock source
  91. PLLCON = 0x3;
  92. feed();
  93. // Enabling MAM and setting number of clocks used for Flash memory fetch
  94. MAMTIM = 0x3;
  95. MAMCR = 0x2;
  96. // Setting peripheral Clock (pclk) to System Clock (cclk)
  97. VPBDIV = 0x1;
  98. }