source: rtems/bsps/mips/rbtx4925/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: 5.5 KB
Line 
1/**
2 *  @file
3 * 
4 *  Instantiate the clock driver shell.
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2012.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.org/license/LICENSE.
14 */
15
16#include <rtems.h>
17#include <bsp/irq.h>
18#include <bsp.h>
19
20/* #define CLOCK_DRIVER_USE_FAST_IDLE 1 */
21
22#define CLOCK_VECTOR TX4925_IRQ_TMR0
23
24#define TX4925_TIMER_INTERVAL_MODE 1
25#define TX4925_TIMER_PULSE_MODE 2
26#define TX4925_TIMER_MODE TX4925_TIMER_INTERVAL_MODE
27
28#if (TX4925_TIMER_MODE == TX4925_TIMER_INTERVAL_MODE)
29#define TX4925_TIMER_INTERRUPT_FLAG TIIS
30#define Clock_driver_support_initialize_hardware() \
31          Initialize_timer0_in_interval_mode()
32#elif (TX4925_TIMER_MODE == TX4925_TIMER_PULSE_MODE)
33#define TX4925_TIMER_INTERRUPT_FLAG TPIBS
34#define Clock_driver_support_initialize_hardware() \
35          Initialize_timer0_in_pulse_mode()
36#else
37#error "Build Error: need to select timer mode"
38#endif
39
40
41#define Clock_driver_support_install_isr( _new ) \
42  rtems_interrupt_handler_install( CLOCK_VECTOR, "clock", 0, _new, NULL )
43
44
45#define Clock_driver_support_at_tick() \
46  do { \
47        uint32_t interrupt_flag; \
48        do { \
49                int loop_count; \
50                TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR, 0x0 ); /* Clear timer 0 interrupt */ \
51                loop_count = 0; \
52                do { /* Wait until interrupt flag is cleared (this prevents re-entering interrupt) */ \
53                        /* Read back interrupt status register and isolate interval timer flag */ \
54                        interrupt_flag = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TISR ) & TX4925_TIMER_INTERRUPT_FLAG; \
55                } while (interrupt_flag && (++loop_count < 10)); /* Loop while timer interrupt bit is set, or loop count is lees than 10 */ \
56        } while(interrupt_flag); \
57  } while(0)
58
59
60/* Setup timer in interval mode to generate peiodic interrupts */
61#define Initialize_timer0_in_interval_mode() \
62  do { \
63        uint32_t temp; \
64    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \
65    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \
66    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, TIMER_CLEAR_ENABLE_MASK ); /* Set interval timer mode register */ \
67    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x30d40 ); /* Set tmier period ,10.0 msec (20 MHz timer clock) */ \
68    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC0 ); /* Enable timer in interval mode */ \
69    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \
70    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \
71    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \
72    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \
73    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR ); /* Enable interval timer interrupts */ \
74    temp |= TIMER_INT_ENABLE_MASK; \
75    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_ITMR, temp ); \
76  } while(0)
77
78
79/* This mode is used to generate periodic interrupts and also output a pulse on PIO20 pin */
80#define Initialize_timer0_in_pulse_mode() \
81  do { \
82        uint32_t temp; \
83    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0x0 ); /* Disable timer */ \
84    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CCDR, 0x0 ); /* Set register for divide by 2 clock */ \
85    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, FFI ); /* Set pulse generator mode register */ \
86    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRA, 0x3e8 ); /* Set pulse high duration ,0.05 msec (20 MHz timer clock) */ \
87/*    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x1388 ); */ /* Set pulse total period, 0.25 msec (20 MHz timer clock) */ \
88    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_CPRB, 0x30d40 ); /* Set pulse total period, 10 msec (20 MHz timer clock) */ \
89    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_TCR, 0xC1 ); /* Enable timer in pulse generator mode */ \
90 \
91        /* Enable timer 0 output pulses on PIO20 */ \
92    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_CFG_PCFG ); \
93    temp = (temp & ~ SELCHI) | SELTMR0; /* Enable timer 0 pulses on PIO20 */ \
94    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_CFG_PCFG, temp ); \
95 \
96    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DM0, 0x0 ); /* Set interrupt controller detection mode */ \
97    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_LVL2, 0x1000000 ); /* Set interrupt controller level */ \
98    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_MSK, 0x0 ); /* Set interrupt controller mask */ \
99    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_IRQCTL_DEN, 0x1 ); /* Enable interrupts from controller */ \
100    temp = TX4925_REG_READ( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR ); /* Enable pulse generator interrupt */ \
101    temp |= TPIBE;      /* Only want interrupts on B compare (where clock count is cleared) */ \
102    TX4925_REG_WRITE( TX4925_REG_BASE, TX4925_TIMER0_BASE + TX4925_TIMER_PGMR, temp ); \
103  } while(0)
104
105
106#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
107
108#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.