source: rtems/c/src/lib/libbsp/arm/shared/armv7m/clock/armv7m-clock-config.c @ f0d66b1

4.115
Last change on this file since f0d66b1 was 34c61517, checked in by Sebastian Huber <sebastian.huber@…>, on 03/24/12 at 19:14:27

bsps: Shared ARMv7-M clock driver

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*
2 * Copyright (c) 2011-2012 Sebastian Huber.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#include <rtems.h>
16#include <rtems/score/armv7m.h>
17
18#include <bsp.h>
19
20#ifdef ARM_MULTILIB_ARCH_V7M
21
22/* This is defined in clockdrv_shell.h */
23rtems_isr Clock_isr(rtems_vector_number vector);
24
25#define _ARMV7M_Systick_get_factor(freq) \
26  ((1000000000ULL << 32) / (freq))
27
28#ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
29  #define _ARMV7M_Systick_factor \
30    _ARMV7M_Systick_get_factor(BSP_ARMV7M_SYSTICK_FREQUENCY)
31#else
32  static uint64_t _ARMV7M_Systick_factor;
33#endif
34
35static void _ARMV7M_Systick_at_tick(void)
36{
37  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
38
39  /* Clear COUNTFLAG */
40  systick->csr;
41}
42
43static void _ARMV7M_Systick_handler(void)
44{
45  _ARMV7M_Interrupt_service_enter();
46  Clock_isr(ARMV7M_VECTOR_SYSTICK);
47  _ARMV7M_Interrupt_service_leave();
48}
49
50static void _ARMV7M_Systick_handler_install(void)
51{
52  _ARMV7M_Set_exception_priority(
53    ARMV7M_VECTOR_SYSTICK,
54    ARMV7M_EXCEPTION_PRIORITY_LOWEST
55  );
56  _ARMV7M_Set_exception_handler(
57    ARMV7M_VECTOR_SYSTICK,
58    _ARMV7M_Systick_handler
59  );
60}
61
62static void _ARMV7M_Systick_initialize(void)
63{
64  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
65  #ifdef BSP_ARMV7M_SYSTICK_FREQUENCY
66    uint64_t freq = BSP_ARMV7M_SYSTICK_FREQUENCY;
67  #else
68    uint64_t freq = ARMV7M_SYSTICK_CALIB_TENMS_GET(systick->calib) * 100ULL;
69  #endif
70  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
71  uint64_t interval = (freq * us_per_tick) / 1000000ULL;
72
73  #ifndef BSP_ARMV7M_SYSTICK_FREQUENCY
74    _ARMV7M_Systick_factor = _ARMV7M_Systick_get_factor(freq);
75  #endif
76
77  systick->rvr = (uint32_t) interval;
78  systick->cvr = 0;
79  systick->csr = ARMV7M_SYSTICK_CSR_ENABLE
80    | ARMV7M_SYSTICK_CSR_TICKINT
81    | ARMV7M_SYSTICK_CSR_CLKSOURCE;
82}
83
84static void _ARMV7M_Systick_cleanup(void)
85{
86  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
87
88  systick->csr = 0;
89}
90
91static uint32_t _ARMV7M_Systick_nanoseconds_since_last_tick(void)
92{
93  volatile ARMV7M_Systick *systick = _ARMV7M_Systick;
94  volatile ARMV7M_SCB *scb = _ARMV7M_SCB;
95  uint32_t rvr = systick->rvr;
96  uint32_t c = rvr - systick->cvr;
97
98  if ((scb->icsr & ARMV7M_SCB_ICSR_PENDSTSET) != 0) {
99    c = rvr - systick->cvr + rvr;
100  }
101
102  return (uint32_t) ((c * _ARMV7M_Systick_factor) >> 32);
103}
104
105#define Clock_driver_support_at_tick() \
106  _ARMV7M_Systick_at_tick()
107
108#define Clock_driver_support_initialize_hardware() \
109  _ARMV7M_Systick_initialize()
110
111#define Clock_driver_support_install_isr(isr, old_isr) \
112  do { \
113    _ARMV7M_Systick_handler_install(); \
114    old_isr = NULL; \
115  } while (0)
116
117#define Clock_driver_support_shutdown_hardware() \
118  _ARMV7M_Systick_cleanup()
119
120#define Clock_driver_nanoseconds_since_last_tick \
121  _ARMV7M_Systick_nanoseconds_since_last_tick
122
123/* Include shared source clock driver code */
124#include "../../../../shared/clockdrv_shell.h"
125
126#endif /* ARM_MULTILIB_ARCH_V7M */
Note: See TracBrowser for help on using the repository browser.