rp2040js 1.3.2 → 1.3.4
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.
|
@@ -366,7 +366,7 @@ class RPDMA extends peripheral_js_1.BasePeripheral {
|
|
|
366
366
|
return (this.intRaw & this.intEnable1) | this.intForce1;
|
|
367
367
|
}
|
|
368
368
|
readUint32(offset) {
|
|
369
|
-
if ((offset & 0x7ff)
|
|
369
|
+
if ((offset & 0x7ff) < CHANNEL_REGISTERS_SIZE) {
|
|
370
370
|
const channelIndex = (offset & 0x7ff) >> 6;
|
|
371
371
|
return this.channels[channelIndex].readUint32(offset & CHANNEL_REGISTERS_MASK);
|
|
372
372
|
}
|
|
@@ -399,7 +399,7 @@ class RPDMA extends peripheral_js_1.BasePeripheral {
|
|
|
399
399
|
return super.readUint32(offset);
|
|
400
400
|
}
|
|
401
401
|
writeUint32(offset, value) {
|
|
402
|
-
if ((offset & 0x7ff)
|
|
402
|
+
if ((offset & 0x7ff) < CHANNEL_REGISTERS_SIZE) {
|
|
403
403
|
const channelIndex = (offset & 0x7ff) >> 6;
|
|
404
404
|
this.channels[channelIndex].writeUint32(offset & CHANNEL_REGISTERS_MASK, value);
|
|
405
405
|
return;
|
|
@@ -106,12 +106,15 @@ class PWMChannel {
|
|
|
106
106
|
if (value & CSR_EN && !(this.csr & CSR_EN)) {
|
|
107
107
|
this.updateDoubleBuffered();
|
|
108
108
|
}
|
|
109
|
+
// PH_ADV and PH_RET are self-clearing, so they never appear in the stored csr value
|
|
109
110
|
this.csr = value & ~(CSR_PH_ADV | CSR_PH_RET);
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
if (value & CSR_EN) {
|
|
112
|
+
if (value & CSR_PH_ADV) {
|
|
113
|
+
this.timer.advance(1);
|
|
114
|
+
}
|
|
115
|
+
if (value & CSR_PH_RET) {
|
|
116
|
+
this.timer.advance(-1);
|
|
117
|
+
}
|
|
115
118
|
}
|
|
116
119
|
this.divMode = (this.csr >> CSR_DIVMODE_SHIFT) & CSR_DIVMODE_MASK;
|
|
117
120
|
this.setBDirection(this.divMode === PWMDivMode.FreeRunning);
|
|
@@ -37,6 +37,12 @@ class Timer32 {
|
|
|
37
37
|
*/
|
|
38
38
|
advance(delta) {
|
|
39
39
|
this.baseValue += delta;
|
|
40
|
+
if (this.topValue !== 0xffffffff) {
|
|
41
|
+
// Keep the base value in range, so that retarding past 0 wraps around to the top
|
|
42
|
+
const topModulo = this.timerMode === TimerMode.ZigZag ? this.topValue * 2 : this.topValue + 1;
|
|
43
|
+
this.baseValue = ((this.baseValue % topModulo) + topModulo) % topModulo;
|
|
44
|
+
}
|
|
45
|
+
this.updated();
|
|
40
46
|
}
|
|
41
47
|
get rawCounter() {
|
|
42
48
|
const { baseFreq, prescalerValue, baseNanos, baseValue, enabled, timerMode } = this;
|
|
@@ -362,7 +362,7 @@ export class RPDMA extends BasePeripheral {
|
|
|
362
362
|
return (this.intRaw & this.intEnable1) | this.intForce1;
|
|
363
363
|
}
|
|
364
364
|
readUint32(offset) {
|
|
365
|
-
if ((offset & 0x7ff)
|
|
365
|
+
if ((offset & 0x7ff) < CHANNEL_REGISTERS_SIZE) {
|
|
366
366
|
const channelIndex = (offset & 0x7ff) >> 6;
|
|
367
367
|
return this.channels[channelIndex].readUint32(offset & CHANNEL_REGISTERS_MASK);
|
|
368
368
|
}
|
|
@@ -395,7 +395,7 @@ export class RPDMA extends BasePeripheral {
|
|
|
395
395
|
return super.readUint32(offset);
|
|
396
396
|
}
|
|
397
397
|
writeUint32(offset, value) {
|
|
398
|
-
if ((offset & 0x7ff)
|
|
398
|
+
if ((offset & 0x7ff) < CHANNEL_REGISTERS_SIZE) {
|
|
399
399
|
const channelIndex = (offset & 0x7ff) >> 6;
|
|
400
400
|
this.channels[channelIndex].writeUint32(offset & CHANNEL_REGISTERS_MASK, value);
|
|
401
401
|
return;
|
|
@@ -103,12 +103,15 @@ class PWMChannel {
|
|
|
103
103
|
if (value & CSR_EN && !(this.csr & CSR_EN)) {
|
|
104
104
|
this.updateDoubleBuffered();
|
|
105
105
|
}
|
|
106
|
+
// PH_ADV and PH_RET are self-clearing, so they never appear in the stored csr value
|
|
106
107
|
this.csr = value & ~(CSR_PH_ADV | CSR_PH_RET);
|
|
107
|
-
if (
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
if (value & CSR_EN) {
|
|
109
|
+
if (value & CSR_PH_ADV) {
|
|
110
|
+
this.timer.advance(1);
|
|
111
|
+
}
|
|
112
|
+
if (value & CSR_PH_RET) {
|
|
113
|
+
this.timer.advance(-1);
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
116
|
this.divMode = (this.csr >> CSR_DIVMODE_SHIFT) & CSR_DIVMODE_MASK;
|
|
114
117
|
this.setBDirection(this.divMode === PWMDivMode.FreeRunning);
|
|
@@ -34,6 +34,12 @@ export class Timer32 {
|
|
|
34
34
|
*/
|
|
35
35
|
advance(delta) {
|
|
36
36
|
this.baseValue += delta;
|
|
37
|
+
if (this.topValue !== 0xffffffff) {
|
|
38
|
+
// Keep the base value in range, so that retarding past 0 wraps around to the top
|
|
39
|
+
const topModulo = this.timerMode === TimerMode.ZigZag ? this.topValue * 2 : this.topValue + 1;
|
|
40
|
+
this.baseValue = ((this.baseValue % topModulo) + topModulo) % topModulo;
|
|
41
|
+
}
|
|
42
|
+
this.updated();
|
|
37
43
|
}
|
|
38
44
|
get rawCounter() {
|
|
39
45
|
const { baseFreq, prescalerValue, baseNanos, baseValue, enabled, timerMode } = this;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rp2040js",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Raspberry Pi Pico (RP2040) Emulator",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/minimist": "^1.2.2",
|
|
64
|
-
"@types/node": "^
|
|
64
|
+
"@types/node": "^20",
|
|
65
65
|
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
66
66
|
"@typescript-eslint/parser": "^6.7.3",
|
|
67
67
|
"eslint": "^8.50.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"tsx": "^4.19.3",
|
|
75
75
|
"typescript": "^5.7.3",
|
|
76
76
|
"uf2": "^1.0.0",
|
|
77
|
-
"vitest": "^
|
|
77
|
+
"vitest": "^4.1.9"
|
|
78
78
|
},
|
|
79
79
|
"lint-staged": {
|
|
80
80
|
"**/*.ts": [
|