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

4.104.115
Last change on this file since 7ae2775 was 7ae2775, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 07/17/09 at 13:53:04

ARM bsp maintenance

  • Property mode set to 100644
File size: 3.9 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#ifndef LPC24XX_OSCILLATOR_MAIN
32  #error "unknown main oscillator frequency"
33#endif
34
35#ifndef LPC24XX_OSCILLATOR_RTC
36  #error "unknown RTC oscillator frequency"
37#endif
38
39/**
40 * @brief Delay for @a us micro seconds.
41 *
42 * @note Uses Timer 1.
43 */
44void lpc24xx_micro_seconds_delay( unsigned us)
45{
46  /* Stop and reset timer */
47  T1TCR = 0x02;
48
49  /* Set prescaler to zero */
50  T1PR = 0x00;
51 
52  /* Set match value */
53  T1MR0 = (uint32_t) ((uint64_t) 4000000 * (uint64_t) us / (uint64_t) lpc24xx_cclk()) + 1;
54
55  /* Reset all interrupt flags */
56  T1IR = 0xff;
57
58  /* Stop timer on match */
59  T1MCR = 0x04;
60
61  /* Start timer */
62  T1TCR = 0x01;
63 
64  /* Wait until delay time has elapsed */
65  while ((T1TCR & 0x01) != 0) {
66    /* Wait */
67  }
68}
69
70/**
71 * @brief Returns the PLL output clock frequency in [Hz].
72 *
73 * Returns zero in case of an unexpected PLL input frequency.
74 */
75unsigned lpc24xx_pllclk( void)
76{
77  unsigned clksrc = GET_CLKSRCSEL_CLKSRC( CLKSRCSEL);
78  unsigned pllinclk = 0;
79  unsigned pllclk = 0;
80
81  /* Get PLL input frequency */
82  switch (clksrc) {
83    case 0:
84      pllinclk = LPC24XX_OSCILLATOR_INTERNAL;
85      break;
86    case 1:
87      pllinclk = LPC24XX_OSCILLATOR_MAIN;
88      break;
89    case 2:
90      pllinclk = LPC24XX_OSCILLATOR_RTC;
91      break;
92    default:
93      return 0;
94  }
95
96  /* Get PLL output frequency */
97  if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
98    uint32_t pllcfg = PLLCFG;
99    unsigned n = GET_PLLCFG_NSEL( pllcfg) + 1;
100    unsigned m = GET_PLLCFG_MSEL( pllcfg) + 1;
101
102    pllclk = (pllinclk / n) * 2 * m;
103  } else {
104    pllclk = pllinclk;
105  }
106
107  return pllclk;
108}
109
110/**
111 * @brief Returns the CPU clock frequency in [Hz].
112 *
113 * Returns zero in case of an unexpected PLL input frequency.
114 */
115unsigned lpc24xx_cclk( void)
116{
117  /* Get PLL output frequency */
118  unsigned pllclk = lpc24xx_pllclk();
119
120  /* Get CPU frequency */
121  unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL( CCLKCFG) + 1);
122
123  return cclk;
124}
125
126static void lpc24xx_pll_config( uint32_t val)
127{
128  PLLCON = val;
129  PLLFEED = 0xaa;
130  PLLFEED = 0x55;
131}
132
133/**
134 * @brief Sets the Phase Locked Loop (PLL).
135 *
136 * @param clksrc Selects the clock source for the PLL.
137 *
138 * @param nsel Selects PLL pre-divider value (sometimes named psel).
139 *
140 * @param msel Selects PLL multiplier value.
141 *
142 * @param cclksel Selects the divide value for creating the CPU clock (CCLK)
143 * from the PLL output.
144 *
145 * @note All parameter values are the actual register field values.
146 */
147void lpc24xx_set_pll( unsigned clksrc, unsigned nsel, unsigned msel, unsigned cclksel)
148{
149  bool pll_enabled = IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLE);
150
151  /* Disconnect PLL if necessary */
152  if (IS_FLAG_SET( PLLSTAT, PLLSTAT_PLLC)) {
153    if (pll_enabled) {
154      lpc24xx_pll_config( PLLCON_PLLE);
155    } else {
156      lpc24xx_pll_config( 0);
157    }
158  }
159
160  /* Set CPU clock divider to a reasonable save value */
161  CCLKCFG = 0;
162
163  /* Disable PLL if necessary */
164  if (pll_enabled) {
165    lpc24xx_pll_config( 0);
166  }
167
168  /* Select clock source */
169  CLKSRCSEL = SET_CLKSRCSEL_CLKSRC( 0, clksrc);
170
171  /* Set PLL Configuration Register */
172  PLLCFG = SET_PLLCFG_NSEL( 0, nsel) | SET_PLLCFG_MSEL( 0, msel);
173
174  /* Enable PLL */
175  lpc24xx_pll_config( PLLCON_PLLE);
176
177  /* Wait for lock */
178  while (IS_FLAG_CLEARED( PLLSTAT, PLLSTAT_PLOCK)) {
179    /* Wait */
180  }
181
182  /* Set CPU clock divider and ensure that we have an odd value */
183  CCLKCFG = SET_CCLKCFG_CCLKSEL( 0, cclksel | 1);
184
185  /* Connect PLL */
186  lpc24xx_pll_config( PLLCON_PLLE | PLLCON_PLLC);
187}
Note: See TracBrowser for help on using the repository browser.