rp2040js 0.19.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/clock/clock.d.ts +6 -8
- package/dist/cjs/clock/mock-clock.d.ts +2 -15
- package/dist/cjs/clock/mock-clock.js +4 -46
- package/dist/cjs/clock/simulation-clock.d.ts +26 -0
- package/dist/cjs/clock/simulation-clock.js +97 -0
- package/dist/cjs/cortex-m0-core.d.ts +1 -1
- package/dist/cjs/cortex-m0-core.js +39 -37
- package/dist/cjs/gdb/gdb-connection.d.ts +1 -1
- package/dist/cjs/gdb/gdb-connection.js +2 -2
- package/dist/cjs/gdb/gdb-server.d.ts +3 -3
- package/dist/cjs/gdb/gdb-server.js +12 -11
- package/dist/cjs/gdb/gdb-target.d.ts +7 -0
- package/dist/cjs/gdb/gdb-target.js +2 -0
- package/dist/cjs/gdb/gdb-tcp-server.d.ts +2 -2
- package/dist/cjs/gdb/gdb-tcp-server.js +2 -2
- package/dist/cjs/index.d.ts +4 -3
- package/dist/cjs/index.js +7 -5
- package/dist/cjs/peripherals/adc.d.ts +7 -2
- package/dist/cjs/peripherals/adc.js +12 -8
- package/dist/cjs/peripherals/dma.d.ts +1 -1
- package/dist/cjs/peripherals/dma.js +6 -15
- package/dist/cjs/peripherals/rtc.d.ts +1 -1
- package/dist/cjs/peripherals/rtc.js +3 -3
- package/dist/cjs/peripherals/timer.js +12 -17
- package/dist/cjs/peripherals/usb.d.ts +4 -0
- package/dist/cjs/peripherals/usb.js +56 -50
- package/dist/cjs/rp2040.d.ts +0 -5
- package/dist/cjs/rp2040.js +2 -27
- package/dist/cjs/simulator.d.ts +13 -0
- package/dist/cjs/simulator.js +45 -0
- package/dist/cjs/utils/timer32.d.ts +3 -3
- package/dist/cjs/utils/timer32.js +14 -16
- package/dist/esm/clock/clock.d.ts +6 -8
- package/dist/esm/clock/mock-clock.d.ts +2 -15
- package/dist/esm/clock/mock-clock.js +3 -44
- package/dist/esm/clock/simulation-clock.d.ts +26 -0
- package/dist/esm/clock/simulation-clock.js +92 -0
- package/dist/esm/cortex-m0-core.d.ts +1 -1
- package/dist/esm/cortex-m0-core.js +39 -37
- package/dist/esm/gdb/gdb-connection.d.ts +1 -1
- package/dist/esm/gdb/gdb-connection.js +2 -2
- package/dist/esm/gdb/gdb-server.d.ts +3 -3
- package/dist/esm/gdb/gdb-server.js +12 -11
- package/dist/esm/gdb/gdb-target.d.ts +7 -0
- package/dist/esm/gdb/gdb-target.js +1 -0
- package/dist/esm/gdb/gdb-tcp-server.d.ts +2 -2
- package/dist/esm/gdb/gdb-tcp-server.js +2 -2
- package/dist/esm/index.d.ts +4 -3
- package/dist/esm/index.js +2 -1
- package/dist/esm/peripherals/adc.d.ts +7 -2
- package/dist/esm/peripherals/adc.js +12 -8
- package/dist/esm/peripherals/dma.d.ts +1 -1
- package/dist/esm/peripherals/dma.js +6 -15
- package/dist/esm/peripherals/rtc.d.ts +1 -1
- package/dist/esm/peripherals/rtc.js +3 -3
- package/dist/esm/peripherals/timer.js +12 -17
- package/dist/esm/peripherals/usb.d.ts +4 -0
- package/dist/esm/peripherals/usb.js +56 -50
- package/dist/esm/rp2040.d.ts +0 -5
- package/dist/esm/rp2040.js +2 -27
- package/dist/esm/simulator.d.ts +13 -0
- package/dist/esm/simulator.js +41 -0
- package/dist/esm/utils/timer32.d.ts +3 -3
- package/dist/esm/utils/timer32.js +14 -16
- package/package.json +1 -1
- package/dist/cjs/clock/realtime-clock.d.ts +0 -23
- package/dist/cjs/clock/realtime-clock.js +0 -73
- package/dist/esm/clock/realtime-clock.d.ts +0 -23
- package/dist/esm/clock/realtime-clock.js +0 -68
package/dist/esm/rp2040.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SimulationClock } from './clock/simulation-clock.js';
|
|
2
2
|
import { CortexM0Core } from './cortex-m0-core.js';
|
|
3
3
|
import { GPIOPin } from './gpio-pin.js';
|
|
4
4
|
import { IRQ } from './irq.js';
|
|
@@ -37,7 +37,7 @@ const KB = 1024;
|
|
|
37
37
|
const MB = 1024 * KB;
|
|
38
38
|
const MHz = 1000000;
|
|
39
39
|
export class RP2040 {
|
|
40
|
-
constructor(clock = new
|
|
40
|
+
constructor(clock = new SimulationClock()) {
|
|
41
41
|
this.clock = clock;
|
|
42
42
|
this.bootrom = new Uint32Array(4 * KB);
|
|
43
43
|
this.sram = new Uint8Array(264 * KB);
|
|
@@ -122,9 +122,7 @@ export class RP2040 {
|
|
|
122
122
|
tx: DREQChannel.DREQ_SPI1_TX,
|
|
123
123
|
}),
|
|
124
124
|
];
|
|
125
|
-
this.stopped = true;
|
|
126
125
|
this.logger = new ConsoleLogger(LogLevel.Debug, true);
|
|
127
|
-
this.executeTimer = null;
|
|
128
126
|
this.peripherals = {
|
|
129
127
|
0x18000: new RPSSI(this, 'SSI'),
|
|
130
128
|
0x40000: new RP2040SysInfo(this, 'SYSINFO_BASE'),
|
|
@@ -164,7 +162,6 @@ export class RP2040 {
|
|
|
164
162
|
this.onBreak = (code) => {
|
|
165
163
|
// TODO: raise HardFault exception
|
|
166
164
|
// console.error('Breakpoint!', code);
|
|
167
|
-
this.stopped = true;
|
|
168
165
|
};
|
|
169
166
|
this.reset();
|
|
170
167
|
}
|
|
@@ -339,26 +336,4 @@ export class RP2040 {
|
|
|
339
336
|
step() {
|
|
340
337
|
this.core.executeInstruction();
|
|
341
338
|
}
|
|
342
|
-
execute() {
|
|
343
|
-
this.clock.resume();
|
|
344
|
-
this.executeTimer = null;
|
|
345
|
-
this.stopped = false;
|
|
346
|
-
for (let i = 0; i < 100000 && !this.stopped && !this.core.waiting; i++) {
|
|
347
|
-
this.core.executeInstruction();
|
|
348
|
-
}
|
|
349
|
-
if (!this.stopped) {
|
|
350
|
-
this.executeTimer = setTimeout(() => this.execute(), 0);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
stop() {
|
|
354
|
-
this.stopped = true;
|
|
355
|
-
if (this.executeTimer != null) {
|
|
356
|
-
clearTimeout(this.executeTimer);
|
|
357
|
-
this.executeTimer = null;
|
|
358
|
-
}
|
|
359
|
-
this.clock.pause();
|
|
360
|
-
}
|
|
361
|
-
get executing() {
|
|
362
|
-
return !this.stopped;
|
|
363
|
-
}
|
|
364
339
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SimulationClock } from './clock/simulation-clock.js';
|
|
2
|
+
import { IGDBTarget } from './gdb/gdb-target.js';
|
|
3
|
+
import { RP2040 } from './rp2040.js';
|
|
4
|
+
export declare class Simulator implements IGDBTarget {
|
|
5
|
+
readonly clock: SimulationClock;
|
|
6
|
+
executeTimer: ReturnType<typeof setTimeout> | null;
|
|
7
|
+
rp2040: RP2040;
|
|
8
|
+
stopped: boolean;
|
|
9
|
+
constructor(clock?: SimulationClock);
|
|
10
|
+
execute(): void;
|
|
11
|
+
stop(): void;
|
|
12
|
+
get executing(): boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SimulationClock } from './clock/simulation-clock.js';
|
|
2
|
+
import { RP2040 } from './rp2040.js';
|
|
3
|
+
export class Simulator {
|
|
4
|
+
constructor(clock = new SimulationClock()) {
|
|
5
|
+
this.clock = clock;
|
|
6
|
+
this.executeTimer = null;
|
|
7
|
+
this.stopped = true;
|
|
8
|
+
this.rp2040 = new RP2040(clock);
|
|
9
|
+
this.rp2040.onBreak = () => this.stop();
|
|
10
|
+
}
|
|
11
|
+
execute() {
|
|
12
|
+
const { rp2040, clock } = this;
|
|
13
|
+
this.executeTimer = null;
|
|
14
|
+
this.stopped = false;
|
|
15
|
+
const cycleNanos = 1e9 / 125000000; // 125 MHz
|
|
16
|
+
for (let i = 0; i < 1000000 && !this.stopped; i++) {
|
|
17
|
+
if (rp2040.core.waiting) {
|
|
18
|
+
const { nanosToNextAlarm } = clock;
|
|
19
|
+
clock.tick(nanosToNextAlarm);
|
|
20
|
+
i += nanosToNextAlarm / cycleNanos;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const cycles = rp2040.core.executeInstruction();
|
|
24
|
+
clock.tick(cycles * cycleNanos);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (!this.stopped) {
|
|
28
|
+
this.executeTimer = setTimeout(() => this.execute(), 0);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
stop() {
|
|
32
|
+
this.stopped = true;
|
|
33
|
+
if (this.executeTimer != null) {
|
|
34
|
+
clearTimeout(this.executeTimer);
|
|
35
|
+
this.executeTimer = null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
get executing() {
|
|
39
|
+
return !this.stopped;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -8,7 +8,7 @@ export declare class Timer32 {
|
|
|
8
8
|
readonly clock: IClock;
|
|
9
9
|
private baseFreq;
|
|
10
10
|
private baseValue;
|
|
11
|
-
private
|
|
11
|
+
private baseNanos;
|
|
12
12
|
private topValue;
|
|
13
13
|
private prescalerValue;
|
|
14
14
|
private timerMode;
|
|
@@ -32,7 +32,7 @@ export declare class Timer32 {
|
|
|
32
32
|
set frequency(value: number);
|
|
33
33
|
get prescaler(): number;
|
|
34
34
|
set prescaler(value: number);
|
|
35
|
-
|
|
35
|
+
toNanos(cycles: number): number;
|
|
36
36
|
get enable(): boolean;
|
|
37
37
|
set enable(value: boolean);
|
|
38
38
|
get mode(): TimerMode;
|
|
@@ -44,7 +44,7 @@ export declare class Timer32PeriodicAlarm {
|
|
|
44
44
|
readonly callback: () => void;
|
|
45
45
|
private targetValue;
|
|
46
46
|
private enabled;
|
|
47
|
-
private
|
|
47
|
+
private clockAlarm;
|
|
48
48
|
constructor(timer: Timer32, callback: () => void);
|
|
49
49
|
get enable(): boolean;
|
|
50
50
|
set enable(value: boolean);
|
|
@@ -9,7 +9,7 @@ export class Timer32 {
|
|
|
9
9
|
this.clock = clock;
|
|
10
10
|
this.baseFreq = baseFreq;
|
|
11
11
|
this.baseValue = 0;
|
|
12
|
-
this.
|
|
12
|
+
this.baseNanos = 0;
|
|
13
13
|
this.topValue = 0xffffffff;
|
|
14
14
|
this.prescalerValue = 1;
|
|
15
15
|
this.timerMode = TimerMode.Increment;
|
|
@@ -17,13 +17,13 @@ export class Timer32 {
|
|
|
17
17
|
this.listeners = [];
|
|
18
18
|
}
|
|
19
19
|
reset() {
|
|
20
|
-
this.
|
|
20
|
+
this.baseNanos = this.clock.nanos;
|
|
21
21
|
this.baseValue = 0;
|
|
22
22
|
this.updated();
|
|
23
23
|
}
|
|
24
24
|
set(value, zigZagDown = false) {
|
|
25
25
|
this.baseValue = zigZagDown ? this.topValue * 2 - value : value;
|
|
26
|
-
this.
|
|
26
|
+
this.baseNanos = this.clock.nanos;
|
|
27
27
|
this.updated();
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
@@ -36,12 +36,12 @@ export class Timer32 {
|
|
|
36
36
|
this.baseValue += delta;
|
|
37
37
|
}
|
|
38
38
|
get rawCounter() {
|
|
39
|
-
const { baseFreq, prescalerValue,
|
|
39
|
+
const { baseFreq, prescalerValue, baseNanos, baseValue, enabled, timerMode } = this;
|
|
40
40
|
if (!baseFreq || !prescalerValue || !enabled) {
|
|
41
41
|
return this.baseValue;
|
|
42
42
|
}
|
|
43
43
|
const zigzag = timerMode == TimerMode.ZigZag;
|
|
44
|
-
const ticks = ((this.clock.
|
|
44
|
+
const ticks = ((this.clock.nanos - baseNanos) / 1e9) * (baseFreq / prescalerValue);
|
|
45
45
|
const topModulo = zigzag ? this.topValue * 2 : this.topValue + 1;
|
|
46
46
|
const delta = timerMode == TimerMode.Decrement ? topModulo - (ticks % topModulo) : ticks;
|
|
47
47
|
let currentValue = Math.round(baseValue + delta);
|
|
@@ -70,7 +70,7 @@ export class Timer32 {
|
|
|
70
70
|
}
|
|
71
71
|
set frequency(value) {
|
|
72
72
|
this.baseValue = this.counter;
|
|
73
|
-
this.
|
|
73
|
+
this.baseNanos = this.clock.nanos;
|
|
74
74
|
this.baseFreq = value;
|
|
75
75
|
this.updated();
|
|
76
76
|
}
|
|
@@ -79,14 +79,14 @@ export class Timer32 {
|
|
|
79
79
|
}
|
|
80
80
|
set prescaler(value) {
|
|
81
81
|
this.baseValue = this.counter;
|
|
82
|
-
this.
|
|
82
|
+
this.baseNanos = this.clock.nanos;
|
|
83
83
|
this.enabled = this.prescalerValue !== 0;
|
|
84
84
|
this.prescalerValue = value;
|
|
85
85
|
this.updated();
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
toNanos(cycles) {
|
|
88
88
|
const { baseFreq, prescalerValue } = this;
|
|
89
|
-
return (cycles *
|
|
89
|
+
return (cycles * 1e9) / (baseFreq / prescalerValue);
|
|
90
90
|
}
|
|
91
91
|
get enable() {
|
|
92
92
|
return this.enabled;
|
|
@@ -94,7 +94,7 @@ export class Timer32 {
|
|
|
94
94
|
set enable(value) {
|
|
95
95
|
if (value !== this.enabled) {
|
|
96
96
|
if (value) {
|
|
97
|
-
this.
|
|
97
|
+
this.baseNanos = this.clock.nanos;
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
this.baseValue = this.counter;
|
|
@@ -137,6 +137,7 @@ export class Timer32PeriodicAlarm {
|
|
|
137
137
|
this.schedule();
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
|
+
this.clockAlarm = this.timer.clock.createAlarm(this.handleAlarm);
|
|
140
141
|
timer.listeners.push(this.update);
|
|
141
142
|
}
|
|
142
143
|
get enable() {
|
|
@@ -191,13 +192,10 @@ export class Timer32PeriodicAlarm {
|
|
|
191
192
|
cycleDelta = top + 1 - cycleDelta;
|
|
192
193
|
}
|
|
193
194
|
const cyclesToAlarm = cycleDelta >>> 0;
|
|
194
|
-
const
|
|
195
|
-
this.
|
|
195
|
+
const nanosToAlarm = timer.toNanos(cyclesToAlarm);
|
|
196
|
+
this.clockAlarm.schedule(nanosToAlarm);
|
|
196
197
|
}
|
|
197
198
|
cancel() {
|
|
198
|
-
|
|
199
|
-
this.timer.clock.deleteTimer(this.clockTimer);
|
|
200
|
-
this.clockTimer = undefined;
|
|
201
|
-
}
|
|
199
|
+
this.clockAlarm.cancel();
|
|
202
200
|
}
|
|
203
201
|
}
|
package/package.json
CHANGED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { IClock, IClockTimer } from './clock.js';
|
|
2
|
-
export declare class ClockTimer implements IClockTimer {
|
|
3
|
-
private micros;
|
|
4
|
-
private callback;
|
|
5
|
-
private jsTimer;
|
|
6
|
-
private timeLeft;
|
|
7
|
-
constructor(micros: number, callback: () => void);
|
|
8
|
-
schedule(currentMicros: number): void;
|
|
9
|
-
unschedule(): void;
|
|
10
|
-
pause(currentMicros: number): void;
|
|
11
|
-
resume(currentMicros: number): void;
|
|
12
|
-
}
|
|
13
|
-
export declare class RealtimeClock implements IClock {
|
|
14
|
-
baseTime: number;
|
|
15
|
-
pauseTime: number;
|
|
16
|
-
paused: boolean;
|
|
17
|
-
timers: Set<ClockTimer>;
|
|
18
|
-
pause(): void;
|
|
19
|
-
resume(): void;
|
|
20
|
-
createTimer(deltaMicros: number, callback: () => void): ClockTimer;
|
|
21
|
-
deleteTimer(timer: ClockTimer): void;
|
|
22
|
-
get micros(): number;
|
|
23
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RealtimeClock = exports.ClockTimer = void 0;
|
|
4
|
-
const time_js_1 = require("../utils/time.js");
|
|
5
|
-
class ClockTimer {
|
|
6
|
-
constructor(micros, callback) {
|
|
7
|
-
this.micros = micros;
|
|
8
|
-
this.callback = callback;
|
|
9
|
-
this.jsTimer = null;
|
|
10
|
-
this.timeLeft = this.micros;
|
|
11
|
-
}
|
|
12
|
-
schedule(currentMicros) {
|
|
13
|
-
this.jsTimer = setTimeout(this.callback, (this.micros - currentMicros) / 1000);
|
|
14
|
-
}
|
|
15
|
-
unschedule() {
|
|
16
|
-
if (this.jsTimer) {
|
|
17
|
-
clearTimeout(this.jsTimer);
|
|
18
|
-
this.jsTimer = null;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
pause(currentMicros) {
|
|
22
|
-
this.timeLeft = this.micros - currentMicros;
|
|
23
|
-
this.unschedule();
|
|
24
|
-
}
|
|
25
|
-
resume(currentMicros) {
|
|
26
|
-
this.micros = currentMicros + this.timeLeft;
|
|
27
|
-
this.schedule(currentMicros);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
exports.ClockTimer = ClockTimer;
|
|
31
|
-
class RealtimeClock {
|
|
32
|
-
constructor() {
|
|
33
|
-
this.baseTime = 0;
|
|
34
|
-
this.pauseTime = 0;
|
|
35
|
-
this.paused = true;
|
|
36
|
-
this.timers = new Set();
|
|
37
|
-
}
|
|
38
|
-
pause() {
|
|
39
|
-
if (!this.paused) {
|
|
40
|
-
for (const timer of this.timers) {
|
|
41
|
-
timer.pause(this.micros);
|
|
42
|
-
}
|
|
43
|
-
this.pauseTime = this.micros;
|
|
44
|
-
this.paused = true;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
resume() {
|
|
48
|
-
if (this.paused) {
|
|
49
|
-
this.baseTime = (0, time_js_1.getCurrentMicroseconds)() - this.pauseTime;
|
|
50
|
-
this.paused = false;
|
|
51
|
-
for (const timer of this.timers) {
|
|
52
|
-
timer.resume(this.micros);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
createTimer(deltaMicros, callback) {
|
|
57
|
-
const timer = new ClockTimer(this.micros + deltaMicros, () => {
|
|
58
|
-
this.timers.delete(timer);
|
|
59
|
-
callback();
|
|
60
|
-
});
|
|
61
|
-
timer.schedule(this.micros);
|
|
62
|
-
this.timers.add(timer);
|
|
63
|
-
return timer;
|
|
64
|
-
}
|
|
65
|
-
deleteTimer(timer) {
|
|
66
|
-
timer.unschedule();
|
|
67
|
-
this.timers.delete(timer);
|
|
68
|
-
}
|
|
69
|
-
get micros() {
|
|
70
|
-
return (0, time_js_1.getCurrentMicroseconds)() - this.baseTime;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
exports.RealtimeClock = RealtimeClock;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { IClock, IClockTimer } from './clock.js';
|
|
2
|
-
export declare class ClockTimer implements IClockTimer {
|
|
3
|
-
private micros;
|
|
4
|
-
private callback;
|
|
5
|
-
private jsTimer;
|
|
6
|
-
private timeLeft;
|
|
7
|
-
constructor(micros: number, callback: () => void);
|
|
8
|
-
schedule(currentMicros: number): void;
|
|
9
|
-
unschedule(): void;
|
|
10
|
-
pause(currentMicros: number): void;
|
|
11
|
-
resume(currentMicros: number): void;
|
|
12
|
-
}
|
|
13
|
-
export declare class RealtimeClock implements IClock {
|
|
14
|
-
baseTime: number;
|
|
15
|
-
pauseTime: number;
|
|
16
|
-
paused: boolean;
|
|
17
|
-
timers: Set<ClockTimer>;
|
|
18
|
-
pause(): void;
|
|
19
|
-
resume(): void;
|
|
20
|
-
createTimer(deltaMicros: number, callback: () => void): ClockTimer;
|
|
21
|
-
deleteTimer(timer: ClockTimer): void;
|
|
22
|
-
get micros(): number;
|
|
23
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { getCurrentMicroseconds } from '../utils/time.js';
|
|
2
|
-
export class ClockTimer {
|
|
3
|
-
constructor(micros, callback) {
|
|
4
|
-
this.micros = micros;
|
|
5
|
-
this.callback = callback;
|
|
6
|
-
this.jsTimer = null;
|
|
7
|
-
this.timeLeft = this.micros;
|
|
8
|
-
}
|
|
9
|
-
schedule(currentMicros) {
|
|
10
|
-
this.jsTimer = setTimeout(this.callback, (this.micros - currentMicros) / 1000);
|
|
11
|
-
}
|
|
12
|
-
unschedule() {
|
|
13
|
-
if (this.jsTimer) {
|
|
14
|
-
clearTimeout(this.jsTimer);
|
|
15
|
-
this.jsTimer = null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
pause(currentMicros) {
|
|
19
|
-
this.timeLeft = this.micros - currentMicros;
|
|
20
|
-
this.unschedule();
|
|
21
|
-
}
|
|
22
|
-
resume(currentMicros) {
|
|
23
|
-
this.micros = currentMicros + this.timeLeft;
|
|
24
|
-
this.schedule(currentMicros);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export class RealtimeClock {
|
|
28
|
-
constructor() {
|
|
29
|
-
this.baseTime = 0;
|
|
30
|
-
this.pauseTime = 0;
|
|
31
|
-
this.paused = true;
|
|
32
|
-
this.timers = new Set();
|
|
33
|
-
}
|
|
34
|
-
pause() {
|
|
35
|
-
if (!this.paused) {
|
|
36
|
-
for (const timer of this.timers) {
|
|
37
|
-
timer.pause(this.micros);
|
|
38
|
-
}
|
|
39
|
-
this.pauseTime = this.micros;
|
|
40
|
-
this.paused = true;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
resume() {
|
|
44
|
-
if (this.paused) {
|
|
45
|
-
this.baseTime = getCurrentMicroseconds() - this.pauseTime;
|
|
46
|
-
this.paused = false;
|
|
47
|
-
for (const timer of this.timers) {
|
|
48
|
-
timer.resume(this.micros);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
createTimer(deltaMicros, callback) {
|
|
53
|
-
const timer = new ClockTimer(this.micros + deltaMicros, () => {
|
|
54
|
-
this.timers.delete(timer);
|
|
55
|
-
callback();
|
|
56
|
-
});
|
|
57
|
-
timer.schedule(this.micros);
|
|
58
|
-
this.timers.add(timer);
|
|
59
|
-
return timer;
|
|
60
|
-
}
|
|
61
|
-
deleteTimer(timer) {
|
|
62
|
-
timer.unschedule();
|
|
63
|
-
this.timers.delete(timer);
|
|
64
|
-
}
|
|
65
|
-
get micros() {
|
|
66
|
-
return getCurrentMicroseconds() - this.baseTime;
|
|
67
|
-
}
|
|
68
|
-
}
|