Intel® Quark™ Microcontroller Software Interface 1.4.0 Intel® Quark™ Microcontroller BSP

- Main Page
- Modules
- Data Structures
- Files

- File List

qm_pic_timer.c
1 /*
2 * {% copyright %}
3 */
4
5 #include "qm_pic_timer.h"
6
7 /*
8 * PIC timer access layer. Supports both Local APIC timer and MVIC timer.
9 *
10 * The MVIC timer differs from the LAPIC specs in that:
11 * - it does not support TSC deadline mode
12 * - vector table lvttimer[3:0] holds the IRQ (not the vector) of the timer
13 */
14
15 #define LVTTIMER_MODE_PERIODIC_OFFS (17)
16 #define LVTTIMER_INT_MASK_OFFS (16)
17
18 static void (*callback)(void *data);
19 static void *callback_data;
20
21 #if (HAS_APIC)
22 #define PIC_TIMER (QM_LAPIC)
23 #else
24 #define PIC_TIMER (QM_PIC_TIMER)
25 #endif
26
27 QM_ISR_DECLARE(qm_pic_timer_0_isr)
28 {
29 if (callback) {
30 callback(callback_data);
31 }
32
33 #if (HAS_APIC)
34 /* Use an invalid vector to avoid acknowledging a valid IRQ */
35 QM_ISR_EOI(0);
36 #else
37 QM_ISR_EOI(QM_IRQ_PIC_TIMER_VECTOR);
38 #endif
39 }
40
41 int qm_pic_timer_set_config(const qm_pic_timer_config_t *const cfg)
42 {
43 QM_CHECK(cfg != NULL, -EINVAL);
44 QM_CHECK(cfg->mode <= QM_PIC_TIMER_MODE_PERIODIC, -EINVAL);
45
46 /* Stop timer, mask interrupt and program interrupt vector */
47 PIC_TIMER->timer_icr.reg = 0;
48 PIC_TIMER->lvttimer.reg = BIT(LVTTIMER_INT_MASK_OFFS) |
49 #if (HAS_APIC)
50 QM_X86_PIC_TIMER_INT_VECTOR;
51 #else
52 QM_IRQ_PIC_TIMER;
53 #endif
54
55 #if (HAS_APIC)
56 /* LAPIC has a timer clock divisor, POR default: 2. Set it to 1. */
57 QM_LAPIC->timer_dcr.reg = 0xB;
58 #endif
59
60 PIC_TIMER->lvttimer.reg |= cfg->mode << LVTTIMER_MODE_PERIODIC_OFFS;
61 callback = cfg->callback;
62 callback_data = cfg->callback_data;
63 if (cfg->int_en) {
64 PIC_TIMER->lvttimer.reg &= ~BIT(LVTTIMER_INT_MASK_OFFS);
65 }
66 return 0;
67 }
68
69 int qm_pic_timer_set(const uint32_t count)
70 {
71 PIC_TIMER->timer_icr.reg = count;
72
73 return 0;
74 }
75
76 int qm_pic_timer_get(uint32_t *const count)
77 {
78 QM_CHECK(count != NULL, -EINVAL);
79
80 *count = PIC_TIMER->timer_ccr.reg;
81
82 return 0;
83 }
84
85 #if (ENABLE_RESTORE_CONTEXT)
86 int qm_pic_timer_save_context(qm_pic_timer_context_t *const ctx)
87 {
88 QM_CHECK(ctx != NULL, -EINVAL);
89
90 ctx->timer_icr = PIC_TIMER->timer_ccr.reg;
91 ctx->timer_dcr = PIC_TIMER->timer_dcr.reg;
92 ctx->lvttimer = PIC_TIMER->lvttimer.reg;
93
94 return 0;
95 }
96
97 int qm_pic_timer_restore_context(const qm_pic_timer_context_t *const ctx)
98 {
99 QM_CHECK(ctx != NULL, -EINVAL);
100
101 /* The PIC Timer is restored to the value before sleep. */
102 PIC_TIMER->timer_icr.reg = ctx->timer_icr;
103 PIC_TIMER->timer_dcr.reg = ctx->timer_dcr;
104 PIC_TIMER->lvttimer.reg = ctx->lvttimer;
105
106 return 0;
107 }
108 #else
109 int qm_pic_timer_save_context(qm_pic_timer_context_t *const ctx)
110 {
111 (void)ctx;
112
113 return 0;
114 }
115
116 int qm_pic_timer_restore_context(const qm_pic_timer_context_t *const ctx)
117 {
118 (void)ctx;
119
120 return 0;
121 }
122 #endif
qm_pic_timer_config_t::callback
void(* callback)(void *data)
User callback.
Definition: qm_pic_timer.h:38
qm_pic_timer_context_t::timer_icr
uint32_t timer_icr
Initial Count Register.
Definition: qm_soc_regs.h:284
qm_pic_timer_context_t
PIC TIMER context type.
Definition: qm_soc_regs.h:283
qm_pic_timer_set
int qm_pic_timer_set(const uint32_t count)
Set the current count value of the PIC timer.
Definition: qm_pic_timer.c:69
QM_PIC_TIMER_MODE_PERIODIC
Periodic mode.
Definition: qm_pic_timer.h:23
qm_pic_timer_restore_context
int qm_pic_timer_restore_context(const qm_pic_timer_context_t *const ctx)
Restore PIC Timer peripheral's context.
Definition: qm_pic_timer.c:97
qm_pic_timer_config_t::int_en
bool int_en
Interrupt enable.
Definition: qm_pic_timer.h:31
qm_pic_timer_context_t::timer_dcr
uint32_t timer_dcr
Divide Configuration Register.
Definition: qm_soc_regs.h:285
QM_ISR_DECLARE
QM_ISR_DECLARE(qm_pic_timer_0_isr)
ISR for PIC Timer interrupt.
Definition: qm_pic_timer.c:27
qm_pic_timer_get
int qm_pic_timer_get(uint32_t *const count)
Get the current count value of the PIC timer.
Definition: qm_pic_timer.c:76
qm_pic_timer_config_t::mode
qm_pic_timer_mode_t mode
Operation mode.
Definition: qm_pic_timer.h:30
qm_pic_timer_set_config
int qm_pic_timer_set_config(const qm_pic_timer_config_t *const cfg)
Set the PIC timer configuration.
Definition: qm_pic_timer.c:41
qm_pic_timer_context_t::lvttimer
uint32_t lvttimer
Timer Entry in Local Vector Table.
Definition: qm_soc_regs.h:286
qm_pic_timer_config_t
PIC timer configuration type.
Definition: qm_pic_timer.h:29
qm_pic_timer_save_context
int qm_pic_timer_save_context(qm_pic_timer_context_t *const ctx)
Save PIC Timer peripheral's context.
Definition: qm_pic_timer.c:86
qm_pic_timer_config_t::callback_data
void * callback_data
Callback user data.
Definition: qm_pic_timer.h:39