blob: 0792ad37be645fb2de2f2318004df0a512b9e568 (
about) (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#ifndef ARMCLOCK_H
#define ARMCLOCK_H
#include <stdint.h>
#include "global.h"
#include "interrupts.h"
#define ARMCLK_LOAD (ARM_BASE + 0x400)
#define ARMCLK_VALUE (ARM_BASE + 0x404)
#define ARMCLK_CONTROL (ARM_BASE + 0x408)
#define ARMCLK_IRQ_CLR_ACK (ARM_BASE + 0x40C)
#define ARMCLK_RAW_IRQ (ARM_BASE + 0x410)
#define ARMCLK_MASKED_IRQ (ARM_BASE + 0x414)
#define ARMCLK_RELOAD (ARM_BASE + 0x418)
#define ARMCLK_PRE_DRIVER (ARM_BASE + 0x41C)
#define ARMCLK_FREE_RUNNING_COUNTER (ARM_BASE + 0x420)
typedef union armclk_control
{
uint32_t raw;
struct
{
uint32_t one_shot_mode : 1; // bit 0; unused in RPi
uint32_t counter_23bit : 1; // bit 1
uint32_t pre_scale : 2; // bits 3:2
uint32_t bit_4 : 1; // bit 4
uint32_t interrupt_enable : 1; // bit 5
uint32_t periodic_mode : 1; // bit 6; unused in RPi
uint32_t timer_enable : 1; // bit 7
uint32_t halt_in_debug : 1; // bit 8
uint32_t free_running_enable : 1; // bit 9
uint32_t bits_15_10 : 6; // bits 15:10
uint32_t free_running_pre_scaler : 8; // bits 23:16
uint32_t bits_31_24 : 8; // bits 31:24
} fields;
} armclk_control_t;
static inline void armclk_init(void)
{
armclk_control_t ctrl = (armclk_control_t) (uint32_t) 0;
ctrl.fields.timer_enable = 1;
ctrl.fields.interrupt_enable = 1;
ctrl.fields.counter_23bit = 1;
wr32(ARMCLK_CONTROL, ctrl.raw);
}
static inline void armclk_enable_timer_irq(void)
{
armclk_control_t ctrl = (armclk_control_t) rd32(ARMCLK_CONTROL);
ctrl.fields.interrupt_enable = 1;
wr32(ARMCLK_CONTROL, ctrl.raw);
wr32(ARM_ENABLE_BASIC_IRQS, 1);
}
static inline void armclk_disable_timer_irq(void)
{
armclk_control_t ctrl = (armclk_control_t) rd32(ARMCLK_CONTROL);
ctrl.fields.interrupt_enable = 0;
wr32(ARMCLK_CONTROL, ctrl.raw);
wr32(ARM_DISABLE_BASIC_IRQS, 1);
}
static inline void armclk_irq_settimeout(uint32_t timeout)
{
wr32(ARMCLK_IRQ_CLR_ACK, 0);
wr32(ARMCLK_LOAD, timeout);
}
static inline _Bool armclk_irq_pending(void)
{
return rd32(ARM_IRQ_BASIC_PENDING) & 1;
}
#endif // ARMCLOCK_H
|