embox

Форк
0
129 строк · 3.6 Кб
1
/**
2
 * @file
3
 *
4
 * @brief Implementation for microblaze timers
5
 *
6
 * @date 19.11.09
7
 * @author Anton Bondarev
8
 */
9

10
#include <drivers/common/memory.h>
11

12
#include <asm/bitops.h>
13
#include <hal/clock.h>
14
#include <hal/system.h>
15
#include <kernel/irq.h>
16
#include <kernel/panic.h>
17
#include <kernel/time/clock_source.h>
18
#include <kernel/time/ktime.h>
19

20
#include <embox/unit.h>
21

22
#include <module/embox/driver/clock/mb_timer.h>
23

24
#define CONFIG_XILINX_TIMER_BASEADDR OPTION_GET(NUMBER,mbtimer_base)
25
#define CONFIG_XILINX_TIMER_IRQ      OPTION_GET(NUMBER,irq_num)
26

27
#define TIMER_PRELOAD (SYS_CLOCK / 1000)
28

29
/*bits definition of cntl/status (tcsr) register*/
30
#define TIMER_ENALL_BIT  21      /**< ENALL */
31
#define TIMER_PWM_BIT    22      /**< PWM */
32
#define TIMER_INT_BIT    23      /**< TxINT */
33
#define TIMER_ENT_BIT    24      /**< ENT */
34
#define TIMER_ENIT_BIT   25      /**< ENIT */
35
#define TIMER_LOAD_BIT   26      /**< LOAD */
36
#define TIMER_ARHT_BIT   27      /**< ARHT */
37
#define TIMER_CAPT_BIT   28      /**< CAPT */
38
#define TIMER_GENT_BIT   29      /**< GENT */
39
#define TIMER_UDT_BIT    30      /**< UDT */
40
#define TIMER_MDT        31      /**< MDT */
41

42
/** enable both timers t0 and t1.
43
 * clearing this bit isn't change state ENT bit */
44
#define TIMER_ENABLE_ALL    REVERSE_MASK(TIMER_ENALL_BIT)
45
/** interrupt was pending. Write '1' for clearing this bit*/
46
#define TIMER_INT           REVERSE_MASK(TIMER_INT_BIT)
47
/** enable timer*/
48
#define TIMER_ENABLE        REVERSE_MASK(TIMER_ENT_BIT)
49
/** enable timer interrupt*/
50
#define TIMER_INT_ENABLE    REVERSE_MASK(TIMER_ENIT_BIT)
51
/** load value from tlr register*/
52
#define TIMER_RESET         REVERSE_MASK(TIMER_LOAD_BIT)
53
/** set reload mode*/
54
#define TIMER_RELOAD        REVERSE_MASK(TIMER_ARHT_BIT)
55
/** set down count mode*/
56
#define TIMER_DOWN_COUNT    REVERSE_MASK(TIMER_UDT_BIT)
57

58
static struct time_event_device mb_ed;
59

60
/**
61
 * Structure one of two timers. Both timers need only for pwm mode
62
 */
63
typedef volatile struct timer_regs {
64
	uint32_t tcsr; /**< control/status register TCSR */
65
	uint32_t tlr; /**< load register TLR */
66
	uint32_t tcr; /**< timer/counter register */
67
} timer_regs_t;
68

69
/**
70
 * Microblaze timer module contains two timer module, each of them is described
71
 * in @link srtuct timer_regs @endlink
72
 */
73
typedef volatile struct mb_timers {
74
	timer_regs_t tmr0;
75
	timer_regs_t tmr1;
76
} mb_timers_t;
77

78
static mb_timers_t *timers = (mb_timers_t *) CONFIG_XILINX_TIMER_BASEADDR;
79
#define timer0 (&timers->tmr0)
80

81
/*
82
 * we must use proxy for interrupt handler because we must clean bit in register
83
 * timer.
84
 */
85
static irq_return_t clock_handler(unsigned int irq_nr, void *dev_id) {
86
	clock_tick_handler(dev_id);
87
	timer0->tcsr |= TIMER_INT;
88
	return IRQ_HANDLED;
89
}
90

91
static cycle_t mb_cycle_read(struct clock_source *cs) {
92
	return TIMER_PRELOAD - timer0->tcr;
93

94
}
95

96
static int mb_timer_init(struct clock_source *cs) {
97
	if (0 != irq_attach(CONFIG_XILINX_TIMER_IRQ, clock_handler, 0, cs, "mbtimer")) {
98
		panic("mbtimer irq_attach failed");
99
	}
100
	return 0;
101
}
102

103
static int mb_clock_setup(struct clock_source *cs) {
104
	/*set clocks period*/
105
	timer0->tlr = TIMER_PRELOAD;
106
	/*clear interrupts bit and load value from tlr register*/
107
	timer0->tcsr = TIMER_INT | TIMER_RESET;
108
	/*start timer*/
109
	timer0->tcsr = TIMER_ENABLE | TIMER_INT_ENABLE | TIMER_RELOAD
110
			| TIMER_DOWN_COUNT;
111

112
	return 0;
113
}
114

115
static struct time_event_device mb_ed = {
116
	.set_periodic = mb_clock_setup,
117
	.name = "mb_timer",
118
	.irq_nr = CONFIG_XILINX_TIMER_IRQ
119
};
120

121
static struct time_counter_device mb_cd = {
122
	.read = mb_cycle_read,
123
	.cycle_hz = SYS_CLOCK,
124
};
125

126
PERIPH_MEMORY_DEFINE(mb_timer, CONFIG_XILINX_TIMER_BASEADDR, sizeof(struct timer_regs));
127

128
CLOCK_SOURCE_DEF(mb_timer, mb_timer_init, NULL,
129
	&mb_ed, &mb_cd);
130

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.