source: rtems/c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c @ 5aeed17

4.104.115
Last change on this file since 5aeed17 was 5aeed17, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Sep 22, 2008 at 11:30:09 AM

lpc24xx: new BSP

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc24xx
5 *
6 * @brief System clocks.
7 */
8
9/*
10 * Copyright (c) 2008
11 * Embedded Brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * rtems@embedded-brains.de
16 *
17 * The license and distribution terms for this file may be found in the file
18 * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
19 */
20
21#include <libcpu/utility.h>
22
23#include <bsp.h>
24#include <bsp/lpc24xx.h>
25#include <bsp/system-clocks.h>
26
27/**
28 * @brief Internal RC oscillator frequency in [Hz].
29 */
30#define LPC24XX_OSCILLATOR_INTERNAL 4000000U
31
32#ifdef LPC2478
33  /**
34   * @brief Main oscillator frequency in [Hz].
35   */
36  #define LPC24XX_OSCILLATOR_MAIN 12000000U
37
38  /**
39   * @brief RTC oscillator frequency in [Hz].
40   */
41  #define LPC24XX_OSCILLATOR_RTC 32768
42#else
43  #error Unknown oscillator frequencies
44#endif
45
46/**
47 * @brief Returns the CPU clock frequency in [Hz].
48 */
49unsigned lpc24xx_cclk( void)
50{
51  unsigned clksrc = GET_CLKSRCSEL_CLKSRC( CLKSRCSEL);
52  unsigned pllinclk = 0;
53  unsigned pllclk = 0;
54  unsigned cclk = 0;
55
56  /* Get PLL input frequency */
57  switch (clksrc) {
58    case 0:
59      pllinclk = LPC24XX_OSCILLATOR_INTERNAL;
60      break;
61    case 1:
62      pllinclk = LPC24XX_OSCILLATOR_MAIN;
63      break;
64    case 2:
65      pllinclk = LPC24XX_OSCILLATOR_RTC;
66      break;
67    default:
68      while (1) {
69        /* Spin forever */
70      }
71      return 0;
72  }
73
74  /* Get PLL output frequency */
75  if (REG_FLAG_IS_SET( PLLSTAT, PLLSTAT_PLLC)) {
76    uint32_t pllcfg = PLLCFG;
77    unsigned n = GET_PLLCFG_NSEL( pllcfg) + 1;
78    unsigned m = GET_PLLCFG_MSEL( pllcfg) + 1;
79
80    pllclk = (pllinclk / n) * 2 * m;
81  } else {
82    pllclk = pllinclk;
83  }
84
85  /* Get CPU clock frequency */
86  cclk = pllclk / (GET_CCLKCFG_CCLKSEL( CCLKCFG) + 1);
87
88  return cclk;
89}
90
91static void lpc24xx_pll_config( uint32_t val)
92{
93  PLLCON = val;
94  PLLFEED = 0xaa;
95  PLLFEED = 0x55;
96}
97
98/**
99 * @brief Sets the Phase Locked Loop (PLL).
100 *
101 * @param clksrc Selects the clock source for the PLL.
102 *
103 * @param nsel Selects PLL pre-divider value (sometimes named psel).
104 *
105 * @param msel Selects PLL multiplier value.
106 *
107 * @param cclksel Selects the divide value for creating the CPU clock (CCLK)
108 * from the PLL output.
109 *
110 * @note All parameter values are the actual register field values.
111 */
112void lpc24xx_set_pll( unsigned clksrc, unsigned nsel, unsigned msel, unsigned cclksel)
113{
114  bool pll_enabled = REG_FLAG_IS_SET( PLLSTAT, PLLSTAT_PLLE);
115
116  /* Disconnect PLL if necessary */
117  if (REG_FLAG_IS_SET( PLLSTAT, PLLSTAT_PLLC)) {
118    if (pll_enabled) {
119      lpc24xx_pll_config( PLLCON_PLLE);
120    } else {
121      lpc24xx_pll_config( 0);
122    }
123  }
124
125  /* Set CPU clock divider to a reasonable save value */
126  CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, 1);
127
128  /* Disable PLL if necessary */
129  if (pll_enabled) {
130    lpc24xx_pll_config( 0);
131  }
132
133  /* Select clock source */
134  CLKSRCSEL = SET_CLKSRCSEL_CLKSRC( 0, clksrc);
135
136  /* Set PLL Configuration Register */
137  PLLCFG = SET_PLLCFG_NSEL( 0, nsel) | SET_PLLCFG_MSEL( 0, msel);
138
139  /* Enable PLL */
140  lpc24xx_pll_config( PLLCON_PLLE);
141
142  /* Wait for lock */
143  while (REG_FLAG_IS_CLEARED( PLLSTAT, PLLSTAT_PLOCK)) {
144    /* Wait */
145  }
146
147  /* Set CPU clock divider and ensure that we have an odd value */
148  CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, cclksel | 1);
149
150  /* Connect PLL */
151  lpc24xx_pll_config( PLLCON_PLLE | PLLCON_PLLC);
152}
Note: See TracBrowser for help on using the repository browser.