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

4.104.115
Last change on this file since 3129783 was 3129783, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/11/08 at 10:19:47

Receive LPC24XX_OSCILLATOR_RTC, LPC24XX_OSCILLATOR_MAIN through bspopts.h.

  • Property mode set to 100644
File size: 3.2 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 <bsp.h>
22#include <bsp/utility.h>
23#include <bsp/lpc24xx.h>
24#include <bsp/system-clocks.h>
25
26/**
27 * @brief Internal RC oscillator frequency in [Hz].
28 */
29#define LPC24XX_OSCILLATOR_INTERNAL 4000000U
30
31#if !defined(LPC24XX_OSCILLATOR_MAIN)
32#error unknown main oscillator frequency
33#endif
34
35#if !defined(LPC24XX_OSCILLATOR_RTC)
36#error unknown rtc oscillator frequency
37#endif
38
39/**
40 * @brief Returns the CPU clock frequency in [Hz].
41 */
42unsigned lpc24xx_cclk( void)
43{
44  unsigned clksrc = GET_CLKSRCSEL_CLKSRC( CLKSRCSEL);
45  unsigned pllinclk = 0;
46  unsigned pllclk = 0;
47  unsigned cclk = 0;
48
49  /* Get PLL input frequency */
50  switch (clksrc) {
51    case 0:
52      pllinclk = LPC24XX_OSCILLATOR_INTERNAL;
53      break;
54    case 1:
55      pllinclk = LPC24XX_OSCILLATOR_MAIN;
56      break;
57    case 2:
58      pllinclk = LPC24XX_OSCILLATOR_RTC;
59      break;
60    default:
61      while (1) {
62        /* Spin forever */
63      }
64      return 0;
65  }
66
67  /* Get PLL output frequency */
68  if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
69    uint32_t pllcfg = PLLCFG;
70    unsigned n = GET_PLLCFG_NSEL( pllcfg) + 1;
71    unsigned m = GET_PLLCFG_MSEL( pllcfg) + 1;
72
73    pllclk = (pllinclk / n) * 2 * m;
74  } else {
75    pllclk = pllinclk;
76  }
77
78  /* Get CPU clock frequency */
79  cclk = pllclk / (GET_CCLKCFG_CCLKSEL( CCLKCFG) + 1);
80
81  return cclk;
82}
83
84static void lpc24xx_pll_config( uint32_t val)
85{
86  PLLCON = val;
87  PLLFEED = 0xaa;
88  PLLFEED = 0x55;
89}
90
91/**
92 * @brief Sets the Phase Locked Loop (PLL).
93 *
94 * @param clksrc Selects the clock source for the PLL.
95 *
96 * @param nsel Selects PLL pre-divider value (sometimes named psel).
97 *
98 * @param msel Selects PLL multiplier value.
99 *
100 * @param cclksel Selects the divide value for creating the CPU clock (CCLK)
101 * from the PLL output.
102 *
103 * @note All parameter values are the actual register field values.
104 */
105void lpc24xx_set_pll( unsigned clksrc, unsigned nsel, unsigned msel, unsigned cclksel)
106{
107  bool pll_enabled = IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLE);
108
109  /* Disconnect PLL if necessary */
110  if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
111    if (pll_enabled) {
112      lpc24xx_pll_config( PLLCON_PLLE);
113    } else {
114      lpc24xx_pll_config( 0);
115    }
116  }
117
118  /* Set CPU clock divider to a reasonable save value */
119  CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, 1);
120
121  /* Disable PLL if necessary */
122  if (pll_enabled) {
123    lpc24xx_pll_config( 0);
124  }
125
126  /* Select clock source */
127  CLKSRCSEL = SET_CLKSRCSEL_CLKSRC( 0, clksrc);
128
129  /* Set PLL Configuration Register */
130  PLLCFG = SET_PLLCFG_NSEL( 0, nsel) | SET_PLLCFG_MSEL( 0, msel);
131
132  /* Enable PLL */
133  lpc24xx_pll_config( PLLCON_PLLE);
134
135  /* Wait for lock */
136  while (IS_FLAG_CLEARED( PLLSTAT, PLLSTAT_PLOCK)) {
137    /* Wait */
138  }
139
140  /* Set CPU clock divider and ensure that we have an odd value */
141  CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, cclksel | 1);
142
143  /* Connect PLL */
144  lpc24xx_pll_config( PLLCON_PLLE | PLLCON_PLLC);
145}
Note: See TracBrowser for help on using the repository browser.