source: rtems/bsps/arm/lpc24xx/start/system-clocks.c @ e945b049

5
Last change on this file since e945b049 was 74df15c, checked in by Sebastian Huber <sebastian.huber@…>, on 04/25/18 at 08:40:40

bsp/lpc24xx: Move source files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc24xx_clocks
5 *
6 * @brief System clocks.
7 */
8
9/*
10 * Copyright (c) 2008-2014 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Obere Lagerstr. 30
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems/counter.h>
24
25#include <bsp.h>
26#include <bsp/lpc24xx.h>
27#include <bsp/system-clocks.h>
28
29/**
30 * @brief Internal RC oscillator frequency in [Hz].
31 */
32#define LPC24XX_OSCILLATOR_INTERNAL 4000000U
33
34#ifndef LPC24XX_OSCILLATOR_MAIN
35  #error "unknown main oscillator frequency"
36#endif
37
38#ifndef LPC24XX_OSCILLATOR_RTC
39  #error "unknown RTC oscillator frequency"
40#endif
41
42void lpc24xx_timer_initialize(void)
43{
44  /* Reset timer */
45  T1TCR = TCR_RST;
46
47  /* Set timer mode */
48  T1CTCR = 0;
49
50  /* Set prescaler to zero */
51  T1PR = 0;
52
53  /* Reset all interrupt flags */
54  T1IR = 0xff;
55
56  /* Do not stop on a match */
57  T1MCR = 0;
58
59  /* No captures */
60  T1CCR = 0;
61
62  /* Start timer */
63  T1TCR = TCR_EN;
64
65  rtems_counter_initialize_converter(LPC24XX_PCLK);
66}
67
68CPU_Counter_ticks _CPU_Counter_read(void)
69{
70  return lpc24xx_timer();
71}
72
73void lpc24xx_micro_seconds_delay(unsigned us)
74{
75  unsigned start = lpc24xx_timer();
76  unsigned delay = us * (LPC24XX_PCLK / 1000000);
77  unsigned elapsed = 0;
78
79  do {
80    elapsed = lpc24xx_timer() - start;
81  } while (elapsed < delay);
82}
83
84#ifdef ARM_MULTILIB_ARCH_V7M
85  static unsigned lpc17xx_sysclk(unsigned clksrcsel)
86  {
87    return (clksrcsel & LPC17XX_SCB_CLKSRCSEL_CLKSRC) != 0 ?
88      LPC24XX_OSCILLATOR_MAIN
89        : LPC24XX_OSCILLATOR_INTERNAL;
90  }
91#endif
92
93unsigned lpc24xx_pllclk(void)
94{
95  #ifdef ARM_MULTILIB_ARCH_V4
96    unsigned clksrc = GET_CLKSRCSEL_CLKSRC(CLKSRCSEL);
97    unsigned pllinclk = 0;
98    unsigned pllclk = 0;
99
100    /* Get PLL input frequency */
101    switch (clksrc) {
102      case 0:
103        pllinclk = LPC24XX_OSCILLATOR_INTERNAL;
104        break;
105      case 1:
106        pllinclk = LPC24XX_OSCILLATOR_MAIN;
107        break;
108      case 2:
109        pllinclk = LPC24XX_OSCILLATOR_RTC;
110        break;
111      default:
112        return 0;
113    }
114
115    /* Get PLL output frequency */
116    if ((PLLSTAT & PLLSTAT_PLLC) != 0) {
117      uint32_t pllcfg = PLLCFG;
118      unsigned n = GET_PLLCFG_NSEL(pllcfg) + 1;
119      unsigned m = GET_PLLCFG_MSEL(pllcfg) + 1;
120
121      pllclk = (pllinclk / n) * 2 * m;
122    } else {
123      pllclk = pllinclk;
124    }
125  #else
126    volatile lpc17xx_scb *scb = &LPC17XX_SCB;
127    unsigned sysclk = lpc17xx_sysclk(scb->clksrcsel);
128    unsigned pllstat = scb->pll_0.stat;
129    unsigned pllclk = 0;
130    unsigned enabled_and_locked = LPC17XX_PLL_STAT_PLLE
131      | LPC17XX_PLL_STAT_PLOCK;
132
133    if ((pllstat & enabled_and_locked) == enabled_and_locked) {
134      unsigned m = LPC17XX_PLL_SEL_MSEL_GET(pllstat) + 1;
135
136      pllclk = sysclk * m;
137    }
138  #endif
139
140  return pllclk;
141}
142
143unsigned lpc24xx_cclk(void)
144{
145  #ifdef ARM_MULTILIB_ARCH_V4
146    /* Get PLL output frequency */
147    unsigned pllclk = lpc24xx_pllclk();
148
149    /* Get CPU frequency */
150    unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL(CCLKCFG) + 1);
151  #else
152    volatile lpc17xx_scb *scb = &LPC17XX_SCB;
153    unsigned cclksel = scb->cclksel;
154    unsigned cclk_in = 0;
155    unsigned cclk = 0;
156
157    if ((cclksel & LPC17XX_SCB_CCLKSEL_CCLKSEL) != 0) {
158      cclk_in = lpc24xx_pllclk();
159    } else {
160      cclk_in = lpc17xx_sysclk(scb->clksrcsel);
161    }
162
163    cclk = cclk_in / LPC17XX_SCB_CCLKSEL_CCLKDIV_GET(cclksel);
164  #endif
165
166  return cclk;
167}
Note: See TracBrowser for help on using the repository browser.