rp2040js 0.19.3 → 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 +5 -4
- 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 +1 -5
- package/dist/cjs/rp2040.js +12 -31
- 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 +5 -4
- 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 +1 -5
- package/dist/esm/rp2040.js +11 -30
- 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 +7 -7
- 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
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Simulator = void 0;
|
|
4
|
+
const simulation_clock_js_1 = require("./clock/simulation-clock.js");
|
|
5
|
+
const rp2040_js_1 = require("./rp2040.js");
|
|
6
|
+
class Simulator {
|
|
7
|
+
constructor(clock = new simulation_clock_js_1.SimulationClock()) {
|
|
8
|
+
this.clock = clock;
|
|
9
|
+
this.executeTimer = null;
|
|
10
|
+
this.stopped = true;
|
|
11
|
+
this.rp2040 = new rp2040_js_1.RP2040(clock);
|
|
12
|
+
this.rp2040.onBreak = () => this.stop();
|
|
13
|
+
}
|
|
14
|
+
execute() {
|
|
15
|
+
const { rp2040, clock } = this;
|
|
16
|
+
this.executeTimer = null;
|
|
17
|
+
this.stopped = false;
|
|
18
|
+
const cycleNanos = 1e9 / 125000000; // 125 MHz
|
|
19
|
+
for (let i = 0; i < 1000000 && !this.stopped; i++) {
|
|
20
|
+
if (rp2040.core.waiting) {
|
|
21
|
+
const { nanosToNextAlarm } = clock;
|
|
22
|
+
clock.tick(nanosToNextAlarm);
|
|
23
|
+
i += nanosToNextAlarm / cycleNanos;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const cycles = rp2040.core.executeInstruction();
|
|
27
|
+
clock.tick(cycles * cycleNanos);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (!this.stopped) {
|
|
31
|
+
this.executeTimer = setTimeout(() => this.execute(), 0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
stop() {
|
|
35
|
+
this.stopped = true;
|
|
36
|
+
if (this.executeTimer != null) {
|
|
37
|
+
clearTimeout(this.executeTimer);
|
|
38
|
+
this.executeTimer = null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get executing() {
|
|
42
|
+
return !this.stopped;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.Simulator = Simulator;
|
|
@@ -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);
|
|
@@ -12,7 +12,7 @@ class Timer32 {
|
|
|
12
12
|
this.clock = clock;
|
|
13
13
|
this.baseFreq = baseFreq;
|
|
14
14
|
this.baseValue = 0;
|
|
15
|
-
this.
|
|
15
|
+
this.baseNanos = 0;
|
|
16
16
|
this.topValue = 0xffffffff;
|
|
17
17
|
this.prescalerValue = 1;
|
|
18
18
|
this.timerMode = TimerMode.Increment;
|
|
@@ -20,13 +20,13 @@ class Timer32 {
|
|
|
20
20
|
this.listeners = [];
|
|
21
21
|
}
|
|
22
22
|
reset() {
|
|
23
|
-
this.
|
|
23
|
+
this.baseNanos = this.clock.nanos;
|
|
24
24
|
this.baseValue = 0;
|
|
25
25
|
this.updated();
|
|
26
26
|
}
|
|
27
27
|
set(value, zigZagDown = false) {
|
|
28
28
|
this.baseValue = zigZagDown ? this.topValue * 2 - value : value;
|
|
29
|
-
this.
|
|
29
|
+
this.baseNanos = this.clock.nanos;
|
|
30
30
|
this.updated();
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
@@ -39,12 +39,12 @@ class Timer32 {
|
|
|
39
39
|
this.baseValue += delta;
|
|
40
40
|
}
|
|
41
41
|
get rawCounter() {
|
|
42
|
-
const { baseFreq, prescalerValue,
|
|
42
|
+
const { baseFreq, prescalerValue, baseNanos, baseValue, enabled, timerMode } = this;
|
|
43
43
|
if (!baseFreq || !prescalerValue || !enabled) {
|
|
44
44
|
return this.baseValue;
|
|
45
45
|
}
|
|
46
46
|
const zigzag = timerMode == TimerMode.ZigZag;
|
|
47
|
-
const ticks = ((this.clock.
|
|
47
|
+
const ticks = ((this.clock.nanos - baseNanos) / 1e9) * (baseFreq / prescalerValue);
|
|
48
48
|
const topModulo = zigzag ? this.topValue * 2 : this.topValue + 1;
|
|
49
49
|
const delta = timerMode == TimerMode.Decrement ? topModulo - (ticks % topModulo) : ticks;
|
|
50
50
|
let currentValue = Math.round(baseValue + delta);
|
|
@@ -73,7 +73,7 @@ class Timer32 {
|
|
|
73
73
|
}
|
|
74
74
|
set frequency(value) {
|
|
75
75
|
this.baseValue = this.counter;
|
|
76
|
-
this.
|
|
76
|
+
this.baseNanos = this.clock.nanos;
|
|
77
77
|
this.baseFreq = value;
|
|
78
78
|
this.updated();
|
|
79
79
|
}
|
|
@@ -82,14 +82,14 @@ class Timer32 {
|
|
|
82
82
|
}
|
|
83
83
|
set prescaler(value) {
|
|
84
84
|
this.baseValue = this.counter;
|
|
85
|
-
this.
|
|
85
|
+
this.baseNanos = this.clock.nanos;
|
|
86
86
|
this.enabled = this.prescalerValue !== 0;
|
|
87
87
|
this.prescalerValue = value;
|
|
88
88
|
this.updated();
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
toNanos(cycles) {
|
|
91
91
|
const { baseFreq, prescalerValue } = this;
|
|
92
|
-
return (cycles *
|
|
92
|
+
return (cycles * 1e9) / (baseFreq / prescalerValue);
|
|
93
93
|
}
|
|
94
94
|
get enable() {
|
|
95
95
|
return this.enabled;
|
|
@@ -97,7 +97,7 @@ class Timer32 {
|
|
|
97
97
|
set enable(value) {
|
|
98
98
|
if (value !== this.enabled) {
|
|
99
99
|
if (value) {
|
|
100
|
-
this.
|
|
100
|
+
this.baseNanos = this.clock.nanos;
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
103
|
this.baseValue = this.counter;
|
|
@@ -141,6 +141,7 @@ class Timer32PeriodicAlarm {
|
|
|
141
141
|
this.schedule();
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
|
+
this.clockAlarm = this.timer.clock.createAlarm(this.handleAlarm);
|
|
144
145
|
timer.listeners.push(this.update);
|
|
145
146
|
}
|
|
146
147
|
get enable() {
|
|
@@ -195,14 +196,11 @@ class Timer32PeriodicAlarm {
|
|
|
195
196
|
cycleDelta = top + 1 - cycleDelta;
|
|
196
197
|
}
|
|
197
198
|
const cyclesToAlarm = cycleDelta >>> 0;
|
|
198
|
-
const
|
|
199
|
-
this.
|
|
199
|
+
const nanosToAlarm = timer.toNanos(cyclesToAlarm);
|
|
200
|
+
this.clockAlarm.schedule(nanosToAlarm);
|
|
200
201
|
}
|
|
201
202
|
cancel() {
|
|
202
|
-
|
|
203
|
-
this.timer.clock.deleteTimer(this.clockTimer);
|
|
204
|
-
this.clockTimer = undefined;
|
|
205
|
-
}
|
|
203
|
+
this.clockAlarm.cancel();
|
|
206
204
|
}
|
|
207
205
|
}
|
|
208
206
|
exports.Timer32PeriodicAlarm = Timer32PeriodicAlarm;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export type AlarmCallback = () => void;
|
|
2
|
+
export interface IAlarm {
|
|
3
|
+
schedule(deltaNanos: number): void;
|
|
4
|
+
cancel(): void;
|
|
4
5
|
}
|
|
5
6
|
export interface IClock {
|
|
6
|
-
readonly
|
|
7
|
-
|
|
8
|
-
resume(): void;
|
|
9
|
-
createTimer(deltaMicros: number, callback: () => void): IClockTimer;
|
|
10
|
-
deleteTimer(timer: IClockTimer): void;
|
|
7
|
+
readonly nanos: number;
|
|
8
|
+
createAlarm(callback: AlarmCallback): IAlarm;
|
|
11
9
|
}
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class
|
|
3
|
-
readonly micros: number;
|
|
4
|
-
readonly callback: () => void;
|
|
5
|
-
constructor(micros: number, callback: () => void);
|
|
6
|
-
pause(): void;
|
|
7
|
-
resume(): void;
|
|
8
|
-
}
|
|
9
|
-
export declare class MockClock implements IClock {
|
|
10
|
-
micros: number;
|
|
11
|
-
readonly timers: MockClockTimer[];
|
|
12
|
-
pause(): void;
|
|
13
|
-
resume(): void;
|
|
1
|
+
import { SimulationClock } from './simulation-clock.js';
|
|
2
|
+
export declare class MockClock extends SimulationClock {
|
|
14
3
|
advance(deltaMicros: number): void;
|
|
15
|
-
createTimer(deltaMicros: number, callback: () => void): MockClockTimer;
|
|
16
|
-
deleteTimer(timer: IClockTimer): void;
|
|
17
4
|
}
|
|
@@ -1,47 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
this.micros = micros;
|
|
4
|
-
this.callback = callback;
|
|
5
|
-
}
|
|
6
|
-
pause() {
|
|
7
|
-
/* intentionally empty */
|
|
8
|
-
}
|
|
9
|
-
resume() {
|
|
10
|
-
/* intentionally empty */
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
export class MockClock {
|
|
14
|
-
constructor() {
|
|
15
|
-
this.micros = 0;
|
|
16
|
-
this.timers = [];
|
|
17
|
-
}
|
|
18
|
-
pause() {
|
|
19
|
-
/* intentionally empty */
|
|
20
|
-
}
|
|
21
|
-
resume() {
|
|
22
|
-
/* intentionally empty */
|
|
23
|
-
}
|
|
1
|
+
import { SimulationClock } from './simulation-clock.js';
|
|
2
|
+
export class MockClock extends SimulationClock {
|
|
24
3
|
advance(deltaMicros) {
|
|
25
|
-
|
|
26
|
-
const targetTime = this.micros + Math.max(deltaMicros, 0.01);
|
|
27
|
-
while (timers[0] && timers[0].micros <= targetTime) {
|
|
28
|
-
const timer = timers.shift();
|
|
29
|
-
if (timer) {
|
|
30
|
-
this.micros = timer.micros;
|
|
31
|
-
timer.callback();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
createTimer(deltaMicros, callback) {
|
|
36
|
-
const timer = new MockClockTimer(this.micros + deltaMicros, callback);
|
|
37
|
-
this.timers.push(timer);
|
|
38
|
-
this.timers.sort((a, b) => a.micros - b.micros);
|
|
39
|
-
return timer;
|
|
40
|
-
}
|
|
41
|
-
deleteTimer(timer) {
|
|
42
|
-
const timerIndex = this.timers.indexOf(timer);
|
|
43
|
-
if (timerIndex >= 0) {
|
|
44
|
-
this.timers.splice(timerIndex, 1);
|
|
45
|
-
}
|
|
4
|
+
this.tick(this.nanos + deltaMicros * 1000);
|
|
46
5
|
}
|
|
47
6
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AlarmCallback, IAlarm, IClock } from './clock.js';
|
|
2
|
+
type ClockEventCallback = () => void;
|
|
3
|
+
export declare class ClockAlarm implements IAlarm {
|
|
4
|
+
private readonly clock;
|
|
5
|
+
readonly callback: AlarmCallback;
|
|
6
|
+
next: ClockAlarm | null;
|
|
7
|
+
nanos: number;
|
|
8
|
+
scheduled: boolean;
|
|
9
|
+
constructor(clock: SimulationClock, callback: AlarmCallback);
|
|
10
|
+
schedule(deltaNanos: number): void;
|
|
11
|
+
cancel(): void;
|
|
12
|
+
}
|
|
13
|
+
export declare class SimulationClock implements IClock {
|
|
14
|
+
readonly frequency: number;
|
|
15
|
+
private nextAlarm;
|
|
16
|
+
private nanosCounter;
|
|
17
|
+
constructor(frequency?: number);
|
|
18
|
+
get nanos(): number;
|
|
19
|
+
get micros(): number;
|
|
20
|
+
createAlarm(callback: ClockEventCallback): ClockAlarm;
|
|
21
|
+
linkAlarm(nanos: number, alarm: ClockAlarm): ClockAlarm;
|
|
22
|
+
unlinkAlarm(alarm: ClockAlarm): boolean;
|
|
23
|
+
tick(deltaNanos: number): void;
|
|
24
|
+
get nanosToNextAlarm(): number;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export class ClockAlarm {
|
|
2
|
+
constructor(clock, callback) {
|
|
3
|
+
this.clock = clock;
|
|
4
|
+
this.callback = callback;
|
|
5
|
+
this.next = null;
|
|
6
|
+
this.nanos = 0;
|
|
7
|
+
this.scheduled = false;
|
|
8
|
+
}
|
|
9
|
+
schedule(deltaNanos) {
|
|
10
|
+
if (this.scheduled) {
|
|
11
|
+
this.cancel();
|
|
12
|
+
}
|
|
13
|
+
this.clock.linkAlarm(deltaNanos, this);
|
|
14
|
+
}
|
|
15
|
+
cancel() {
|
|
16
|
+
this.clock.unlinkAlarm(this);
|
|
17
|
+
this.scheduled = false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class SimulationClock {
|
|
21
|
+
constructor(frequency = 125e6) {
|
|
22
|
+
this.frequency = frequency;
|
|
23
|
+
this.nextAlarm = null;
|
|
24
|
+
this.nanosCounter = 0;
|
|
25
|
+
}
|
|
26
|
+
get nanos() {
|
|
27
|
+
return this.nanosCounter;
|
|
28
|
+
}
|
|
29
|
+
get micros() {
|
|
30
|
+
return this.nanos / 1000;
|
|
31
|
+
}
|
|
32
|
+
createAlarm(callback) {
|
|
33
|
+
return new ClockAlarm(this, callback);
|
|
34
|
+
}
|
|
35
|
+
linkAlarm(nanos, alarm) {
|
|
36
|
+
alarm.nanos = this.nanos + nanos;
|
|
37
|
+
let alarmListItem = this.nextAlarm;
|
|
38
|
+
let lastItem = null;
|
|
39
|
+
while (alarmListItem && alarmListItem.nanos < alarm.nanos) {
|
|
40
|
+
lastItem = alarmListItem;
|
|
41
|
+
alarmListItem = alarmListItem.next;
|
|
42
|
+
}
|
|
43
|
+
if (lastItem) {
|
|
44
|
+
lastItem.next = alarm;
|
|
45
|
+
alarm.next = alarmListItem;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.nextAlarm = alarm;
|
|
49
|
+
alarm.next = alarmListItem;
|
|
50
|
+
}
|
|
51
|
+
alarm.scheduled = true;
|
|
52
|
+
return alarm;
|
|
53
|
+
}
|
|
54
|
+
unlinkAlarm(alarm) {
|
|
55
|
+
let alarmListItem = this.nextAlarm;
|
|
56
|
+
if (!alarmListItem) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
let lastItem = null;
|
|
60
|
+
while (alarmListItem) {
|
|
61
|
+
if (alarmListItem === alarm) {
|
|
62
|
+
if (lastItem) {
|
|
63
|
+
lastItem.next = alarmListItem.next;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.nextAlarm = alarmListItem.next;
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
lastItem = alarmListItem;
|
|
71
|
+
alarmListItem = alarmListItem.next;
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
tick(deltaNanos) {
|
|
76
|
+
const targetNanos = this.nanosCounter + deltaNanos;
|
|
77
|
+
let alarm = this.nextAlarm;
|
|
78
|
+
while (alarm && alarm.nanos <= targetNanos) {
|
|
79
|
+
this.nextAlarm = alarm.next;
|
|
80
|
+
this.nanosCounter = alarm.nanos;
|
|
81
|
+
alarm.callback();
|
|
82
|
+
alarm = this.nextAlarm;
|
|
83
|
+
}
|
|
84
|
+
this.nanosCounter = targetNanos;
|
|
85
|
+
}
|
|
86
|
+
get nanosToNextAlarm() {
|
|
87
|
+
if (this.nextAlarm) {
|
|
88
|
+
return this.nextAlarm.nanos - this.nanos;
|
|
89
|
+
}
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
}
|