rp2040js 1.1.0 → 1.2.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/README.md +3 -1
- package/dist/cjs/peripherals/pio.d.ts +2 -0
- package/dist/cjs/peripherals/pio.js +13 -4
- package/dist/cjs/peripherals/xosc.d.ts +13 -0
- package/dist/cjs/peripherals/xosc.js +123 -0
- package/dist/cjs/rp2040.js +2 -1
- package/dist/esm/peripherals/pio.d.ts +2 -0
- package/dist/esm/peripherals/pio.js +13 -4
- package/dist/esm/peripherals/xosc.d.ts +13 -0
- package/dist/esm/peripherals/xosc.js +119 -0
- package/dist/esm/rp2040.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
  
|
|
2
|
+
|
|
1
3
|
# rp2040js
|
|
2
4
|
|
|
3
5
|
Raspberry Pi Pico Emulator for the [Wokwi Simulation Platform](https://wokwi.com). It blinks, runs Arduino code, and even the MicroPython REPL!
|
|
@@ -58,7 +60,7 @@ A GDB server on port 3333 can be enabled by specifying the `--gdb` flag:
|
|
|
58
60
|
npm run start:micropython -- --gdb
|
|
59
61
|
```
|
|
60
62
|
|
|
61
|
-
For using the MicroPython demo code in tests, the `--expect-text` can come handy: it will look for the given text in the serial output and exit with code 0 if found, or 1 if not found. You can find an example in [the MicroPython CI test](
|
|
63
|
+
For using the MicroPython demo code in tests, the `--expect-text` can come handy: it will look for the given text in the serial output and exit with code 0 if found, or 1 if not found. You can find an example in [the MicroPython CI test](./.github/workflows/ci-micropython.yml).
|
|
62
64
|
|
|
63
65
|
#### Filesystem support
|
|
64
66
|
|
|
@@ -169,6 +169,7 @@ class StateMachine {
|
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
171
|
this.txFIFO.push(value);
|
|
172
|
+
this.pio.txStall &= ~(FDEBUG_TXSTALL << this.index);
|
|
172
173
|
this.updateDMATx();
|
|
173
174
|
this.checkWait();
|
|
174
175
|
if (this.txFIFO.full) {
|
|
@@ -181,6 +182,7 @@ class StateMachine {
|
|
|
181
182
|
return 0;
|
|
182
183
|
}
|
|
183
184
|
const result = this.rxFIFO.pull();
|
|
185
|
+
this.pio.rxStall &= ~(FDEBUG_RXSTALL << this.index);
|
|
184
186
|
this.updateDMARx();
|
|
185
187
|
this.checkWait();
|
|
186
188
|
if (this.rxFIFO.empty) {
|
|
@@ -440,7 +442,8 @@ class StateMachine {
|
|
|
440
442
|
this.pio.checkInterrupts();
|
|
441
443
|
}
|
|
442
444
|
else {
|
|
443
|
-
this.pio.
|
|
445
|
+
this.pio.rxStall |= FDEBUG_RXSTALL << this.index;
|
|
446
|
+
this.pio.fdebug |= this.pio.rxStall;
|
|
444
447
|
this.wait(WaitType.rxFIFO, false, this.inputShiftReg);
|
|
445
448
|
}
|
|
446
449
|
this.inputShiftCount = 0;
|
|
@@ -458,7 +461,8 @@ class StateMachine {
|
|
|
458
461
|
this.pio.checkInterrupts();
|
|
459
462
|
}
|
|
460
463
|
else {
|
|
461
|
-
this.pio.
|
|
464
|
+
this.pio.txStall |= FDEBUG_TXSTALL << this.index;
|
|
465
|
+
this.pio.fdebug |= this.pio.txStall;
|
|
462
466
|
this.wait(WaitType.Out, false, arg);
|
|
463
467
|
}
|
|
464
468
|
}
|
|
@@ -488,7 +492,8 @@ class StateMachine {
|
|
|
488
492
|
this.pio.checkInterrupts();
|
|
489
493
|
}
|
|
490
494
|
else {
|
|
491
|
-
this.pio.
|
|
495
|
+
this.pio.txStall |= FDEBUG_TXSTALL << this.index;
|
|
496
|
+
this.pio.fdebug |= this.pio.txStall;
|
|
492
497
|
if (block) {
|
|
493
498
|
this.wait(WaitType.txFIFO, false, 0);
|
|
494
499
|
}
|
|
@@ -511,7 +516,8 @@ class StateMachine {
|
|
|
511
516
|
this.pio.checkInterrupts();
|
|
512
517
|
}
|
|
513
518
|
else {
|
|
514
|
-
this.pio.
|
|
519
|
+
this.pio.rxStall |= FDEBUG_RXSTALL << this.index;
|
|
520
|
+
this.pio.fdebug |= this.pio.rxStall;
|
|
515
521
|
if (block) {
|
|
516
522
|
this.wait(WaitType.rxFIFO, false, this.inputShiftReg);
|
|
517
523
|
}
|
|
@@ -831,6 +837,8 @@ class RPPIO extends peripheral_js_1.BasePeripheral {
|
|
|
831
837
|
];
|
|
832
838
|
this.stopped = true;
|
|
833
839
|
this.fdebug = 0;
|
|
840
|
+
this.txStall = 0;
|
|
841
|
+
this.rxStall = 0;
|
|
834
842
|
this.inputSyncBypass = 0;
|
|
835
843
|
this.irq = 0;
|
|
836
844
|
this.pinValues = 0;
|
|
@@ -977,6 +985,7 @@ class RPPIO extends peripheral_js_1.BasePeripheral {
|
|
|
977
985
|
}
|
|
978
986
|
case FDEBUG:
|
|
979
987
|
this.fdebug &= ~this.rawWriteValue;
|
|
988
|
+
this.fdebug |= this.txStall | this.rxStall;
|
|
980
989
|
break;
|
|
981
990
|
case TXF0:
|
|
982
991
|
this.machines[0].writeFIFO(value);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BasePeripheral, Peripheral } from './peripheral.js';
|
|
2
|
+
export declare class RPXOSC extends BasePeripheral implements Peripheral {
|
|
3
|
+
private ctrl;
|
|
4
|
+
private status;
|
|
5
|
+
private dormant;
|
|
6
|
+
private startup;
|
|
7
|
+
private count;
|
|
8
|
+
private enabled;
|
|
9
|
+
private stable;
|
|
10
|
+
private isDormant;
|
|
11
|
+
readUint32(offset: number): number;
|
|
12
|
+
writeUint32(offset: number, value: number): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RPXOSC = void 0;
|
|
4
|
+
const peripheral_js_1 = require("./peripheral.js");
|
|
5
|
+
// XOSC register offsets
|
|
6
|
+
const XOSC_CTRL = 0x00;
|
|
7
|
+
const XOSC_STATUS = 0x04;
|
|
8
|
+
const XOSC_DORMANT = 0x08;
|
|
9
|
+
const XOSC_STARTUP = 0x0c;
|
|
10
|
+
const XOSC_COUNT = 0x1c;
|
|
11
|
+
// CTRL register bits
|
|
12
|
+
const CTRL_ENABLE_LSB = 12;
|
|
13
|
+
const CTRL_ENABLE_BITS = 0x00fff000;
|
|
14
|
+
const CTRL_FREQ_RANGE_BITS = 0x00000fff;
|
|
15
|
+
// CTRL ENABLE values
|
|
16
|
+
const CTRL_ENABLE_DISABLE = 0xd1e;
|
|
17
|
+
const CTRL_ENABLE_ENABLE = 0xfab;
|
|
18
|
+
// STATUS register bits
|
|
19
|
+
const STATUS_STABLE = 0x80000000; // bit 31
|
|
20
|
+
const STATUS_BADWRITE = 0x01000000; // bit 24
|
|
21
|
+
const STATUS_ENABLED = 0x00001000; // bit 12
|
|
22
|
+
const STATUS_FREQ_RANGE_BITS = 0x00000003;
|
|
23
|
+
// DORMANT register values
|
|
24
|
+
const DORMANT_VALUE = 0x636f6d61; // "coma" in ASCII
|
|
25
|
+
const WAKE_VALUE = 0x77616b65; // "wake" in ASCII
|
|
26
|
+
// STARTUP register bits
|
|
27
|
+
const STARTUP_X4 = 0x00100000; // bit 20
|
|
28
|
+
const STARTUP_DELAY_BITS = 0x00003fff;
|
|
29
|
+
class RPXOSC extends peripheral_js_1.BasePeripheral {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
this.ctrl = 0;
|
|
33
|
+
this.status = 0;
|
|
34
|
+
this.dormant = 0;
|
|
35
|
+
this.startup = 0;
|
|
36
|
+
this.count = 0;
|
|
37
|
+
this.enabled = false;
|
|
38
|
+
this.stable = false;
|
|
39
|
+
this.isDormant = false;
|
|
40
|
+
}
|
|
41
|
+
readUint32(offset) {
|
|
42
|
+
switch (offset) {
|
|
43
|
+
case XOSC_CTRL:
|
|
44
|
+
return this.ctrl;
|
|
45
|
+
case XOSC_STATUS: {
|
|
46
|
+
let status = this.status;
|
|
47
|
+
if (this.stable) {
|
|
48
|
+
status |= STATUS_STABLE;
|
|
49
|
+
}
|
|
50
|
+
if (this.enabled) {
|
|
51
|
+
status |= STATUS_ENABLED;
|
|
52
|
+
}
|
|
53
|
+
return status;
|
|
54
|
+
}
|
|
55
|
+
case XOSC_DORMANT:
|
|
56
|
+
return this.dormant;
|
|
57
|
+
case XOSC_STARTUP:
|
|
58
|
+
return this.startup;
|
|
59
|
+
case XOSC_COUNT:
|
|
60
|
+
return this.count;
|
|
61
|
+
}
|
|
62
|
+
return super.readUint32(offset);
|
|
63
|
+
}
|
|
64
|
+
writeUint32(offset, value) {
|
|
65
|
+
switch (offset) {
|
|
66
|
+
case XOSC_CTRL: {
|
|
67
|
+
this.ctrl = value;
|
|
68
|
+
const enableValue = (value & CTRL_ENABLE_BITS) >>> CTRL_ENABLE_LSB;
|
|
69
|
+
const freqRange = value & CTRL_FREQ_RANGE_BITS;
|
|
70
|
+
void freqRange; // Currently unused, but could be logged or validated
|
|
71
|
+
if (enableValue === CTRL_ENABLE_ENABLE) {
|
|
72
|
+
if (!this.isDormant) {
|
|
73
|
+
this.enabled = true;
|
|
74
|
+
// For simplicity, become stable immediately
|
|
75
|
+
// In real hardware, this would take time based on STARTUP register
|
|
76
|
+
this.stable = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (enableValue === CTRL_ENABLE_DISABLE) {
|
|
80
|
+
this.enabled = false;
|
|
81
|
+
this.stable = false;
|
|
82
|
+
}
|
|
83
|
+
else if (enableValue !== 0) {
|
|
84
|
+
// Invalid write to ENABLE field
|
|
85
|
+
this.status |= STATUS_BADWRITE;
|
|
86
|
+
this.warn(`Invalid ENABLE value written: 0x${enableValue.toString(16)}`);
|
|
87
|
+
}
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case XOSC_STATUS:
|
|
91
|
+
// Clear BADWRITE bit if written as 1 (write-1-to-clear)
|
|
92
|
+
if (value & STATUS_BADWRITE) {
|
|
93
|
+
this.status &= ~STATUS_BADWRITE;
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
case XOSC_DORMANT:
|
|
97
|
+
if (value === DORMANT_VALUE) {
|
|
98
|
+
this.isDormant = true;
|
|
99
|
+
this.stable = false;
|
|
100
|
+
}
|
|
101
|
+
else if (value === WAKE_VALUE) {
|
|
102
|
+
this.isDormant = false;
|
|
103
|
+
if (this.enabled) {
|
|
104
|
+
this.stable = true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.dormant = value;
|
|
108
|
+
break;
|
|
109
|
+
case XOSC_STARTUP:
|
|
110
|
+
this.startup = value & (STARTUP_X4 | STARTUP_DELAY_BITS);
|
|
111
|
+
break;
|
|
112
|
+
case XOSC_COUNT:
|
|
113
|
+
// Writing to COUNT starts the countdown
|
|
114
|
+
this.count = value & 0xff;
|
|
115
|
+
// For simplicity, we don't actually implement the countdown
|
|
116
|
+
// In real hardware, this would decrement at the XOSC frequency
|
|
117
|
+
break;
|
|
118
|
+
default:
|
|
119
|
+
super.writeUint32(offset, value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.RPXOSC = RPXOSC;
|
package/dist/cjs/rp2040.js
CHANGED
|
@@ -27,6 +27,7 @@ const timer_js_1 = require("./peripherals/timer.js");
|
|
|
27
27
|
const uart_js_1 = require("./peripherals/uart.js");
|
|
28
28
|
const usb_js_1 = require("./peripherals/usb.js");
|
|
29
29
|
const watchdog_js_1 = require("./peripherals/watchdog.js");
|
|
30
|
+
const xosc_js_1 = require("./peripherals/xosc.js");
|
|
30
31
|
const sio_js_1 = require("./sio.js");
|
|
31
32
|
const logging_js_1 = require("./utils/logging.js");
|
|
32
33
|
exports.FLASH_START_ADDRESS = 0x10000000;
|
|
@@ -137,7 +138,7 @@ class RP2040 {
|
|
|
137
138
|
0x40018: new peripheral_js_1.UnimplementedPeripheral(this, 'IO_QSPI_BASE'),
|
|
138
139
|
0x4001c: new pads_js_1.RPPADS(this, 'PADS_BANK0_BASE', 'bank0'),
|
|
139
140
|
0x40020: new pads_js_1.RPPADS(this, 'PADS_QSPI_BASE', 'qspi'),
|
|
140
|
-
0x40024: new
|
|
141
|
+
0x40024: new xosc_js_1.RPXOSC(this, 'XOSC_BASE'),
|
|
141
142
|
0x40028: new peripheral_js_1.UnimplementedPeripheral(this, 'PLL_SYS_BASE'),
|
|
142
143
|
0x4002c: new peripheral_js_1.UnimplementedPeripheral(this, 'PLL_USB_BASE'),
|
|
143
144
|
0x40030: new busctrl_js_1.RPBUSCTRL(this, 'BUSCTRL_BASE'),
|
|
@@ -166,6 +166,7 @@ export class StateMachine {
|
|
|
166
166
|
return;
|
|
167
167
|
}
|
|
168
168
|
this.txFIFO.push(value);
|
|
169
|
+
this.pio.txStall &= ~(FDEBUG_TXSTALL << this.index);
|
|
169
170
|
this.updateDMATx();
|
|
170
171
|
this.checkWait();
|
|
171
172
|
if (this.txFIFO.full) {
|
|
@@ -178,6 +179,7 @@ export class StateMachine {
|
|
|
178
179
|
return 0;
|
|
179
180
|
}
|
|
180
181
|
const result = this.rxFIFO.pull();
|
|
182
|
+
this.pio.rxStall &= ~(FDEBUG_RXSTALL << this.index);
|
|
181
183
|
this.updateDMARx();
|
|
182
184
|
this.checkWait();
|
|
183
185
|
if (this.rxFIFO.empty) {
|
|
@@ -437,7 +439,8 @@ export class StateMachine {
|
|
|
437
439
|
this.pio.checkInterrupts();
|
|
438
440
|
}
|
|
439
441
|
else {
|
|
440
|
-
this.pio.
|
|
442
|
+
this.pio.rxStall |= FDEBUG_RXSTALL << this.index;
|
|
443
|
+
this.pio.fdebug |= this.pio.rxStall;
|
|
441
444
|
this.wait(WaitType.rxFIFO, false, this.inputShiftReg);
|
|
442
445
|
}
|
|
443
446
|
this.inputShiftCount = 0;
|
|
@@ -455,7 +458,8 @@ export class StateMachine {
|
|
|
455
458
|
this.pio.checkInterrupts();
|
|
456
459
|
}
|
|
457
460
|
else {
|
|
458
|
-
this.pio.
|
|
461
|
+
this.pio.txStall |= FDEBUG_TXSTALL << this.index;
|
|
462
|
+
this.pio.fdebug |= this.pio.txStall;
|
|
459
463
|
this.wait(WaitType.Out, false, arg);
|
|
460
464
|
}
|
|
461
465
|
}
|
|
@@ -485,7 +489,8 @@ export class StateMachine {
|
|
|
485
489
|
this.pio.checkInterrupts();
|
|
486
490
|
}
|
|
487
491
|
else {
|
|
488
|
-
this.pio.
|
|
492
|
+
this.pio.txStall |= FDEBUG_TXSTALL << this.index;
|
|
493
|
+
this.pio.fdebug |= this.pio.txStall;
|
|
489
494
|
if (block) {
|
|
490
495
|
this.wait(WaitType.txFIFO, false, 0);
|
|
491
496
|
}
|
|
@@ -508,7 +513,8 @@ export class StateMachine {
|
|
|
508
513
|
this.pio.checkInterrupts();
|
|
509
514
|
}
|
|
510
515
|
else {
|
|
511
|
-
this.pio.
|
|
516
|
+
this.pio.rxStall |= FDEBUG_RXSTALL << this.index;
|
|
517
|
+
this.pio.fdebug |= this.pio.rxStall;
|
|
512
518
|
if (block) {
|
|
513
519
|
this.wait(WaitType.rxFIFO, false, this.inputShiftReg);
|
|
514
520
|
}
|
|
@@ -827,6 +833,8 @@ export class RPPIO extends BasePeripheral {
|
|
|
827
833
|
];
|
|
828
834
|
this.stopped = true;
|
|
829
835
|
this.fdebug = 0;
|
|
836
|
+
this.txStall = 0;
|
|
837
|
+
this.rxStall = 0;
|
|
830
838
|
this.inputSyncBypass = 0;
|
|
831
839
|
this.irq = 0;
|
|
832
840
|
this.pinValues = 0;
|
|
@@ -973,6 +981,7 @@ export class RPPIO extends BasePeripheral {
|
|
|
973
981
|
}
|
|
974
982
|
case FDEBUG:
|
|
975
983
|
this.fdebug &= ~this.rawWriteValue;
|
|
984
|
+
this.fdebug |= this.txStall | this.rxStall;
|
|
976
985
|
break;
|
|
977
986
|
case TXF0:
|
|
978
987
|
this.machines[0].writeFIFO(value);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BasePeripheral, Peripheral } from './peripheral.js';
|
|
2
|
+
export declare class RPXOSC extends BasePeripheral implements Peripheral {
|
|
3
|
+
private ctrl;
|
|
4
|
+
private status;
|
|
5
|
+
private dormant;
|
|
6
|
+
private startup;
|
|
7
|
+
private count;
|
|
8
|
+
private enabled;
|
|
9
|
+
private stable;
|
|
10
|
+
private isDormant;
|
|
11
|
+
readUint32(offset: number): number;
|
|
12
|
+
writeUint32(offset: number, value: number): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { BasePeripheral } from './peripheral.js';
|
|
2
|
+
// XOSC register offsets
|
|
3
|
+
const XOSC_CTRL = 0x00;
|
|
4
|
+
const XOSC_STATUS = 0x04;
|
|
5
|
+
const XOSC_DORMANT = 0x08;
|
|
6
|
+
const XOSC_STARTUP = 0x0c;
|
|
7
|
+
const XOSC_COUNT = 0x1c;
|
|
8
|
+
// CTRL register bits
|
|
9
|
+
const CTRL_ENABLE_LSB = 12;
|
|
10
|
+
const CTRL_ENABLE_BITS = 0x00fff000;
|
|
11
|
+
const CTRL_FREQ_RANGE_BITS = 0x00000fff;
|
|
12
|
+
// CTRL ENABLE values
|
|
13
|
+
const CTRL_ENABLE_DISABLE = 0xd1e;
|
|
14
|
+
const CTRL_ENABLE_ENABLE = 0xfab;
|
|
15
|
+
// STATUS register bits
|
|
16
|
+
const STATUS_STABLE = 0x80000000; // bit 31
|
|
17
|
+
const STATUS_BADWRITE = 0x01000000; // bit 24
|
|
18
|
+
const STATUS_ENABLED = 0x00001000; // bit 12
|
|
19
|
+
const STATUS_FREQ_RANGE_BITS = 0x00000003;
|
|
20
|
+
// DORMANT register values
|
|
21
|
+
const DORMANT_VALUE = 0x636f6d61; // "coma" in ASCII
|
|
22
|
+
const WAKE_VALUE = 0x77616b65; // "wake" in ASCII
|
|
23
|
+
// STARTUP register bits
|
|
24
|
+
const STARTUP_X4 = 0x00100000; // bit 20
|
|
25
|
+
const STARTUP_DELAY_BITS = 0x00003fff;
|
|
26
|
+
export class RPXOSC extends BasePeripheral {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(...arguments);
|
|
29
|
+
this.ctrl = 0;
|
|
30
|
+
this.status = 0;
|
|
31
|
+
this.dormant = 0;
|
|
32
|
+
this.startup = 0;
|
|
33
|
+
this.count = 0;
|
|
34
|
+
this.enabled = false;
|
|
35
|
+
this.stable = false;
|
|
36
|
+
this.isDormant = false;
|
|
37
|
+
}
|
|
38
|
+
readUint32(offset) {
|
|
39
|
+
switch (offset) {
|
|
40
|
+
case XOSC_CTRL:
|
|
41
|
+
return this.ctrl;
|
|
42
|
+
case XOSC_STATUS: {
|
|
43
|
+
let status = this.status;
|
|
44
|
+
if (this.stable) {
|
|
45
|
+
status |= STATUS_STABLE;
|
|
46
|
+
}
|
|
47
|
+
if (this.enabled) {
|
|
48
|
+
status |= STATUS_ENABLED;
|
|
49
|
+
}
|
|
50
|
+
return status;
|
|
51
|
+
}
|
|
52
|
+
case XOSC_DORMANT:
|
|
53
|
+
return this.dormant;
|
|
54
|
+
case XOSC_STARTUP:
|
|
55
|
+
return this.startup;
|
|
56
|
+
case XOSC_COUNT:
|
|
57
|
+
return this.count;
|
|
58
|
+
}
|
|
59
|
+
return super.readUint32(offset);
|
|
60
|
+
}
|
|
61
|
+
writeUint32(offset, value) {
|
|
62
|
+
switch (offset) {
|
|
63
|
+
case XOSC_CTRL: {
|
|
64
|
+
this.ctrl = value;
|
|
65
|
+
const enableValue = (value & CTRL_ENABLE_BITS) >>> CTRL_ENABLE_LSB;
|
|
66
|
+
const freqRange = value & CTRL_FREQ_RANGE_BITS;
|
|
67
|
+
void freqRange; // Currently unused, but could be logged or validated
|
|
68
|
+
if (enableValue === CTRL_ENABLE_ENABLE) {
|
|
69
|
+
if (!this.isDormant) {
|
|
70
|
+
this.enabled = true;
|
|
71
|
+
// For simplicity, become stable immediately
|
|
72
|
+
// In real hardware, this would take time based on STARTUP register
|
|
73
|
+
this.stable = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (enableValue === CTRL_ENABLE_DISABLE) {
|
|
77
|
+
this.enabled = false;
|
|
78
|
+
this.stable = false;
|
|
79
|
+
}
|
|
80
|
+
else if (enableValue !== 0) {
|
|
81
|
+
// Invalid write to ENABLE field
|
|
82
|
+
this.status |= STATUS_BADWRITE;
|
|
83
|
+
this.warn(`Invalid ENABLE value written: 0x${enableValue.toString(16)}`);
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case XOSC_STATUS:
|
|
88
|
+
// Clear BADWRITE bit if written as 1 (write-1-to-clear)
|
|
89
|
+
if (value & STATUS_BADWRITE) {
|
|
90
|
+
this.status &= ~STATUS_BADWRITE;
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case XOSC_DORMANT:
|
|
94
|
+
if (value === DORMANT_VALUE) {
|
|
95
|
+
this.isDormant = true;
|
|
96
|
+
this.stable = false;
|
|
97
|
+
}
|
|
98
|
+
else if (value === WAKE_VALUE) {
|
|
99
|
+
this.isDormant = false;
|
|
100
|
+
if (this.enabled) {
|
|
101
|
+
this.stable = true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.dormant = value;
|
|
105
|
+
break;
|
|
106
|
+
case XOSC_STARTUP:
|
|
107
|
+
this.startup = value & (STARTUP_X4 | STARTUP_DELAY_BITS);
|
|
108
|
+
break;
|
|
109
|
+
case XOSC_COUNT:
|
|
110
|
+
// Writing to COUNT starts the countdown
|
|
111
|
+
this.count = value & 0xff;
|
|
112
|
+
// For simplicity, we don't actually implement the countdown
|
|
113
|
+
// In real hardware, this would decrement at the XOSC frequency
|
|
114
|
+
break;
|
|
115
|
+
default:
|
|
116
|
+
super.writeUint32(offset, value);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
package/dist/esm/rp2040.js
CHANGED
|
@@ -24,6 +24,7 @@ import { RPTimer } from './peripherals/timer.js';
|
|
|
24
24
|
import { RPUART } from './peripherals/uart.js';
|
|
25
25
|
import { RPUSBController } from './peripherals/usb.js';
|
|
26
26
|
import { RPWatchdog } from './peripherals/watchdog.js';
|
|
27
|
+
import { RPXOSC } from './peripherals/xosc.js';
|
|
27
28
|
import { RPSIO } from './sio.js';
|
|
28
29
|
import { ConsoleLogger, LogLevel } from './utils/logging.js';
|
|
29
30
|
export const FLASH_START_ADDRESS = 0x10000000;
|
|
@@ -134,7 +135,7 @@ export class RP2040 {
|
|
|
134
135
|
0x40018: new UnimplementedPeripheral(this, 'IO_QSPI_BASE'),
|
|
135
136
|
0x4001c: new RPPADS(this, 'PADS_BANK0_BASE', 'bank0'),
|
|
136
137
|
0x40020: new RPPADS(this, 'PADS_QSPI_BASE', 'qspi'),
|
|
137
|
-
0x40024: new
|
|
138
|
+
0x40024: new RPXOSC(this, 'XOSC_BASE'),
|
|
138
139
|
0x40028: new UnimplementedPeripheral(this, 'PLL_SYS_BASE'),
|
|
139
140
|
0x4002c: new UnimplementedPeripheral(this, 'PLL_USB_BASE'),
|
|
140
141
|
0x40030: new RPBUSCTRL(this, 'BUSCTRL_BASE'),
|