source: rtems/bsps/arm/rtl22xx/clock/clockdrv.c @ 7ee59313

5
Last change on this file since 7ee59313 was 7ee59313, checked in by Sebastian Huber <sebastian.huber@…>, on 06/01/18 at 05:11:12

Remove Clock_driver_support_shutdown_hardware()

The aim of this clock driver hook was to stop clock tick interrupts at
some late point in the exit() procedure.

The use of atexit() pulls in malloc() which pulls in errno. It is
incompatible with the intention of the
CONFIGURE_DISABLE_NEWLIB_REENTRANCY configuration option.

The exit() function must be called from thread context, so accompanied
clock tick interrupts should cause no harm. On the contrary, someone
may assume a normal operating system operation, e.g. working timeouts.

Remove the Clock_driver_support_shutdown_hardware() clock driver hook.

Close #3436.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/*
2 *  LPC22XX/LPC21xx clock specific using the System Timer
3 *
4 *  Set the Time0 to generate click for RTEMS
5 */
6
7/*
8 *  Copyright (c) 2006 by Ray <rayx.cn@gmail.com>
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.org/license/LICENSE.
13 */
14
15#include <rtems.h>
16#include <bsp.h>
17#include <bsp/irq.h>
18#include <lpc22xx.h>
19#include <rtems/bspIo.h>  /* for printk */
20#include <rtems/timecounter.h>
21
22void Clock_isr(rtems_irq_hdl_param arg);
23static void clock_isr_on(const rtems_irq_connect_data *unused);
24static void clock_isr_off(const rtems_irq_connect_data *unused);
25static int clock_isr_is_on(const rtems_irq_connect_data *irq);
26
27static rtems_timecounter_simple lpc22xx_tc;
28
29static uint32_t lpc22xx_tc_get(rtems_timecounter_simple *tc)
30{
31  return T0TC;
32}
33
34static bool lpc22xx_tc_is_pending(rtems_timecounter_simple *tc)
35{
36  return (T0IR & 0x1) != 0;
37}
38
39static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc)
40{
41  return rtems_timecounter_simple_upcounter_get(
42    tc,
43    lpc22xx_tc_get,
44    lpc22xx_tc_is_pending
45  );
46}
47
48/**
49 * When we get the clock interrupt
50 *    - clear the interrupt bit?
51 *    - restart the timer?
52 */
53static void lpc22xx_tc_at_tick(rtems_timecounter_simple *tc)
54{
55  if (!(T0IR & 0x01))
56    return;
57  T0IR = 0x01;
58  VICVectAddr = 0x00;
59}
60
61static void lpc22xx_tc_tick(void)
62{
63  rtems_timecounter_simple_upcounter_tick(
64    &lpc22xx_tc,
65    lpc22xx_tc_get,
66    lpc22xx_tc_at_tick
67  );
68}
69
70/* Replace the first value with the clock's interrupt name. */
71rtems_irq_connect_data clock_isr_data = {
72  .name   = LPC22xx_INTERRUPT_TIMER0,
73  .hdl    = Clock_isr,
74  .handle = NULL,
75  .on     = clock_isr_on,
76  .off    = clock_isr_off,
77  .isOn   = clock_isr_is_on,
78};
79
80/* use the /shared/dev/clock/clockimpl.h code template */
81
82/**
83 * Installs the clock ISR. You shouldn't need to change this.
84 */
85#define Clock_driver_support_install_isr( _new ) \
86  BSP_install_rtems_irq_handler(&clock_isr_data)
87
88/**
89 * Initialize the hardware for the clock
90 *   - Set the frequency
91 *   - enable it
92 *   - clear any pending interrupts
93 *
94 * Since you may want the clock always running, you can
95 * enable interrupts here. If you do so, the clock_isr_on(),
96 * clock_isr_off(), and clock_isr_is_on() functions can be
97 * NOPs.
98 *
99 * set timer to generate interrupt every
100 * rtems_configuration_get_microseconds_per_tick()
101 *     MR0/(LPC22xx_Fpclk/(PR0+1)) = 10/1000 = 0.01s
102 */
103#define Clock_driver_support_initialize_hardware() \
104  do { \
105    /* disable and clear timer 0, set to  */ \
106    T0TCR &= 0;                              \
107    /* TC is incremented on every pclk.*/    \
108    T0PC   = 0;                              \
109    /* initialize the timer period and prescaler */  \
110    T0MR0  = ((LPC22xx_Fpclk/1000 *          \
111             rtems_configuration_get_microseconds_per_tick()) / 1000); \
112    /* generate interrupt when T0MR0 match T0TC and Reset Timer Count*/ \
113    T0MCR |= 0x03;          \
114    /* No external match */ \
115    T0EMR = 0;              \
116    /* enable timer0 */     \
117    T0TCR = 1;              \
118    /* enable interrupt, skyeye will check this*/ \
119    T0IR |= 0x01; \
120    /* install timecounter */ \
121    rtems_timecounter_simple_install( \
122      &lpc22xx_tc, \
123      LPC22xx_Fpclk, \
124      T0MR0, \
125      lpc22xx_tc_get_timecount \
126    ); \
127  } while (0)
128
129/**
130 * Enables clock interrupt.
131 *
132 * If the interrupt is always on, this can be a NOP.
133 */
134static void clock_isr_on(const rtems_irq_connect_data *unused)
135{
136  T0IR&=0x01;
137}
138
139/**
140 * Disables clock interrupts
141 *
142 * If the interrupt is always on, this can be a NOP.
143 */
144static void clock_isr_off(const rtems_irq_connect_data *unused)
145{
146  T0IR=0x00;
147}
148
149/**
150 * Tests to see if clock interrupt is enabled, and returns 1 if so.
151 * If interrupt is not enabled, returns 0.
152 *
153 * If the interrupt is always on, this always returns 1.
154 */
155static int clock_isr_is_on(const rtems_irq_connect_data *irq)
156{
157  return T0IR & 0x01;  /* MR0 mask */
158}
159
160#define Clock_driver_timecounter_tick() lpc22xx_tc_tick()
161
162/* Make sure to include this, and only at the end of the file */
163#include "../../../shared/dev/clock/clockimpl.h"
164
Note: See TracBrowser for help on using the repository browser.