source: rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c @ f3b29236

Last change on this file since f3b29236 was f3b29236, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 18, 2017 at 6:22:38 AM

bsps: Clock_driver_support_install_isr()

Remove old ISR parameter since is not used by the clock driver shell.
Make an implementation optional.

Update #3139.

  • Property mode set to 100644
File size: 6.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup mpc55xx
5 *
6 * @brief Clock driver configuration.
7 */
8
9/*
10 * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
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 <bsp.h>
24#include <bsp/fatal.h>
25#include <bsp/irq.h>
26
27#include <mpc55xx/regs.h>
28
29#include <rtems/timecounter.h>
30
31void Clock_isr(void *arg);
32
33static rtems_timecounter_simple mpc55xx_tc;
34
35#if defined(MPC55XX_CLOCK_EMIOS_CHANNEL)
36
37#include <mpc55xx/emios.h>
38
39static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
40{
41  return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CCNTR.R;
42}
43
44static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
45{
46  return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.B.FLAG != 0;
47}
48
49static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
50{
51  return rtems_timecounter_simple_upcounter_get(
52    tc,
53    mpc55xx_tc_get,
54    mpc55xx_tc_is_pending
55  );
56}
57
58static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
59{
60  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
61  csr.B.FLAG = 1;
62  EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R;
63}
64
65static void mpc55xx_tc_tick(void)
66{
67  rtems_timecounter_simple_upcounter_tick(
68    &mpc55xx_tc,
69    mpc55xx_tc_get,
70    mpc55xx_tc_at_tick
71  );
72}
73
74static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
75{
76  rtems_status_code sc = RTEMS_SUCCESSFUL;
77
78  sc = mpc55xx_interrupt_handler_install(
79    MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL),
80    "clock",
81    RTEMS_INTERRUPT_UNIQUE,
82    MPC55XX_INTC_MIN_PRIORITY,
83    (rtems_interrupt_handler) isr,
84    NULL
85  );
86  if (sc != RTEMS_SUCCESSFUL) {
87    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_IRQ_INSTALL);
88  }
89}
90
91static void mpc55xx_clock_initialize(void)
92{
93  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
94  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
95  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
96  unsigned prescaler = mpc55xx_emios_global_prescaler();
97  uint64_t reference_clock = bsp_clock_speed;
98  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
99  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
100
101  /* Apply prescaler */
102  if (prescaler > 0) {
103    interval /= (uint64_t) prescaler;
104  } else {
105    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_PRESCALER);
106  }
107
108  /* Check interval */
109  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
110    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_INTERVAL);
111  }
112
113  /* Configure eMIOS channel */
114
115  /* Set channel in GPIO mode */
116  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
117  regs->CCR.R = ccr.R;
118
119  /* Clear status flags */
120  csr.B.OVR = 1;
121  csr.B.OVFL = 1;
122  csr.B.FLAG = 1;
123  regs->CSR.R = csr.R;
124
125  /* Set internal counter start value */
126  regs->CCNTR.R = 1;
127
128  /* Set timer period */
129  regs->CADR.R = (uint32_t) interval - 1;
130
131  /* Set control register */
132  #if MPC55XX_CHIP_FAMILY == 551
133    ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
134  #else
135    ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
136  #endif
137  ccr.B.UCPREN = 1;
138  ccr.B.FEN = 1;
139  ccr.B.FREN = 1;
140  regs->CCR.R = ccr.R;
141
142  rtems_timecounter_simple_install(
143    &mpc55xx_tc,
144    reference_clock,
145    interval,
146    mpc55xx_tc_get_timecount
147  );
148}
149
150static void mpc55xx_clock_cleanup(void)
151{
152  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
153  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
154
155  /* Set channel in GPIO mode */
156  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
157  regs->CCR.R = ccr.R;
158}
159
160#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
161
162static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
163{
164  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].CVAL.R;
165}
166
167static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
168{
169  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].TFLG.B.TIF != 0;
170}
171
172static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
173{
174  return rtems_timecounter_simple_downcounter_get(
175    tc,
176    mpc55xx_tc_get,
177    mpc55xx_tc_is_pending
178  );
179}
180
181static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
182{
183  volatile PIT_RTI_CHANNEL_tag *channel =
184    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
185  PIT_RTI_TFLG_32B_tag tflg = { .B = { .TIF = 1 } };
186
187  channel->TFLG.R = tflg.R;
188}
189
190static void mpc55xx_tc_tick(void)
191{
192  rtems_timecounter_simple_downcounter_tick(
193    &mpc55xx_tc,
194    mpc55xx_tc_get,
195    mpc55xx_tc_at_tick
196  );
197}
198
199static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
200{
201  rtems_status_code sc = RTEMS_SUCCESSFUL;
202
203  sc = mpc55xx_interrupt_handler_install(
204    MPC55XX_IRQ_PIT_CHANNEL(MPC55XX_CLOCK_PIT_CHANNEL),
205    "clock",
206    RTEMS_INTERRUPT_UNIQUE,
207    MPC55XX_INTC_MIN_PRIORITY,
208    (rtems_interrupt_handler) isr,
209    NULL
210  );
211  if (sc != RTEMS_SUCCESSFUL) {
212    bsp_fatal(MPC55XX_FATAL_CLOCK_PIT_IRQ_INSTALL);
213  }
214}
215
216static void mpc55xx_clock_initialize(void)
217{
218  volatile PIT_RTI_CHANNEL_tag *channel =
219    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
220  uint64_t reference_clock = bsp_clock_speed;
221  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
222  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
223  PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } };
224  PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } };
225
226  PIT_RTI.PITMCR.R = pitmcr.R;
227  channel->LDVAL.R = interval;
228  channel->TCTRL.R = tctrl.R;
229
230  rtems_timecounter_simple_install(
231    &mpc55xx_tc,
232    reference_clock,
233    interval,
234    mpc55xx_tc_get_timecount
235  );
236}
237
238static void mpc55xx_clock_cleanup(void)
239{
240  volatile PIT_RTI_CHANNEL_tag *channel =
241    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
242
243  channel->TCTRL.R = 0;
244}
245
246#endif
247
248#define Clock_driver_timecounter_tick() mpc55xx_tc_tick()
249#define Clock_driver_support_initialize_hardware() \
250  mpc55xx_clock_initialize()
251#define Clock_driver_support_install_isr(isr) \
252  mpc55xx_clock_handler_install(isr)
253#define Clock_driver_support_shutdown_hardware() \
254  mpc55xx_clock_cleanup()
255
256/* Include shared source clock driver code */
257#include "../../../../libbsp/shared/clockdrv_shell.h"
Note: See TracBrowser for help on using the repository browser.