summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/lpc24xx/misc/system-clocks.c
blob: 110e9aef15f902d981726dedb76aab9aab38ba58 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
 * @file
 *
 * @ingroup lpc24xx_clocks
 *
 * @brief System clocks.
 */

/*
 * Copyright (c) 2008
 * Embedded Brains GmbH
 * Obere Lagerstr. 30
 * D-82178 Puchheim
 * Germany
 * rtems@embedded-brains.de
 *
 * The license and distribution terms for this file may be found in the file
 * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE.
 */

#include <bsp.h>
#include <bsp/utility.h>
#include <bsp/lpc24xx.h>
#include <bsp/system-clocks.h>

/**
 * @brief Internal RC oscillator frequency in [Hz].
 */
#define LPC24XX_OSCILLATOR_INTERNAL 4000000U

#ifndef LPC24XX_OSCILLATOR_MAIN
  #error "unknown main oscillator frequency"
#endif

#ifndef LPC24XX_OSCILLATOR_RTC
  #error "unknown RTC oscillator frequency"
#endif

void lpc24xx_timer_initialize(void)
{
  /* Reset timer */
  T1TCR = TCR_RST;

  /* Set timer mode */
  T1CTCR = 0;

  /* Set prescaler to zero */
  T1PR = 0;

  /* Reset all interrupt flags */
  T1IR = 0xff;

  /* Do not stop on a match */
  T1MCR = 0;

  /* No captures */
  T1CCR = 0;

  /* Start timer */
  T1TCR = TCR_EN;
}

void lpc24xx_micro_seconds_delay(unsigned us)
{
  unsigned start = lpc24xx_timer();
  unsigned end = start + us * (lpc24xx_cclk() / 1000000);
  unsigned now = 0;

  do {
    now = lpc24xx_timer();
  } while (now < end);
}

unsigned lpc24xx_pllclk(void)
{
  unsigned clksrc = GET_CLKSRCSEL_CLKSRC(CLKSRCSEL);
  unsigned pllinclk = 0;
  unsigned pllclk = 0;

  /* Get PLL input frequency */
  switch (clksrc) {
    case 0:
      pllinclk = LPC24XX_OSCILLATOR_INTERNAL;
      break;
    case 1:
      pllinclk = LPC24XX_OSCILLATOR_MAIN;
      break;
    case 2:
      pllinclk = LPC24XX_OSCILLATOR_RTC;
      break;
    default:
      return 0;
  }

  /* Get PLL output frequency */
  if (IS_FLAG_SET(PLLSTAT, PLLSTAT_PLLC)) {
    uint32_t pllcfg = PLLCFG;
    unsigned n = GET_PLLCFG_NSEL(pllcfg) + 1;
    unsigned m = GET_PLLCFG_MSEL(pllcfg) + 1;

    pllclk = (pllinclk / n) * 2 * m;
  } else {
    pllclk = pllinclk;
  }

  return pllclk;
}

unsigned lpc24xx_cclk(void)
{
  /* Get PLL output frequency */
  unsigned pllclk = lpc24xx_pllclk();

  /* Get CPU frequency */
  unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL(CCLKCFG) + 1);

  return cclk;
}