source: rtems/c/src/lib/libbsp/arm/shared/lpc/clock/lpc-clock-config.c @ df40cc9

4.115
Last change on this file since df40cc9 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup lpc_clock
5 *
6 * @brief Clock driver configuration.
7 */
8
9/*
10 * Copyright (c) 2009-2012 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.h>
24
25#include <bsp/lpc-clock-config.h>
26#include <bsp/lpc-timer.h>
27
28#ifdef ARM_MULTILIB_ARCH_V4
29
30/* This is defined in ../../../shared/clockdrv_shell.h */
31void Clock_isr(rtems_irq_hdl_param arg);
32
33static volatile lpc_timer *const lpc_clock =
34  (volatile lpc_timer *) LPC_CLOCK_TIMER_BASE;
35
36static void lpc_clock_at_tick(void)
37{
38  lpc_clock->ir = LPC_TIMER_IR_MR0;
39}
40
41static void lpc_clock_handler_install(void)
42{
43  rtems_status_code sc = RTEMS_SUCCESSFUL;
44
45  sc = rtems_interrupt_handler_install(
46    LPC_CLOCK_INTERRUPT,
47    "Clock",
48    RTEMS_INTERRUPT_UNIQUE,
49    (rtems_interrupt_handler) Clock_isr,
50    NULL
51  );
52  if (sc != RTEMS_SUCCESSFUL) {
53    rtems_fatal_error_occurred(0xdeadbeef);
54  }
55}
56
57static void lpc_clock_initialize(void)
58{
59  uint64_t interval = ((uint64_t) LPC_CLOCK_REFERENCE
60    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
61
62  /* Enable module */
63  LPC_CLOCK_MODULE_ENABLE();
64
65  /* Reset timer */
66  lpc_clock->tcr = LPC_TIMER_TCR_RST;
67
68  /* Clear interrupt flags */
69  lpc_clock->ir = LPC_TIMER_IR_ALL;
70
71  /* Set timer mode */
72  lpc_clock->ccr = 0;
73
74  /* Timer is incremented every PERIPH_CLK tick */
75  lpc_clock->pr = 0;
76
77  /* Set match registers */
78  lpc_clock->mr0 = (uint32_t) interval;
79
80  /* Generate interrupt and reset counter on match with MR0 */
81  lpc_clock->mcr = LPC_TIMER_MCR_MR0_INTR | LPC_TIMER_MCR_MR0_RST;
82
83  /* No external match */
84  lpc_clock->emr = 0x0;
85
86  /* Enable timer */
87  lpc_clock->tcr = LPC_TIMER_TCR_EN;
88}
89
90static void lpc_clock_cleanup(void)
91{
92  rtems_status_code sc = RTEMS_SUCCESSFUL;
93
94  /* Disable timer */
95  lpc_clock->tcr = 0x0;
96
97  /* Remove interrupt handler */
98  sc = rtems_interrupt_handler_remove(
99    LPC_CLOCK_INTERRUPT,
100    (rtems_interrupt_handler) Clock_isr,
101    NULL
102  );
103  if (sc != RTEMS_SUCCESSFUL) {
104    rtems_fatal_error_occurred(0xdeadbeef);
105  }
106}
107
108static uint32_t lpc_clock_nanoseconds_since_last_tick(void)
109{
110  uint64_t k = (1000000000ULL << 32) / LPC_CLOCK_REFERENCE;
111  uint64_t c = lpc_clock->tc;
112
113  if ((lpc_clock->ir & LPC_TIMER_IR_MR0) != 0) {
114    c = lpc_clock->tc + lpc_clock->mr0;
115  }
116
117  return (uint32_t) ((c * k) >> 32);
118}
119
120#define Clock_driver_support_at_tick() lpc_clock_at_tick()
121#define Clock_driver_support_initialize_hardware() lpc_clock_initialize()
122#define Clock_driver_support_install_isr(isr, old_isr) \
123  do {                                                 \
124    lpc_clock_handler_install();                       \
125    old_isr = NULL;                                    \
126  } while (0)
127
128#define Clock_driver_support_shutdown_hardware() lpc_clock_cleanup()
129#define Clock_driver_nanoseconds_since_last_tick \
130  lpc_clock_nanoseconds_since_last_tick
131
132/* Include shared source clock driver code */
133#include "../../../../shared/clockdrv_shell.h"
134
135#endif /* ARM_MULTILIB_ARCH_V4 */
Note: See TracBrowser for help on using the repository browser.