embox

Форк
0
/
raspi_systick.c 
105 строк · 2.7 Кб
1
/**
2
 * @file
3
 * @brief Core clocking device in Raspberry PI
4
 *
5
 * See BCM2835-ARM-Peripherals.pdf, 12 chapter for details.
6
 *
7
 * A frequency of the System Timer is 1 MHz.
8
 *
9
 * @date 02.07.15
10
 * @author Vita Loginova
11
 */
12

13
#include <drivers/common/memory.h>
14
#include <hal/clock.h>
15
#include <hal/reg.h>
16
#include <hal/system.h>
17
#include <kernel/irq.h>
18
#include <kernel/time/clock_source.h>
19
#include <sys/mman.h>
20
#include <hal/mmu.h>
21
#include <util/binalign.h>
22
#include <framework/mod/options.h>
23

24
#include <embox/unit.h>
25

26
#define BCM2835_SYSTEM_TIMER_BASE OPTION_GET(NUMBER,base_addr)
27

28
/**
29
 * Layout of the System Timer Registers.
30
 */
31
struct raspi_timer_regs {
32
	uint32_t CS;  /**< Control/Status */
33
	uint32_t CLO; /**< Counter Lower 32 bits */
34
	uint32_t CHI; /**< Counter Higher 32 bits */
35
	uint32_t C0;  /**< Compare 0. DO NOT USE; is used by GPU.  */
36
	uint32_t C1;  /**< Compare 1 */
37
	uint32_t C2;  /**< Compare 2. DO NOT USE; is used by GPU.  */
38
	uint32_t C3;  /**< Compare 3 */
39
};
40

41
/**
42
 * Need to write one of these values into CS register to clear the
43
 * match detect status bit and the corresponding interrupt request line.
44
 */
45
#define BCM2835_SYSTEM_TIMER_MATCH_0 (1 << 0)
46
#define BCM2835_SYSTEM_TIMER_MATCH_1 (1 << 1)
47
#define BCM2835_SYSTEM_TIMER_MATCH_2 (1 << 2)
48
#define BCM2835_SYSTEM_TIMER_MATCH_3 (1 << 3)
49

50
#define SYSTICK_IRQ 3
51
#define CLOCK_DIVIDER 70
52

53
#define RELOAD_VALUE (SYS_CLOCK / (CLOCK_DIVIDER * 1000))
54

55
static volatile struct raspi_timer_regs * const regs =
56
		(volatile struct raspi_timer_regs*)BCM2835_SYSTEM_TIMER_BASE;
57

58
static inline void raspi_systick_clear(void) {
59
	regs->CS = BCM2835_SYSTEM_TIMER_MATCH_3;
60
}
61

62
static inline void raspi_systick_comare(uint32_t value) {
63
	regs->C3 = regs->CLO + value;
64
}
65

66
static irq_return_t clock_handler(unsigned int irq_nr, void *data) {
67
	raspi_systick_clear();
68
	raspi_systick_comare(RELOAD_VALUE);
69

70
	clock_tick_handler(data);
71

72
	return IRQ_HANDLED;
73
}
74

75
static int raspi_systick_init(struct clock_source *cs) {
76
	irq_attach(SYSTICK_IRQ, clock_handler, 0, cs, "Raspberry PI systick timer");
77
	return 0;
78
}
79

80
static int this_set_periodic(struct clock_source *cs) {
81
	raspi_systick_clear();
82
	/* From that point interrupts will occur. */
83
	raspi_systick_comare(RELOAD_VALUE);
84

85
	return 0;
86
}
87

88
static cycle_t this_read(struct clock_source *cs) {
89
	return regs->CLO;
90
}
91

92
static struct time_event_device raspi_systick_event = {
93
	.set_periodic = this_set_periodic,
94
	.irq_nr = SYSTICK_IRQ,
95
};
96

97
static struct time_counter_device raspi_systick_counter = {
98
	.read = this_read,
99
	.cycle_hz = SYS_CLOCK / CLOCK_DIVIDER,
100
};
101

102
PERIPH_MEMORY_DEFINE(raspi_systick, BCM2835_SYSTEM_TIMER_BASE, sizeof(struct raspi_timer_regs));
103

104
CLOCK_SOURCE_DEF(raspi_systick, raspi_systick_init, NULL,
105
	&raspi_systick_event, &raspi_systick_counter);
106

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

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

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

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