clock.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* ___DISCLAIMER___ */
  2. /* clock.c: PLL, CCLK, PCLK controls */
  3. #include <arm/NXP/LPC17xx/LPC17xx.h>
  4. #include "clock.h"
  5. #include "bits.h"
  6. #include "uart.h"
  7. void clock_disconnect()
  8. {
  9. disconnectPLL0();
  10. disablePLL0();
  11. }
  12. void clock_init()
  13. {
  14. /* set flash access time to 5 clks (80<f<=100MHz) */
  15. setFlashAccessTime( 5 );
  16. /* setup PLL0 for ~44100*256*8 Hz
  17. Base clock: 12MHz
  18. Multiplier: 429
  19. Pre-Divisor: 19
  20. Divisor: 6
  21. (want: 90316800, get: 90315789.47)
  22. -> DAC freq = 44099.5 Hz
  23. -> FPGA freq = 11289473.7Hz
  24. First, disable and disconnect PLL0.
  25. */
  26. clock_disconnect();
  27. /* PLL is disabled and disconnected. setup PCLK NOW as it cannot be changed
  28. reliably with PLL0 connected.
  29. see:
  30. http://ics.nxp.com/support/documents/microcontrollers/pdf/errata.lpc1754.pdf
  31. */
  32. /* continue with PLL0 setup:
  33. enable the xtal oscillator and wait for it to become stable
  34. set the oscillator as clk source for PLL0
  35. set PLL0 multiplier+predivider
  36. enable PLL0
  37. set CCLK divider
  38. wait for PLL0 to lock
  39. connect PLL0
  40. done
  41. */
  42. enableMainOsc();
  43. setClkSrc( CLKSRC_MAINOSC );
  44. setPLL0MultPrediv( 22, 1 );
  45. enablePLL0();
  46. setCCLKDiv( 6 );
  47. connectPLL0();
  48. }
  49. void setFlashAccessTime( uint8_t clocks )
  50. {
  51. LPC_SC->FLASHCFG = FLASHTIM( clocks );
  52. }
  53. void setPLL0MultPrediv( uint16_t mult, uint8_t prediv )
  54. {
  55. LPC_SC->PLL0CFG = PLL_MULT( mult ) | PLL_PREDIV( prediv );
  56. PLL0feed();
  57. }
  58. void enablePLL0()
  59. {
  60. LPC_SC->PLL0CON |= PLLE0;
  61. PLL0feed();
  62. }
  63. void disablePLL0()
  64. {
  65. LPC_SC->PLL0CON &= ~PLLE0;
  66. PLL0feed();
  67. }
  68. void connectPLL0()
  69. {
  70. while ( !( LPC_SC->PLL0STAT & PLOCK0 ) );
  71. LPC_SC->PLL0CON |= PLLC0;
  72. PLL0feed();
  73. }
  74. void disconnectPLL0()
  75. {
  76. LPC_SC->PLL0CON &= ~PLLC0;
  77. PLL0feed();
  78. }
  79. void setCCLKDiv( uint8_t div )
  80. {
  81. LPC_SC->CCLKCFG = CCLK_DIV( div );
  82. }
  83. void enableMainOsc()
  84. {
  85. LPC_SC->SCS = OSCEN;
  86. while ( !( LPC_SC->SCS & OSCSTAT ) );
  87. }
  88. void disableMainOsc()
  89. {
  90. LPC_SC->SCS = 0;
  91. }
  92. void PLL0feed()
  93. {
  94. LPC_SC->PLL0FEED = 0xaa;
  95. LPC_SC->PLL0FEED = 0x55;
  96. }
  97. void setClkSrc( uint8_t src )
  98. {
  99. LPC_SC->CLKSRCSEL = src;
  100. }