clock.c 2.1 KB

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