clock.c 2.0 KB

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