rp2040js 0.17.6 → 0.17.8
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 +23 -8
- package/dist/cjs/cortex-m0-core.d.ts +1 -1
- package/dist/cjs/cortex-m0-core.js +25 -44
- package/dist/cjs/interpolator.js +12 -4
- package/dist/cjs/peripherals/adc.js +1 -1
- package/dist/cjs/peripherals/usb.js +1 -1
- package/dist/cjs/rp2040.d.ts +1 -0
- package/dist/cjs/rp2040.js +2 -1
- package/dist/esm/cortex-m0-core.d.ts +1 -1
- package/dist/esm/cortex-m0-core.js +26 -45
- package/dist/esm/interpolator.js +12 -4
- package/dist/esm/peripherals/adc.js +1 -1
- package/dist/esm/peripherals/usb.js +1 -1
- package/dist/esm/rp2040.d.ts +1 -0
- package/dist/esm/rp2040.js +1 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -6,20 +6,21 @@ Raspberry Pi Pico Emulator for the [Wokwi Simulation Platform](https://wokwi.com
|
|
|
6
6
|
|
|
7
7
|
If you are just looking to play around with the Raspberry Pi Pico Simulator, check out the Wokwi Simulator:
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
- [Raspberry Pi Pico Traffic Light](https://wokwi.com/arduino/projects/297322571959894536)
|
|
10
|
+
- [LCD1602 Hello World](https://wokwi.com/arduino/projects/297323005822894602)
|
|
11
|
+
- [MicroPython Blink](https://wokwi.com/arduino/projects/300504213470839309)
|
|
12
|
+
- [MicroPython 7-Segment Counter](https://wokwi.com/arduino/projects/300210834979684872)
|
|
13
13
|
|
|
14
14
|
For more information, take a look at the [wokwi-pi-pico docs](https://docs.wokwi.com/parts/wokwi-pi-pico) and the [Pi Pico MicroPython Guide](https://docs.wokwi.com/guides/micropython).
|
|
15
15
|
|
|
16
16
|
If you want to develop your own application using the Raspberry Pi Pico simulator, the following examples may be helpful:
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
- [Blink LEDs with RP2040js, from scratch](https://stackblitz.com/edit/rp2040js-blink?file=index.ts) - Press "Run" and patiently wait for the code to compile ;-)
|
|
19
19
|
|
|
20
20
|
## Run the demo project
|
|
21
21
|
|
|
22
22
|
### Native code
|
|
23
|
+
|
|
23
24
|
You'd need to get `hello_uart.hex` by building it from the [pico-examples repo](https://github.com/raspberrypi/pico-examples/tree/master/uart/hello_uart), then copy it to the rp2040js root directory and run:
|
|
24
25
|
|
|
25
26
|
```
|
|
@@ -28,6 +29,7 @@ npm start
|
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
### MicroPython code
|
|
32
|
+
|
|
31
33
|
To run the MicroPython demo, first download [rp2-pico-20210902-v1.17.uf2](https://micropython.org/resources/firmware/rp2-pico-20210902-v1.17.uf2), place it in the rp2040js root directory, then run:
|
|
32
34
|
|
|
33
35
|
```
|
|
@@ -35,14 +37,27 @@ npm install
|
|
|
35
37
|
npm run start:micropython
|
|
36
38
|
```
|
|
37
39
|
|
|
38
|
-
and enjoy the MicroPython REPL! Quit the REPL with Ctrl+X.
|
|
40
|
+
and enjoy the MicroPython REPL! Quit the REPL with Ctrl+X. A different UF2 image can be loaded by supplying the `--image` option:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
npm run start:micropython -- --image=my_image.uf2
|
|
44
|
+
```
|
|
39
45
|
|
|
40
|
-
|
|
46
|
+
A GDB server on port 3333 can be enabled by specifying the `--gdb` flag:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
npm run start:micropython -- --gdb
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
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).
|
|
53
|
+
|
|
54
|
+
#### Filesystem support
|
|
41
55
|
|
|
42
56
|
With MicroPython – and probably also CircuitPython – you can use the filesystem on the Pico. This becomes useful as more than one script file is used in your code. Just put a [LittleFS](https://github.com/littlefs-project/littlefs) formatted filesystem image called `littlefs.img` into the rp2040js root directory, and your `main.py` will be automatically started from there.
|
|
43
57
|
|
|
44
58
|
A simple way to create a suitable LittleFS image containing your script files is outlined in [create_littlefs_image.py](https://github.com/tomods/GrinderController/blob/358ad3e0f795d8cc0bdf4f21bb35f806871d433f/tools/create_littlefs_image.py).
|
|
45
59
|
So, using [littlefs-python](https://pypi.org/project/littlefs-python/), you can do the following:
|
|
60
|
+
|
|
46
61
|
```python
|
|
47
62
|
from littlefs import LittleFS
|
|
48
63
|
files = ['your.py', 'files.py', 'here.py', 'main.py']
|
|
@@ -66,4 +81,4 @@ Currently, the filesystem is not writeable, as the SSI peripheral required for f
|
|
|
66
81
|
|
|
67
82
|
## License
|
|
68
83
|
|
|
69
|
-
Released under the MIT licence. Copyright (c) 2021, Uri Shaked.
|
|
84
|
+
Released under the MIT licence. Copyright (c) 2021-2023, Uri Shaked.
|
|
@@ -79,7 +79,7 @@ export declare class CortexM0Core {
|
|
|
79
79
|
BXWritePC(address: number): void;
|
|
80
80
|
private substractUpdateFlags;
|
|
81
81
|
private addUpdateFlags;
|
|
82
|
-
|
|
82
|
+
cyclesIO(addr: number, write?: boolean): 3 | 0 | 1 | 4;
|
|
83
83
|
executeInstruction(): void;
|
|
84
84
|
}
|
|
85
85
|
export {};
|
|
@@ -502,9 +502,15 @@ class CortexM0Core {
|
|
|
502
502
|
this.V = (result | 0) === signedSum ? false : true;
|
|
503
503
|
return result & 0xffffffff;
|
|
504
504
|
}
|
|
505
|
-
|
|
505
|
+
cyclesIO(addr, write = false) {
|
|
506
506
|
addr = addr >>> 0;
|
|
507
|
-
|
|
507
|
+
if (addr >= rp2040_1.SIO_START_ADDRESS && addr < rp2040_1.SIO_START_ADDRESS + 0x10000000) {
|
|
508
|
+
return 0;
|
|
509
|
+
}
|
|
510
|
+
if (addr >= rp2040_1.APB_START_ADDRESS && addr < rp2040_1.APB_START_ADDRESS + 0x10000000) {
|
|
511
|
+
return write ? 4 : 3;
|
|
512
|
+
}
|
|
513
|
+
return 1;
|
|
508
514
|
}
|
|
509
515
|
executeInstruction() {
|
|
510
516
|
if (this.interruptsUpdated) {
|
|
@@ -759,6 +765,7 @@ class CortexM0Core {
|
|
|
759
765
|
const Rn = (opcode >> 3) & 0x7;
|
|
760
766
|
const Rt = opcode & 0x7;
|
|
761
767
|
const addr = this.registers[Rn] + imm5;
|
|
768
|
+
this.cycles += this.cyclesIO(addr);
|
|
762
769
|
this.registers[Rt] = this.readUint32(addr);
|
|
763
770
|
}
|
|
764
771
|
// LDR (sp + immediate)
|
|
@@ -766,6 +773,7 @@ class CortexM0Core {
|
|
|
766
773
|
const Rt = (opcode >> 8) & 0x7;
|
|
767
774
|
const imm8 = opcode & 0xff;
|
|
768
775
|
const addr = this.SP + (imm8 << 2);
|
|
776
|
+
this.cycles += this.cyclesIO(addr);
|
|
769
777
|
this.registers[Rt] = this.readUint32(addr);
|
|
770
778
|
}
|
|
771
779
|
// LDR (literal)
|
|
@@ -774,6 +782,7 @@ class CortexM0Core {
|
|
|
774
782
|
const Rt = (opcode >> 8) & 7;
|
|
775
783
|
const nextPC = this.PC + 2;
|
|
776
784
|
const addr = (nextPC & 0xfffffffc) + imm8;
|
|
785
|
+
this.cycles += this.cyclesIO(addr);
|
|
777
786
|
this.registers[Rt] = this.readUint32(addr);
|
|
778
787
|
}
|
|
779
788
|
// LDR (register)
|
|
@@ -782,9 +791,7 @@ class CortexM0Core {
|
|
|
782
791
|
const Rn = (opcode >> 3) & 0x7;
|
|
783
792
|
const Rt = opcode & 0x7;
|
|
784
793
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
785
|
-
|
|
786
|
-
this.cycles++;
|
|
787
|
-
}
|
|
794
|
+
this.cycles += this.cyclesIO(addr);
|
|
788
795
|
this.registers[Rt] = this.readUint32(addr);
|
|
789
796
|
}
|
|
790
797
|
// LDRB (immediate)
|
|
@@ -793,9 +800,7 @@ class CortexM0Core {
|
|
|
793
800
|
const Rn = (opcode >> 3) & 0x7;
|
|
794
801
|
const Rt = opcode & 0x7;
|
|
795
802
|
const addr = this.registers[Rn] + imm5;
|
|
796
|
-
|
|
797
|
-
this.cycles++;
|
|
798
|
-
}
|
|
803
|
+
this.cycles += this.cyclesIO(addr);
|
|
799
804
|
this.registers[Rt] = this.readUint8(addr);
|
|
800
805
|
}
|
|
801
806
|
// LDRB (register)
|
|
@@ -804,9 +809,7 @@ class CortexM0Core {
|
|
|
804
809
|
const Rn = (opcode >> 3) & 0x7;
|
|
805
810
|
const Rt = opcode & 0x7;
|
|
806
811
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
807
|
-
|
|
808
|
-
this.cycles++;
|
|
809
|
-
}
|
|
812
|
+
this.cycles += this.cyclesIO(addr);
|
|
810
813
|
this.registers[Rt] = this.readUint8(addr);
|
|
811
814
|
}
|
|
812
815
|
// LDRH (immediate)
|
|
@@ -815,9 +818,7 @@ class CortexM0Core {
|
|
|
815
818
|
const Rn = (opcode >> 3) & 0x7;
|
|
816
819
|
const Rt = opcode & 0x7;
|
|
817
820
|
const addr = this.registers[Rn] + (imm5 << 1);
|
|
818
|
-
|
|
819
|
-
this.cycles++;
|
|
820
|
-
}
|
|
821
|
+
this.cycles += this.cyclesIO(addr);
|
|
821
822
|
this.registers[Rt] = this.readUint16(addr);
|
|
822
823
|
}
|
|
823
824
|
// LDRH (register)
|
|
@@ -826,9 +827,7 @@ class CortexM0Core {
|
|
|
826
827
|
const Rn = (opcode >> 3) & 0x7;
|
|
827
828
|
const Rt = opcode & 0x7;
|
|
828
829
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
829
|
-
|
|
830
|
-
this.cycles++;
|
|
831
|
-
}
|
|
830
|
+
this.cycles += this.cyclesIO(addr);
|
|
832
831
|
this.registers[Rt] = this.readUint16(addr);
|
|
833
832
|
}
|
|
834
833
|
// LDRSB
|
|
@@ -837,9 +836,7 @@ class CortexM0Core {
|
|
|
837
836
|
const Rn = (opcode >> 3) & 0x7;
|
|
838
837
|
const Rt = opcode & 0x7;
|
|
839
838
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
840
|
-
|
|
841
|
-
this.cycles++;
|
|
842
|
-
}
|
|
839
|
+
this.cycles += this.cyclesIO(addr);
|
|
843
840
|
this.registers[Rt] = signExtend8(this.readUint8(addr));
|
|
844
841
|
}
|
|
845
842
|
// LDRSH
|
|
@@ -848,9 +845,7 @@ class CortexM0Core {
|
|
|
848
845
|
const Rn = (opcode >> 3) & 0x7;
|
|
849
846
|
const Rt = opcode & 0x7;
|
|
850
847
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
851
|
-
|
|
852
|
-
this.cycles++;
|
|
853
|
-
}
|
|
848
|
+
this.cycles += this.cyclesIO(addr);
|
|
854
849
|
this.registers[Rt] = signExtend16(this.readUint16(addr));
|
|
855
850
|
}
|
|
856
851
|
// LSLS (immediate)
|
|
@@ -1091,9 +1086,7 @@ class CortexM0Core {
|
|
|
1091
1086
|
const Rn = (opcode >> 3) & 0x7;
|
|
1092
1087
|
const Rt = opcode & 0x7;
|
|
1093
1088
|
const address = this.registers[Rn] + imm5;
|
|
1094
|
-
|
|
1095
|
-
this.cycles++;
|
|
1096
|
-
}
|
|
1089
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1097
1090
|
this.writeUint32(address, this.registers[Rt]);
|
|
1098
1091
|
}
|
|
1099
1092
|
// STR (sp + immediate)
|
|
@@ -1101,9 +1094,7 @@ class CortexM0Core {
|
|
|
1101
1094
|
const Rt = (opcode >> 8) & 0x7;
|
|
1102
1095
|
const imm8 = opcode & 0xff;
|
|
1103
1096
|
const address = this.SP + (imm8 << 2);
|
|
1104
|
-
|
|
1105
|
-
this.cycles++;
|
|
1106
|
-
}
|
|
1097
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1107
1098
|
this.writeUint32(address, this.registers[Rt]);
|
|
1108
1099
|
}
|
|
1109
1100
|
// STR (register)
|
|
@@ -1112,9 +1103,7 @@ class CortexM0Core {
|
|
|
1112
1103
|
const Rn = (opcode >> 3) & 0x7;
|
|
1113
1104
|
const Rt = opcode & 0x7;
|
|
1114
1105
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1115
|
-
|
|
1116
|
-
this.cycles++;
|
|
1117
|
-
}
|
|
1106
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1118
1107
|
this.writeUint32(address, this.registers[Rt]);
|
|
1119
1108
|
}
|
|
1120
1109
|
// STRB (immediate)
|
|
@@ -1123,9 +1112,7 @@ class CortexM0Core {
|
|
|
1123
1112
|
const Rn = (opcode >> 3) & 0x7;
|
|
1124
1113
|
const Rt = opcode & 0x7;
|
|
1125
1114
|
const address = this.registers[Rn] + imm5;
|
|
1126
|
-
|
|
1127
|
-
this.cycles++;
|
|
1128
|
-
}
|
|
1115
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1129
1116
|
this.writeUint8(address, this.registers[Rt]);
|
|
1130
1117
|
}
|
|
1131
1118
|
// STRB (register)
|
|
@@ -1134,9 +1121,7 @@ class CortexM0Core {
|
|
|
1134
1121
|
const Rn = (opcode >> 3) & 0x7;
|
|
1135
1122
|
const Rt = opcode & 0x7;
|
|
1136
1123
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1137
|
-
|
|
1138
|
-
this.cycles++;
|
|
1139
|
-
}
|
|
1124
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1140
1125
|
this.writeUint8(address, this.registers[Rt]);
|
|
1141
1126
|
}
|
|
1142
1127
|
// STRH (immediate)
|
|
@@ -1145,9 +1130,7 @@ class CortexM0Core {
|
|
|
1145
1130
|
const Rn = (opcode >> 3) & 0x7;
|
|
1146
1131
|
const Rt = opcode & 0x7;
|
|
1147
1132
|
const address = this.registers[Rn] + imm5;
|
|
1148
|
-
|
|
1149
|
-
this.cycles++;
|
|
1150
|
-
}
|
|
1133
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1151
1134
|
this.writeUint16(address, this.registers[Rt]);
|
|
1152
1135
|
}
|
|
1153
1136
|
// STRH (register)
|
|
@@ -1156,9 +1139,7 @@ class CortexM0Core {
|
|
|
1156
1139
|
const Rn = (opcode >> 3) & 0x7;
|
|
1157
1140
|
const Rt = opcode & 0x7;
|
|
1158
1141
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1159
|
-
|
|
1160
|
-
this.cycles++;
|
|
1161
|
-
}
|
|
1142
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1162
1143
|
this.writeUint16(address, this.registers[Rt]);
|
|
1163
1144
|
}
|
|
1164
1145
|
// SUB (SP minus immediate)
|
package/dist/cjs/interpolator.js
CHANGED
|
@@ -89,8 +89,8 @@ class Interpolator {
|
|
|
89
89
|
const overf0 = Boolean((input0 >>> ctrl0.shift) & ~msbmask0);
|
|
90
90
|
const overf1 = Boolean((input1 >>> ctrl1.shift) & ~msbmask1);
|
|
91
91
|
const overf = overf0 || overf1;
|
|
92
|
-
const sextmask0 =
|
|
93
|
-
const sextmask1 =
|
|
92
|
+
const sextmask0 = uresult0 & (1 << ctrl0.maskMSB) ? -1 << ctrl0.maskMSB : 0;
|
|
93
|
+
const sextmask1 = uresult1 & (1 << ctrl1.maskMSB) ? -1 << ctrl1.maskMSB : 0;
|
|
94
94
|
const sresult0 = uresult0 | sextmask0;
|
|
95
95
|
const sresult1 = uresult1 | sextmask1;
|
|
96
96
|
const result0 = ctrl0.signed ? sresult0 : uresult0;
|
|
@@ -98,8 +98,16 @@ class Interpolator {
|
|
|
98
98
|
const addresult0 = this.base0 + (ctrl0.addRaw ? input0 : result0);
|
|
99
99
|
const addresult1 = this.base1 + (ctrl1.addRaw ? input1 : result1);
|
|
100
100
|
const addresult2 = this.base2 + result0 + (do_blend ? 0 : result1);
|
|
101
|
-
const uclamp0 = bit_1.u32(result0) < bit_1.u32(this.base0)
|
|
102
|
-
|
|
101
|
+
const uclamp0 = bit_1.u32(result0) < bit_1.u32(this.base0)
|
|
102
|
+
? this.base0
|
|
103
|
+
: bit_1.u32(result0) > bit_1.u32(this.base1)
|
|
104
|
+
? this.base1
|
|
105
|
+
: result0;
|
|
106
|
+
const sclamp0 = bit_1.s32(result0) < bit_1.s32(this.base0)
|
|
107
|
+
? this.base0
|
|
108
|
+
: bit_1.s32(result0) > bit_1.s32(this.base1)
|
|
109
|
+
? this.base1
|
|
110
|
+
: result0;
|
|
103
111
|
const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
|
|
104
112
|
const alpha1 = result1 & 0xff;
|
|
105
113
|
const ublend1 = bit_1.u32(this.base0) + (Math.floor((alpha1 * (bit_1.u32(this.base1) - bit_1.u32(this.base0))) / 256) | 0);
|
|
@@ -205,7 +205,7 @@ class RPUSBController extends peripheral_1.BasePeripheral {
|
|
|
205
205
|
(_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
if (doubleBuffer && (
|
|
208
|
+
if (doubleBuffer && (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE) {
|
|
209
209
|
const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
|
|
210
210
|
const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
|
|
211
211
|
this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
|
package/dist/cjs/rp2040.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { RPSIO } from './sio';
|
|
|
15
15
|
import { Logger } from './utils/logging';
|
|
16
16
|
export declare const FLASH_START_ADDRESS = 268435456;
|
|
17
17
|
export declare const RAM_START_ADDRESS = 536870912;
|
|
18
|
+
export declare const APB_START_ADDRESS = 1073741824;
|
|
18
19
|
export declare const DPRAM_START_ADDRESS = 1343225856;
|
|
19
20
|
export declare const SIO_START_ADDRESS = 3489660928;
|
|
20
21
|
export declare class RP2040 {
|
package/dist/cjs/rp2040.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RP2040 = exports.SIO_START_ADDRESS = exports.DPRAM_START_ADDRESS = exports.RAM_START_ADDRESS = exports.FLASH_START_ADDRESS = void 0;
|
|
3
|
+
exports.RP2040 = exports.SIO_START_ADDRESS = exports.DPRAM_START_ADDRESS = exports.APB_START_ADDRESS = exports.RAM_START_ADDRESS = exports.FLASH_START_ADDRESS = void 0;
|
|
4
4
|
const realtime_clock_1 = require("./clock/realtime-clock");
|
|
5
5
|
const cortex_m0_core_1 = require("./cortex-m0-core");
|
|
6
6
|
const gpio_pin_1 = require("./gpio-pin");
|
|
@@ -29,6 +29,7 @@ const logging_1 = require("./utils/logging");
|
|
|
29
29
|
const tbman_1 = require("./peripherals/tbman");
|
|
30
30
|
exports.FLASH_START_ADDRESS = 0x10000000;
|
|
31
31
|
exports.RAM_START_ADDRESS = 0x20000000;
|
|
32
|
+
exports.APB_START_ADDRESS = 0x40000000;
|
|
32
33
|
exports.DPRAM_START_ADDRESS = 0x50100000;
|
|
33
34
|
exports.SIO_START_ADDRESS = 0xd0000000;
|
|
34
35
|
const LOG_NAME = 'RP2040';
|
|
@@ -79,7 +79,7 @@ export declare class CortexM0Core {
|
|
|
79
79
|
BXWritePC(address: number): void;
|
|
80
80
|
private substractUpdateFlags;
|
|
81
81
|
private addUpdateFlags;
|
|
82
|
-
|
|
82
|
+
cyclesIO(addr: number, write?: boolean): 3 | 0 | 1 | 4;
|
|
83
83
|
executeInstruction(): void;
|
|
84
84
|
}
|
|
85
85
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MAX_HARDWARE_IRQ } from './irq';
|
|
2
|
-
import { SIO_START_ADDRESS } from './rp2040';
|
|
2
|
+
import { APB_START_ADDRESS, SIO_START_ADDRESS } from './rp2040';
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
4
4
|
const EXC_RESET = 1;
|
|
5
5
|
const EXC_NMI = 2;
|
|
@@ -499,9 +499,15 @@ export class CortexM0Core {
|
|
|
499
499
|
this.V = (result | 0) === signedSum ? false : true;
|
|
500
500
|
return result & 0xffffffff;
|
|
501
501
|
}
|
|
502
|
-
|
|
502
|
+
cyclesIO(addr, write = false) {
|
|
503
503
|
addr = addr >>> 0;
|
|
504
|
-
|
|
504
|
+
if (addr >= SIO_START_ADDRESS && addr < SIO_START_ADDRESS + 0x10000000) {
|
|
505
|
+
return 0;
|
|
506
|
+
}
|
|
507
|
+
if (addr >= APB_START_ADDRESS && addr < APB_START_ADDRESS + 0x10000000) {
|
|
508
|
+
return write ? 4 : 3;
|
|
509
|
+
}
|
|
510
|
+
return 1;
|
|
505
511
|
}
|
|
506
512
|
executeInstruction() {
|
|
507
513
|
if (this.interruptsUpdated) {
|
|
@@ -756,6 +762,7 @@ export class CortexM0Core {
|
|
|
756
762
|
const Rn = (opcode >> 3) & 0x7;
|
|
757
763
|
const Rt = opcode & 0x7;
|
|
758
764
|
const addr = this.registers[Rn] + imm5;
|
|
765
|
+
this.cycles += this.cyclesIO(addr);
|
|
759
766
|
this.registers[Rt] = this.readUint32(addr);
|
|
760
767
|
}
|
|
761
768
|
// LDR (sp + immediate)
|
|
@@ -763,6 +770,7 @@ export class CortexM0Core {
|
|
|
763
770
|
const Rt = (opcode >> 8) & 0x7;
|
|
764
771
|
const imm8 = opcode & 0xff;
|
|
765
772
|
const addr = this.SP + (imm8 << 2);
|
|
773
|
+
this.cycles += this.cyclesIO(addr);
|
|
766
774
|
this.registers[Rt] = this.readUint32(addr);
|
|
767
775
|
}
|
|
768
776
|
// LDR (literal)
|
|
@@ -771,6 +779,7 @@ export class CortexM0Core {
|
|
|
771
779
|
const Rt = (opcode >> 8) & 7;
|
|
772
780
|
const nextPC = this.PC + 2;
|
|
773
781
|
const addr = (nextPC & 0xfffffffc) + imm8;
|
|
782
|
+
this.cycles += this.cyclesIO(addr);
|
|
774
783
|
this.registers[Rt] = this.readUint32(addr);
|
|
775
784
|
}
|
|
776
785
|
// LDR (register)
|
|
@@ -779,9 +788,7 @@ export class CortexM0Core {
|
|
|
779
788
|
const Rn = (opcode >> 3) & 0x7;
|
|
780
789
|
const Rt = opcode & 0x7;
|
|
781
790
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
782
|
-
|
|
783
|
-
this.cycles++;
|
|
784
|
-
}
|
|
791
|
+
this.cycles += this.cyclesIO(addr);
|
|
785
792
|
this.registers[Rt] = this.readUint32(addr);
|
|
786
793
|
}
|
|
787
794
|
// LDRB (immediate)
|
|
@@ -790,9 +797,7 @@ export class CortexM0Core {
|
|
|
790
797
|
const Rn = (opcode >> 3) & 0x7;
|
|
791
798
|
const Rt = opcode & 0x7;
|
|
792
799
|
const addr = this.registers[Rn] + imm5;
|
|
793
|
-
|
|
794
|
-
this.cycles++;
|
|
795
|
-
}
|
|
800
|
+
this.cycles += this.cyclesIO(addr);
|
|
796
801
|
this.registers[Rt] = this.readUint8(addr);
|
|
797
802
|
}
|
|
798
803
|
// LDRB (register)
|
|
@@ -801,9 +806,7 @@ export class CortexM0Core {
|
|
|
801
806
|
const Rn = (opcode >> 3) & 0x7;
|
|
802
807
|
const Rt = opcode & 0x7;
|
|
803
808
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
804
|
-
|
|
805
|
-
this.cycles++;
|
|
806
|
-
}
|
|
809
|
+
this.cycles += this.cyclesIO(addr);
|
|
807
810
|
this.registers[Rt] = this.readUint8(addr);
|
|
808
811
|
}
|
|
809
812
|
// LDRH (immediate)
|
|
@@ -812,9 +815,7 @@ export class CortexM0Core {
|
|
|
812
815
|
const Rn = (opcode >> 3) & 0x7;
|
|
813
816
|
const Rt = opcode & 0x7;
|
|
814
817
|
const addr = this.registers[Rn] + (imm5 << 1);
|
|
815
|
-
|
|
816
|
-
this.cycles++;
|
|
817
|
-
}
|
|
818
|
+
this.cycles += this.cyclesIO(addr);
|
|
818
819
|
this.registers[Rt] = this.readUint16(addr);
|
|
819
820
|
}
|
|
820
821
|
// LDRH (register)
|
|
@@ -823,9 +824,7 @@ export class CortexM0Core {
|
|
|
823
824
|
const Rn = (opcode >> 3) & 0x7;
|
|
824
825
|
const Rt = opcode & 0x7;
|
|
825
826
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
826
|
-
|
|
827
|
-
this.cycles++;
|
|
828
|
-
}
|
|
827
|
+
this.cycles += this.cyclesIO(addr);
|
|
829
828
|
this.registers[Rt] = this.readUint16(addr);
|
|
830
829
|
}
|
|
831
830
|
// LDRSB
|
|
@@ -834,9 +833,7 @@ export class CortexM0Core {
|
|
|
834
833
|
const Rn = (opcode >> 3) & 0x7;
|
|
835
834
|
const Rt = opcode & 0x7;
|
|
836
835
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
837
|
-
|
|
838
|
-
this.cycles++;
|
|
839
|
-
}
|
|
836
|
+
this.cycles += this.cyclesIO(addr);
|
|
840
837
|
this.registers[Rt] = signExtend8(this.readUint8(addr));
|
|
841
838
|
}
|
|
842
839
|
// LDRSH
|
|
@@ -845,9 +842,7 @@ export class CortexM0Core {
|
|
|
845
842
|
const Rn = (opcode >> 3) & 0x7;
|
|
846
843
|
const Rt = opcode & 0x7;
|
|
847
844
|
const addr = this.registers[Rm] + this.registers[Rn];
|
|
848
|
-
|
|
849
|
-
this.cycles++;
|
|
850
|
-
}
|
|
845
|
+
this.cycles += this.cyclesIO(addr);
|
|
851
846
|
this.registers[Rt] = signExtend16(this.readUint16(addr));
|
|
852
847
|
}
|
|
853
848
|
// LSLS (immediate)
|
|
@@ -1088,9 +1083,7 @@ export class CortexM0Core {
|
|
|
1088
1083
|
const Rn = (opcode >> 3) & 0x7;
|
|
1089
1084
|
const Rt = opcode & 0x7;
|
|
1090
1085
|
const address = this.registers[Rn] + imm5;
|
|
1091
|
-
|
|
1092
|
-
this.cycles++;
|
|
1093
|
-
}
|
|
1086
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1094
1087
|
this.writeUint32(address, this.registers[Rt]);
|
|
1095
1088
|
}
|
|
1096
1089
|
// STR (sp + immediate)
|
|
@@ -1098,9 +1091,7 @@ export class CortexM0Core {
|
|
|
1098
1091
|
const Rt = (opcode >> 8) & 0x7;
|
|
1099
1092
|
const imm8 = opcode & 0xff;
|
|
1100
1093
|
const address = this.SP + (imm8 << 2);
|
|
1101
|
-
|
|
1102
|
-
this.cycles++;
|
|
1103
|
-
}
|
|
1094
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1104
1095
|
this.writeUint32(address, this.registers[Rt]);
|
|
1105
1096
|
}
|
|
1106
1097
|
// STR (register)
|
|
@@ -1109,9 +1100,7 @@ export class CortexM0Core {
|
|
|
1109
1100
|
const Rn = (opcode >> 3) & 0x7;
|
|
1110
1101
|
const Rt = opcode & 0x7;
|
|
1111
1102
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1112
|
-
|
|
1113
|
-
this.cycles++;
|
|
1114
|
-
}
|
|
1103
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1115
1104
|
this.writeUint32(address, this.registers[Rt]);
|
|
1116
1105
|
}
|
|
1117
1106
|
// STRB (immediate)
|
|
@@ -1120,9 +1109,7 @@ export class CortexM0Core {
|
|
|
1120
1109
|
const Rn = (opcode >> 3) & 0x7;
|
|
1121
1110
|
const Rt = opcode & 0x7;
|
|
1122
1111
|
const address = this.registers[Rn] + imm5;
|
|
1123
|
-
|
|
1124
|
-
this.cycles++;
|
|
1125
|
-
}
|
|
1112
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1126
1113
|
this.writeUint8(address, this.registers[Rt]);
|
|
1127
1114
|
}
|
|
1128
1115
|
// STRB (register)
|
|
@@ -1131,9 +1118,7 @@ export class CortexM0Core {
|
|
|
1131
1118
|
const Rn = (opcode >> 3) & 0x7;
|
|
1132
1119
|
const Rt = opcode & 0x7;
|
|
1133
1120
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1134
|
-
|
|
1135
|
-
this.cycles++;
|
|
1136
|
-
}
|
|
1121
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1137
1122
|
this.writeUint8(address, this.registers[Rt]);
|
|
1138
1123
|
}
|
|
1139
1124
|
// STRH (immediate)
|
|
@@ -1142,9 +1127,7 @@ export class CortexM0Core {
|
|
|
1142
1127
|
const Rn = (opcode >> 3) & 0x7;
|
|
1143
1128
|
const Rt = opcode & 0x7;
|
|
1144
1129
|
const address = this.registers[Rn] + imm5;
|
|
1145
|
-
|
|
1146
|
-
this.cycles++;
|
|
1147
|
-
}
|
|
1130
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1148
1131
|
this.writeUint16(address, this.registers[Rt]);
|
|
1149
1132
|
}
|
|
1150
1133
|
// STRH (register)
|
|
@@ -1153,9 +1136,7 @@ export class CortexM0Core {
|
|
|
1153
1136
|
const Rn = (opcode >> 3) & 0x7;
|
|
1154
1137
|
const Rt = opcode & 0x7;
|
|
1155
1138
|
const address = this.registers[Rm] + this.registers[Rn];
|
|
1156
|
-
|
|
1157
|
-
this.cycles++;
|
|
1158
|
-
}
|
|
1139
|
+
this.cycles += this.cyclesIO(address, true);
|
|
1159
1140
|
this.writeUint16(address, this.registers[Rt]);
|
|
1160
1141
|
}
|
|
1161
1142
|
// SUB (SP minus immediate)
|
package/dist/esm/interpolator.js
CHANGED
|
@@ -85,8 +85,8 @@ export class Interpolator {
|
|
|
85
85
|
const overf0 = Boolean((input0 >>> ctrl0.shift) & ~msbmask0);
|
|
86
86
|
const overf1 = Boolean((input1 >>> ctrl1.shift) & ~msbmask1);
|
|
87
87
|
const overf = overf0 || overf1;
|
|
88
|
-
const sextmask0 =
|
|
89
|
-
const sextmask1 =
|
|
88
|
+
const sextmask0 = uresult0 & (1 << ctrl0.maskMSB) ? -1 << ctrl0.maskMSB : 0;
|
|
89
|
+
const sextmask1 = uresult1 & (1 << ctrl1.maskMSB) ? -1 << ctrl1.maskMSB : 0;
|
|
90
90
|
const sresult0 = uresult0 | sextmask0;
|
|
91
91
|
const sresult1 = uresult1 | sextmask1;
|
|
92
92
|
const result0 = ctrl0.signed ? sresult0 : uresult0;
|
|
@@ -94,8 +94,16 @@ export class Interpolator {
|
|
|
94
94
|
const addresult0 = this.base0 + (ctrl0.addRaw ? input0 : result0);
|
|
95
95
|
const addresult1 = this.base1 + (ctrl1.addRaw ? input1 : result1);
|
|
96
96
|
const addresult2 = this.base2 + result0 + (do_blend ? 0 : result1);
|
|
97
|
-
const uclamp0 = u32(result0) < u32(this.base0)
|
|
98
|
-
|
|
97
|
+
const uclamp0 = u32(result0) < u32(this.base0)
|
|
98
|
+
? this.base0
|
|
99
|
+
: u32(result0) > u32(this.base1)
|
|
100
|
+
? this.base1
|
|
101
|
+
: result0;
|
|
102
|
+
const sclamp0 = s32(result0) < s32(this.base0)
|
|
103
|
+
? this.base0
|
|
104
|
+
: s32(result0) > s32(this.base1)
|
|
105
|
+
? this.base1
|
|
106
|
+
: result0;
|
|
99
107
|
const clamp0 = ctrl0.signed ? sclamp0 : uclamp0;
|
|
100
108
|
const alpha1 = result1 & 0xff;
|
|
101
109
|
const ublend1 = u32(this.base0) + (Math.floor((alpha1 * (u32(this.base1) - u32(this.base0))) / 256) | 0);
|
|
@@ -202,7 +202,7 @@ export class RPUSBController extends BasePeripheral {
|
|
|
202
202
|
(_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
|
-
if (doubleBuffer && (
|
|
205
|
+
if (doubleBuffer && (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE) {
|
|
206
206
|
const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
|
|
207
207
|
const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
|
|
208
208
|
this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
|
package/dist/esm/rp2040.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { RPSIO } from './sio';
|
|
|
15
15
|
import { Logger } from './utils/logging';
|
|
16
16
|
export declare const FLASH_START_ADDRESS = 268435456;
|
|
17
17
|
export declare const RAM_START_ADDRESS = 536870912;
|
|
18
|
+
export declare const APB_START_ADDRESS = 1073741824;
|
|
18
19
|
export declare const DPRAM_START_ADDRESS = 1343225856;
|
|
19
20
|
export declare const SIO_START_ADDRESS = 3489660928;
|
|
20
21
|
export declare class RP2040 {
|
package/dist/esm/rp2040.js
CHANGED
|
@@ -26,6 +26,7 @@ import { ConsoleLogger, LogLevel } from './utils/logging';
|
|
|
26
26
|
import { RPTBMAN } from './peripherals/tbman';
|
|
27
27
|
export const FLASH_START_ADDRESS = 0x10000000;
|
|
28
28
|
export const RAM_START_ADDRESS = 0x20000000;
|
|
29
|
+
export const APB_START_ADDRESS = 0x40000000;
|
|
29
30
|
export const DPRAM_START_ADDRESS = 0x50100000;
|
|
30
31
|
export const SIO_START_ADDRESS = 0xd0000000;
|
|
31
32
|
const LOG_NAME = 'RP2040';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rp2040js",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.8",
|
|
4
4
|
"description": "Raspberry Pi Pico (RP2040) Emulator",
|
|
5
5
|
"repository": "https://github.com/wokwi/rp2040js",
|
|
6
6
|
"keywords": [
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"build": "rimraf dist && tsc && tsc -p tsconfig.esm.json && node build-scripts/dist-package-json",
|
|
31
31
|
"prepublish": "npm run build",
|
|
32
32
|
"prepare": "husky install",
|
|
33
|
+
"format:check": "prettier --check **/*.{ts,js} !**/dist/** !**/node_modules/**",
|
|
33
34
|
"lint": "eslint . --ext .ts",
|
|
34
35
|
"start": "ts-node demo/emulator-run.ts",
|
|
35
36
|
"start:micropython": "ts-node demo/micropython-run.ts",
|
|
@@ -38,13 +39,15 @@
|
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/jest": "^27.4.1",
|
|
42
|
+
"@types/minimist": "^1.2.2",
|
|
41
43
|
"@types/node": "^14.14.22",
|
|
42
44
|
"@typescript-eslint/eslint-plugin": "^4.22.1",
|
|
43
45
|
"@typescript-eslint/parser": "^4.22.1",
|
|
44
46
|
"eslint": "^7.26.0",
|
|
45
|
-
"husky": "^
|
|
47
|
+
"husky": "^8.0.0",
|
|
46
48
|
"jest": "^27.5.1",
|
|
47
49
|
"lint-staged": "^11.0.0",
|
|
50
|
+
"minimist": "^1.2.7",
|
|
48
51
|
"prettier": "^2.2.1",
|
|
49
52
|
"rimraf": "^3.0.2",
|
|
50
53
|
"ts-jest": "^27.1.3",
|