Lines Matching +full:- +full:s

2  * nRF51 System-on-Chip Timer peripheral
7 * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
11 * the COPYING file in the top-level directory.
20 #include "hw/qdev-properties.h"
28 static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns) in ns_to_ticks() argument
30 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler; in ns_to_ticks()
35 static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks) in ticks_to_ns() argument
37 uint32_t freq = TIMER_CLK_FREQ >> s->prescaler; in ticks_to_ns()
43 static uint32_t update_counter(NRF51TimerState *s, int64_t now) in update_counter() argument
45 uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns); in update_counter()
47 s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]); in update_counter()
53 s->update_counter_ns += ticks_to_ns(s, ticks); in update_counter()
57 /* Assumes s->counter is up-to-date */
58 static void rearm_timer(NRF51TimerState *s, int64_t now) in rearm_timer() argument
66 if (s->events_compare[i]) { in rearm_timer()
70 if (s->cc[i] <= s->counter) { in rearm_timer()
71 delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) - in rearm_timer()
72 s->counter + s->cc[i]); in rearm_timer()
74 delta_ns = ticks_to_ns(s, s->cc[i] - s->counter); in rearm_timer()
83 timer_mod_ns(&s->timer, now + min_ns); in rearm_timer()
87 static void update_irq(NRF51TimerState *s) in update_irq() argument
93 flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1); in update_irq()
95 qemu_set_irq(s->irq, flag); in update_irq()
100 NRF51TimerState *s = NRF51_TIMER(opaque); in timer_expire() local
108 if (s->cc[i] > s->counter) { in timer_expire()
109 cc_remaining[i] = s->cc[i] - s->counter; in timer_expire()
111 cc_remaining[i] = BIT(bitwidths[s->bitmode]) - in timer_expire()
112 s->counter + s->cc[i]; in timer_expire()
116 ticks = update_counter(s, now); in timer_expire()
120 s->events_compare[i] = 1; in timer_expire()
122 if (s->shorts & BIT(i)) { in timer_expire()
123 s->timer_start_ns = now; in timer_expire()
124 s->update_counter_ns = s->timer_start_ns; in timer_expire()
125 s->counter = 0; in timer_expire()
128 should_stop |= s->shorts & BIT(i + 8); in timer_expire()
132 update_irq(s); in timer_expire()
135 s->running = false; in timer_expire()
136 timer_del(&s->timer); in timer_expire()
138 rearm_timer(s, now); in timer_expire()
142 static void counter_compare(NRF51TimerState *s) in counter_compare() argument
144 uint32_t counter = s->counter; in counter_compare()
148 if (counter == s->cc[i]) { in counter_compare()
149 s->events_compare[i] = 1; in counter_compare()
151 if (s->shorts & BIT(i)) { in counter_compare()
152 s->counter = 0; in counter_compare()
160 NRF51TimerState *s = NRF51_TIMER(opaque); in nrf51_timer_read() local
165 r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4]; in nrf51_timer_read()
168 r = s->shorts; in nrf51_timer_read()
171 r = s->inten; in nrf51_timer_read()
174 r = s->inten; in nrf51_timer_read()
177 r = s->mode; in nrf51_timer_read()
180 r = s->bitmode; in nrf51_timer_read()
183 r = s->prescaler; in nrf51_timer_read()
186 r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4]; in nrf51_timer_read()
190 "%s: bad read offset 0x%" HWADDR_PRIx "\n", in nrf51_timer_read()
194 trace_nrf51_timer_read(s->id, offset, r, size); in nrf51_timer_read()
202 NRF51TimerState *s = NRF51_TIMER(opaque); in nrf51_timer_write() local
206 trace_nrf51_timer_write(s->id, offset, value, size); in nrf51_timer_write()
210 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) { in nrf51_timer_write()
211 s->running = true; in nrf51_timer_write()
212 s->timer_start_ns = now - ticks_to_ns(s, s->counter); in nrf51_timer_write()
213 s->update_counter_ns = s->timer_start_ns; in nrf51_timer_write()
214 rearm_timer(s, now); in nrf51_timer_write()
220 s->running = false; in nrf51_timer_write()
221 timer_del(&s->timer); in nrf51_timer_write()
225 if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) { in nrf51_timer_write()
226 s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]); in nrf51_timer_write()
227 counter_compare(s); in nrf51_timer_write()
232 s->timer_start_ns = now; in nrf51_timer_write()
233 s->update_counter_ns = s->timer_start_ns; in nrf51_timer_write()
234 s->counter = 0; in nrf51_timer_write()
235 if (s->running) { in nrf51_timer_write()
236 rearm_timer(s, now); in nrf51_timer_write()
242 if (s->running) { in nrf51_timer_write()
243 timer_expire(s); /* update counter and all state */ in nrf51_timer_write()
246 idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4; in nrf51_timer_write()
247 s->cc[idx] = s->counter; in nrf51_timer_write()
248 trace_nrf51_timer_set_count(s->id, idx, s->counter); in nrf51_timer_write()
253 s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0; in nrf51_timer_write()
255 if (s->running) { in nrf51_timer_write()
256 timer_expire(s); /* update counter and all state */ in nrf51_timer_write()
261 s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK; in nrf51_timer_write()
264 s->inten |= value & NRF51_TIMER_REG_INTEN_MASK; in nrf51_timer_write()
267 s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK); in nrf51_timer_write()
270 s->mode = value; in nrf51_timer_write()
273 if (s->mode == NRF51_TIMER_TIMER && s->running) { in nrf51_timer_write()
275 "%s: erroneous change of BITMODE while timer is running\n", in nrf51_timer_write()
278 s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK; in nrf51_timer_write()
281 if (s->mode == NRF51_TIMER_TIMER && s->running) { in nrf51_timer_write()
283 "%s: erroneous change of PRESCALER while timer is running\n", in nrf51_timer_write()
286 s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK; in nrf51_timer_write()
289 if (s->running) { in nrf51_timer_write()
290 timer_expire(s); /* update counter */ in nrf51_timer_write()
293 idx = (offset - NRF51_TIMER_REG_CC0) / 4; in nrf51_timer_write()
294 s->cc[idx] = value % BIT(bitwidths[s->bitmode]); in nrf51_timer_write()
296 if (s->running) { in nrf51_timer_write()
297 rearm_timer(s, now); in nrf51_timer_write()
302 "%s: bad write offset 0x%" HWADDR_PRIx "\n", in nrf51_timer_write()
306 update_irq(s); in nrf51_timer_write()
319 NRF51TimerState *s = NRF51_TIMER(obj); in nrf51_timer_init() local
322 memory_region_init_io(&s->iomem, obj, &rng_ops, s, in nrf51_timer_init()
324 sysbus_init_mmio(sbd, &s->iomem); in nrf51_timer_init()
325 sysbus_init_irq(sbd, &s->irq); in nrf51_timer_init()
327 timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s); in nrf51_timer_init()
332 NRF51TimerState *s = NRF51_TIMER(dev); in nrf51_timer_reset() local
334 timer_del(&s->timer); in nrf51_timer_reset()
335 s->timer_start_ns = 0x00; in nrf51_timer_reset()
336 s->update_counter_ns = 0x00; in nrf51_timer_reset()
337 s->counter = 0x00; in nrf51_timer_reset()
338 s->running = false; in nrf51_timer_reset()
340 memset(s->events_compare, 0x00, sizeof(s->events_compare)); in nrf51_timer_reset()
341 memset(s->cc, 0x00, sizeof(s->cc)); in nrf51_timer_reset()
343 s->shorts = 0x00; in nrf51_timer_reset()
344 s->inten = 0x00; in nrf51_timer_reset()
345 s->mode = 0x00; in nrf51_timer_reset()
346 s->bitmode = 0x00; in nrf51_timer_reset()
347 s->prescaler = 0x00; in nrf51_timer_reset()
352 NRF51TimerState *s = NRF51_TIMER(opaque); in nrf51_timer_post_load() local
354 if (s->running && s->mode == NRF51_TIMER_TIMER) { in nrf51_timer_post_load()
355 timer_expire(s); in nrf51_timer_post_load()
392 dc->vmsd = &vmstate_nrf51_timer; in nrf51_timer_class_init()