rp2040js 0.17.17 → 0.18.1
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 +11 -11
- package/dist/cjs/clock/clock.js +2 -2
- package/dist/cjs/clock/mock-clock.d.ts +17 -17
- package/dist/cjs/clock/mock-clock.js +52 -52
- package/dist/cjs/clock/realtime-clock.d.ts +23 -23
- package/dist/cjs/clock/realtime-clock.js +73 -73
- package/dist/cjs/cortex-m0-core.d.ts +87 -87
- package/dist/cjs/cortex-m0-core.js +1251 -1251
- package/dist/cjs/gdb/gdb-connection.d.ts +11 -11
- package/dist/cjs/gdb/gdb-connection.js +57 -57
- package/dist/cjs/gdb/gdb-server.d.ts +23 -23
- package/dist/cjs/gdb/gdb-server.js +232 -232
- package/dist/cjs/gdb/gdb-tcp-server.d.ts +10 -10
- package/dist/cjs/gdb/gdb-tcp-server.js +34 -34
- package/dist/cjs/gdb/gdb-utils.d.ts +9 -9
- package/dist/cjs/gdb/gdb-utils.js +48 -48
- package/dist/cjs/gpio-pin.d.ts +56 -56
- package/dist/cjs/gpio-pin.js +216 -216
- package/dist/cjs/index.d.ts +11 -11
- package/dist/cjs/index.js +36 -36
- package/dist/cjs/interpolator.d.ts +36 -36
- package/dist/cjs/interpolator.js +150 -150
- package/dist/cjs/irq.d.ts +29 -29
- package/dist/cjs/irq.js +33 -33
- package/dist/cjs/peripherals/adc.d.ts +52 -52
- package/dist/cjs/peripherals/adc.js +261 -261
- package/dist/cjs/peripherals/busctrl.d.ts +10 -10
- package/dist/cjs/peripherals/busctrl.js +84 -84
- package/dist/cjs/peripherals/clocks.d.ts +9 -9
- package/dist/cjs/peripherals/clocks.js +42 -42
- package/dist/cjs/peripherals/dma.d.ts +109 -109
- package/dist/cjs/peripherals/dma.js +520 -520
- package/dist/cjs/peripherals/i2c.d.ts +54 -54
- package/dist/cjs/peripherals/i2c.js +458 -458
- package/dist/cjs/peripherals/io.d.ts +11 -11
- package/dist/cjs/peripherals/io.js +100 -100
- package/dist/cjs/peripherals/pads.d.ts +13 -13
- package/dist/cjs/peripherals/pads.js +58 -58
- package/dist/cjs/peripherals/peripheral.d.ts +22 -22
- package/dist/cjs/peripherals/peripheral.js +61 -61
- package/dist/cjs/peripherals/pio.d.ts +120 -120
- package/dist/cjs/peripherals/pio.js +1086 -1086
- package/dist/cjs/peripherals/ppb.d.ts +25 -25
- package/dist/cjs/peripherals/ppb.js +229 -229
- package/dist/cjs/peripherals/pwm.d.ts +65 -65
- package/dist/cjs/peripherals/pwm.js +372 -372
- package/dist/cjs/peripherals/reset.d.ts +8 -8
- package/dist/cjs/peripherals/reset.js +40 -40
- package/dist/cjs/peripherals/rtc.d.ts +10 -10
- package/dist/cjs/peripherals/rtc.js +74 -74
- package/dist/cjs/peripherals/spi.d.ts +38 -38
- package/dist/cjs/peripherals/spi.js +240 -240
- package/dist/cjs/peripherals/ssi.d.ts +6 -6
- package/dist/cjs/peripherals/ssi.js +43 -43
- package/dist/cjs/peripherals/syscfg.d.ts +5 -5
- package/dist/cjs/peripherals/syscfg.js +26 -26
- package/dist/cjs/peripherals/sysinfo.d.ts +4 -4
- package/dist/cjs/peripherals/sysinfo.js +22 -22
- package/dist/cjs/peripherals/tbman.d.ts +4 -4
- package/dist/cjs/peripherals/tbman.js +17 -17
- package/dist/cjs/peripherals/timer.d.ts +18 -18
- package/dist/cjs/peripherals/timer.js +156 -156
- package/dist/cjs/peripherals/uart.d.ts +31 -31
- package/dist/cjs/peripherals/uart.js +132 -132
- package/dist/cjs/peripherals/usb.d.ts +29 -29
- package/dist/cjs/peripherals/usb.js +309 -309
- package/dist/cjs/rp2040.d.ts +71 -71
- package/dist/cjs/rp2040.js +361 -361
- package/dist/cjs/sio.d.ts +21 -21
- package/dist/cjs/sio.js +425 -425
- package/dist/cjs/usb/cdc.d.ts +20 -20
- package/dist/cjs/usb/cdc.js +126 -126
- package/dist/cjs/usb/interfaces.d.ts +47 -47
- package/dist/cjs/usb/interfaces.js +46 -46
- package/dist/cjs/usb/setup.d.ts +5 -5
- package/dist/cjs/usb/setup.js +53 -53
- package/dist/cjs/utils/assembler.d.ts +79 -79
- package/dist/cjs/utils/assembler.js +328 -328
- package/dist/cjs/utils/bit.d.ts +3 -3
- package/dist/cjs/utils/bit.js +15 -15
- package/dist/cjs/utils/fifo.d.ts +15 -15
- package/dist/cjs/utils/fifo.js +56 -56
- package/dist/cjs/utils/logging.d.ts +23 -23
- package/dist/cjs/utils/logging.js +48 -48
- package/dist/cjs/utils/pio-assembler.d.ts +45 -45
- package/dist/cjs/utils/pio-assembler.js +87 -87
- package/dist/cjs/utils/time.d.ts +2 -2
- package/dist/cjs/utils/time.js +32 -32
- package/dist/cjs/utils/timer32.d.ts +57 -57
- package/dist/cjs/utils/timer32.js +208 -208
- package/dist/esm/clock/clock.d.ts +11 -11
- package/dist/esm/clock/clock.js +1 -1
- package/dist/esm/clock/mock-clock.d.ts +17 -17
- package/dist/esm/clock/mock-clock.js +47 -47
- package/dist/esm/clock/realtime-clock.d.ts +23 -23
- package/dist/esm/clock/realtime-clock.js +68 -68
- package/dist/esm/cortex-m0-core.d.ts +87 -87
- package/dist/esm/cortex-m0-core.js +1247 -1247
- package/dist/esm/gdb/gdb-connection.d.ts +11 -11
- package/dist/esm/gdb/gdb-connection.js +53 -53
- package/dist/esm/gdb/gdb-server.d.ts +23 -23
- package/dist/esm/gdb/gdb-server.js +228 -228
- package/dist/esm/gdb/gdb-tcp-server.d.ts +10 -10
- package/dist/esm/gdb/gdb-tcp-server.js +30 -30
- package/dist/esm/gdb/gdb-utils.d.ts +9 -9
- package/dist/esm/gdb/gdb-utils.js +36 -36
- package/dist/esm/gpio-pin.d.ts +56 -56
- package/dist/esm/gpio-pin.js +212 -212
- package/dist/esm/index.d.ts +11 -11
- package/dist/esm/index.js +11 -11
- package/dist/esm/interpolator.d.ts +36 -36
- package/dist/esm/interpolator.js +145 -145
- package/dist/esm/irq.d.ts +29 -29
- package/dist/esm/irq.js +30 -30
- package/dist/esm/peripherals/adc.d.ts +52 -52
- package/dist/esm/peripherals/adc.js +257 -257
- package/dist/esm/peripherals/busctrl.d.ts +10 -10
- package/dist/esm/peripherals/busctrl.js +80 -80
- package/dist/esm/peripherals/clocks.d.ts +9 -9
- package/dist/esm/peripherals/clocks.js +38 -38
- package/dist/esm/peripherals/dma.d.ts +109 -109
- package/dist/esm/peripherals/dma.js +515 -515
- package/dist/esm/peripherals/i2c.d.ts +54 -54
- package/dist/esm/peripherals/i2c.js +454 -454
- package/dist/esm/peripherals/io.d.ts +11 -11
- package/dist/esm/peripherals/io.js +96 -96
- package/dist/esm/peripherals/pads.d.ts +13 -13
- package/dist/esm/peripherals/pads.js +54 -54
- package/dist/esm/peripherals/peripheral.d.ts +22 -22
- package/dist/esm/peripherals/peripheral.js +55 -55
- package/dist/esm/peripherals/pio.d.ts +120 -120
- package/dist/esm/peripherals/pio.js +1081 -1081
- package/dist/esm/peripherals/ppb.d.ts +25 -25
- package/dist/esm/peripherals/ppb.js +225 -225
- package/dist/esm/peripherals/pwm.d.ts +65 -65
- package/dist/esm/peripherals/pwm.js +368 -368
- package/dist/esm/peripherals/reset.d.ts +8 -8
- package/dist/esm/peripherals/reset.js +36 -36
- package/dist/esm/peripherals/rtc.d.ts +10 -10
- package/dist/esm/peripherals/rtc.js +70 -70
- package/dist/esm/peripherals/spi.d.ts +38 -38
- package/dist/esm/peripherals/spi.js +236 -236
- package/dist/esm/peripherals/ssi.d.ts +6 -6
- package/dist/esm/peripherals/ssi.js +39 -39
- package/dist/esm/peripherals/syscfg.d.ts +5 -5
- package/dist/esm/peripherals/syscfg.js +22 -22
- package/dist/esm/peripherals/sysinfo.d.ts +4 -4
- package/dist/esm/peripherals/sysinfo.js +18 -18
- package/dist/esm/peripherals/tbman.d.ts +4 -4
- package/dist/esm/peripherals/tbman.js +13 -13
- package/dist/esm/peripherals/timer.d.ts +18 -18
- package/dist/esm/peripherals/timer.js +152 -152
- package/dist/esm/peripherals/uart.d.ts +31 -31
- package/dist/esm/peripherals/uart.js +128 -128
- package/dist/esm/peripherals/usb.d.ts +29 -29
- package/dist/esm/peripherals/usb.js +305 -305
- package/dist/esm/rp2040.d.ts +71 -71
- package/dist/esm/rp2040.js +357 -357
- package/dist/esm/sio.d.ts +21 -21
- package/dist/esm/sio.js +421 -421
- package/dist/esm/usb/cdc.d.ts +20 -20
- package/dist/esm/usb/cdc.js +121 -121
- package/dist/esm/usb/interfaces.d.ts +47 -47
- package/dist/esm/usb/interfaces.js +43 -43
- package/dist/esm/usb/setup.d.ts +5 -5
- package/dist/esm/usb/setup.js +46 -46
- package/dist/esm/utils/assembler.d.ts +79 -79
- package/dist/esm/utils/assembler.js +245 -245
- package/dist/esm/utils/bit.d.ts +3 -3
- package/dist/esm/utils/bit.js +9 -9
- package/dist/esm/utils/fifo.d.ts +15 -15
- package/dist/esm/utils/fifo.js +52 -52
- package/dist/esm/utils/logging.d.ts +23 -23
- package/dist/esm/utils/logging.js +44 -44
- package/dist/esm/utils/pio-assembler.d.ts +45 -45
- package/dist/esm/utils/pio-assembler.js +75 -75
- package/dist/esm/utils/time.d.ts +2 -2
- package/dist/esm/utils/time.js +27 -27
- package/dist/esm/utils/timer32.d.ts +57 -57
- package/dist/esm/utils/timer32.js +203 -203
- package/package.json +38 -27
- package/dist/esm/package.json +0 -1
|
@@ -1,368 +1,368 @@
|
|
|
1
|
-
import { IRQ } from '../irq';
|
|
2
|
-
import { Timer32, Timer32PeriodicAlarm, TimerMode } from '../utils/timer32';
|
|
3
|
-
import { DREQChannel } from './dma';
|
|
4
|
-
import { BasePeripheral } from './peripheral';
|
|
5
|
-
/** Control and status register */
|
|
6
|
-
const CHn_CSR = 0x00;
|
|
7
|
-
/**
|
|
8
|
-
* INT and FRAC form a fixed-point fractional number.
|
|
9
|
-
* Counting rate is system clock frequency divided by this number.
|
|
10
|
-
* Fractional division uses simple 1st-order sigma-delta.
|
|
11
|
-
*/
|
|
12
|
-
const CHn_DIV = 0x04;
|
|
13
|
-
/** Direct access to the PWM counter */
|
|
14
|
-
const CHn_CTR = 0x08;
|
|
15
|
-
/** Counter compare values */
|
|
16
|
-
const CHn_CC = 0x0c;
|
|
17
|
-
/** Counter wrap value */
|
|
18
|
-
const CHn_TOP = 0x10;
|
|
19
|
-
/**
|
|
20
|
-
* This register aliases the CSR_EN bits for all channels.
|
|
21
|
-
* Writing to this register allows multiple channels to be enabled
|
|
22
|
-
* or disabled simultaneously, so they can run in perfect sync.
|
|
23
|
-
* For each channel, there is only one physical EN register bit,
|
|
24
|
-
* which can be accessed through here or CHx_CSR.
|
|
25
|
-
*/
|
|
26
|
-
const EN = 0xa0;
|
|
27
|
-
/** Raw Interrupts */
|
|
28
|
-
const INTR = 0xa4;
|
|
29
|
-
/** Interrupt Enable */
|
|
30
|
-
const INTE = 0xa8;
|
|
31
|
-
/** Interrupt Force */
|
|
32
|
-
const INTF = 0xac;
|
|
33
|
-
/** Interrupt status after masking & forcing */
|
|
34
|
-
const INTS = 0xb0;
|
|
35
|
-
const INT_MASK = 0xff;
|
|
36
|
-
/* CHn_CSR bits */
|
|
37
|
-
const CSR_PH_ADV = 1 << 7;
|
|
38
|
-
const CSR_PH_RET = 1 << 6;
|
|
39
|
-
const CSR_DIVMODE_SHIFT = 4;
|
|
40
|
-
const CSR_DIVMODE_MASK = 0x3;
|
|
41
|
-
const CSR_B_INV = 1 << 3;
|
|
42
|
-
const CSR_A_INV = 1 << 2;
|
|
43
|
-
const CSR_PH_CORRECT = 1 << 1;
|
|
44
|
-
const CSR_EN = 1 << 0;
|
|
45
|
-
var PWMDivMode;
|
|
46
|
-
(function (PWMDivMode) {
|
|
47
|
-
PWMDivMode[PWMDivMode["FreeRunning"] = 0] = "FreeRunning";
|
|
48
|
-
PWMDivMode[PWMDivMode["BGated"] = 1] = "BGated";
|
|
49
|
-
PWMDivMode[PWMDivMode["BRisingEdge"] = 2] = "BRisingEdge";
|
|
50
|
-
PWMDivMode[PWMDivMode["BFallingEdge"] = 3] = "BFallingEdge";
|
|
51
|
-
})(PWMDivMode || (PWMDivMode = {}));
|
|
52
|
-
class PWMChannel {
|
|
53
|
-
constructor(pwm, clock, index) {
|
|
54
|
-
this.pwm = pwm;
|
|
55
|
-
this.clock = clock;
|
|
56
|
-
this.index = index;
|
|
57
|
-
this.timer = new Timer32(this.clock, this.pwm.clockFreq);
|
|
58
|
-
this.alarmA = new Timer32PeriodicAlarm(this.timer, () => {
|
|
59
|
-
this.setA(false);
|
|
60
|
-
});
|
|
61
|
-
this.alarmB = new Timer32PeriodicAlarm(this.timer, () => {
|
|
62
|
-
this.setB(false);
|
|
63
|
-
});
|
|
64
|
-
this.alarmBottom = new Timer32PeriodicAlarm(this.timer, () => this.wrap());
|
|
65
|
-
this.csr = 0;
|
|
66
|
-
this.div = 0;
|
|
67
|
-
this.cc = 0;
|
|
68
|
-
this.top = 0;
|
|
69
|
-
this.lastBValue = false;
|
|
70
|
-
this.countingUp = true;
|
|
71
|
-
this.ccUpdated = false;
|
|
72
|
-
this.topUpdated = false;
|
|
73
|
-
this.tickCounter = 0;
|
|
74
|
-
this.divMode = PWMDivMode.FreeRunning;
|
|
75
|
-
// GPIO pin indices: Table 525. Mapping of PWM channels to GPIO pins on RP2040
|
|
76
|
-
this.pinA1 = this.index * 2;
|
|
77
|
-
this.pinB1 = this.index * 2 + 1;
|
|
78
|
-
this.pinA2 = this.index < 7 ? 16 + this.index * 2 : -1;
|
|
79
|
-
this.pinB2 = this.index < 7 ? 16 + this.index * 2 + 1 : -1;
|
|
80
|
-
this.alarmA.enable = true;
|
|
81
|
-
this.alarmB.enable = true;
|
|
82
|
-
this.alarmBottom.enable = true;
|
|
83
|
-
}
|
|
84
|
-
readRegister(offset) {
|
|
85
|
-
switch (offset) {
|
|
86
|
-
case CHn_CSR:
|
|
87
|
-
return this.csr;
|
|
88
|
-
case CHn_DIV:
|
|
89
|
-
return this.div;
|
|
90
|
-
case CHn_CTR:
|
|
91
|
-
return this.timer.counter;
|
|
92
|
-
case CHn_CC:
|
|
93
|
-
return this.cc;
|
|
94
|
-
case CHn_TOP:
|
|
95
|
-
return this.top;
|
|
96
|
-
}
|
|
97
|
-
/* Shouldn't get here */
|
|
98
|
-
return 0;
|
|
99
|
-
}
|
|
100
|
-
writeRegister(offset, value) {
|
|
101
|
-
switch (offset) {
|
|
102
|
-
case CHn_CSR:
|
|
103
|
-
if (value & CSR_EN && !(this.csr & CSR_EN)) {
|
|
104
|
-
this.updateDoubleBuffered();
|
|
105
|
-
}
|
|
106
|
-
this.csr = value & ~(CSR_PH_ADV | CSR_PH_RET);
|
|
107
|
-
if (this.csr & CSR_PH_ADV) {
|
|
108
|
-
this.timer.advance(1);
|
|
109
|
-
}
|
|
110
|
-
if (this.csr & CSR_PH_RET) {
|
|
111
|
-
this.timer.advance(-1);
|
|
112
|
-
}
|
|
113
|
-
this.divMode = (this.csr >> CSR_DIVMODE_SHIFT) & CSR_DIVMODE_MASK;
|
|
114
|
-
this.setBDirection(this.divMode === PWMDivMode.FreeRunning);
|
|
115
|
-
this.updateEnable();
|
|
116
|
-
this.lastBValue = this.gpioBValue;
|
|
117
|
-
this.timer.mode = value & CSR_PH_CORRECT ? TimerMode.ZigZag : TimerMode.Increment;
|
|
118
|
-
break;
|
|
119
|
-
case CHn_DIV: {
|
|
120
|
-
this.div = value & 1048575;
|
|
121
|
-
const intValue = (value >> 4) & 0xff;
|
|
122
|
-
const fracValue = value & 0xf;
|
|
123
|
-
this.timer.prescaler = (intValue ? intValue : 256) + fracValue / 16;
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
case CHn_CTR:
|
|
127
|
-
this.timer.set(value & 0xffff);
|
|
128
|
-
break;
|
|
129
|
-
case CHn_CC:
|
|
130
|
-
this.cc = value;
|
|
131
|
-
this.ccUpdated = true;
|
|
132
|
-
break;
|
|
133
|
-
case CHn_TOP:
|
|
134
|
-
this.top = value & 0xffff;
|
|
135
|
-
this.topUpdated = true;
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
reset() {
|
|
140
|
-
this.writeRegister(CHn_CSR, 0);
|
|
141
|
-
this.writeRegister(CHn_DIV, 0x01 << 4);
|
|
142
|
-
this.writeRegister(CHn_CTR, 0);
|
|
143
|
-
this.writeRegister(CHn_CC, 0);
|
|
144
|
-
this.writeRegister(CHn_TOP, 0xffff);
|
|
145
|
-
this.countingUp = true;
|
|
146
|
-
this.timer.enable = false;
|
|
147
|
-
this.timer.reset();
|
|
148
|
-
}
|
|
149
|
-
updateDoubleBuffered() {
|
|
150
|
-
if (this.ccUpdated) {
|
|
151
|
-
this.alarmB.target = this.cc >>> 16;
|
|
152
|
-
this.alarmA.target = this.cc & 0xffff;
|
|
153
|
-
this.ccUpdated = false;
|
|
154
|
-
}
|
|
155
|
-
if (this.topUpdated) {
|
|
156
|
-
this.timer.top = this.top;
|
|
157
|
-
this.topUpdated = false;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
wrap() {
|
|
161
|
-
this.pwm.channelInterrupt(this.index);
|
|
162
|
-
this.updateDoubleBuffered();
|
|
163
|
-
if (!(this.csr & CSR_PH_CORRECT)) {
|
|
164
|
-
this.setA(this.alarmA.target > 0);
|
|
165
|
-
this.setB(this.alarmB.target > 0);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
setA(value) {
|
|
169
|
-
if (this.csr & CSR_A_INV) {
|
|
170
|
-
value = !value;
|
|
171
|
-
}
|
|
172
|
-
this.pwm.gpioSet(this.pinA1, value);
|
|
173
|
-
if (this.pinA2 >= 0) {
|
|
174
|
-
this.pwm.gpioSet(this.pinA2, value);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
setB(value) {
|
|
178
|
-
if (this.csr & CSR_B_INV) {
|
|
179
|
-
value = !value;
|
|
180
|
-
}
|
|
181
|
-
this.pwm.gpioSet(this.pinB1, value);
|
|
182
|
-
if (this.pinB2 >= 0) {
|
|
183
|
-
this.pwm.gpioSet(this.pinB2, value);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
get gpioBValue() {
|
|
187
|
-
return (this.pwm.gpioRead(this.pinB1) || (this.pinB2 > 0 ? this.pwm.gpioRead(this.pinB2) : false));
|
|
188
|
-
}
|
|
189
|
-
setBDirection(value) {
|
|
190
|
-
this.pwm.gpioSetDir(this.pinB1, value);
|
|
191
|
-
if (this.pinB2 >= 0) {
|
|
192
|
-
this.pwm.gpioSetDir(this.pinB2, value);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
gpioBChanged() {
|
|
196
|
-
const value = this.gpioBValue;
|
|
197
|
-
if (value === this.lastBValue) {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
this.lastBValue = value;
|
|
201
|
-
switch (this.divMode) {
|
|
202
|
-
case PWMDivMode.BGated:
|
|
203
|
-
this.updateEnable();
|
|
204
|
-
break;
|
|
205
|
-
case PWMDivMode.BRisingEdge:
|
|
206
|
-
if (value) {
|
|
207
|
-
this.tickCounter++;
|
|
208
|
-
}
|
|
209
|
-
break;
|
|
210
|
-
case PWMDivMode.BFallingEdge:
|
|
211
|
-
if (!value) {
|
|
212
|
-
this.tickCounter++;
|
|
213
|
-
}
|
|
214
|
-
break;
|
|
215
|
-
}
|
|
216
|
-
if (this.tickCounter >= this.timer.prescaler) {
|
|
217
|
-
this.timer.advance(1);
|
|
218
|
-
this.tickCounter -= this.timer.prescaler;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
updateEnable() {
|
|
222
|
-
const { csr, divMode } = this;
|
|
223
|
-
const enable = !!(csr & CSR_EN);
|
|
224
|
-
this.timer.enable =
|
|
225
|
-
enable &&
|
|
226
|
-
(divMode === PWMDivMode.FreeRunning || (divMode === PWMDivMode.BGated && this.gpioBValue));
|
|
227
|
-
}
|
|
228
|
-
set en(value) {
|
|
229
|
-
if (value && !(this.csr & CSR_EN)) {
|
|
230
|
-
this.updateDoubleBuffered();
|
|
231
|
-
}
|
|
232
|
-
if (value) {
|
|
233
|
-
this.csr |= CSR_EN;
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
this.csr &= ~CSR_EN;
|
|
237
|
-
}
|
|
238
|
-
this.updateEnable();
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
export class RPPWM extends BasePeripheral {
|
|
242
|
-
constructor() {
|
|
243
|
-
super(...arguments);
|
|
244
|
-
this.channels = [
|
|
245
|
-
new PWMChannel(this, this.rp2040.clock, 0),
|
|
246
|
-
new PWMChannel(this, this.rp2040.clock, 1),
|
|
247
|
-
new PWMChannel(this, this.rp2040.clock, 2),
|
|
248
|
-
new PWMChannel(this, this.rp2040.clock, 3),
|
|
249
|
-
new PWMChannel(this, this.rp2040.clock, 4),
|
|
250
|
-
new PWMChannel(this, this.rp2040.clock, 5),
|
|
251
|
-
new PWMChannel(this, this.rp2040.clock, 6),
|
|
252
|
-
new PWMChannel(this, this.rp2040.clock, 7),
|
|
253
|
-
];
|
|
254
|
-
this.intRaw = 0;
|
|
255
|
-
this.intEnable = 0;
|
|
256
|
-
this.intForce = 0;
|
|
257
|
-
this.gpioValue = 0;
|
|
258
|
-
this.gpioDirection = 0;
|
|
259
|
-
}
|
|
260
|
-
get intStatus() {
|
|
261
|
-
return (this.intRaw & this.intEnable) | this.intForce;
|
|
262
|
-
}
|
|
263
|
-
readUint32(offset) {
|
|
264
|
-
if (offset < EN) {
|
|
265
|
-
const channel = Math.floor(offset / 0x14);
|
|
266
|
-
return this.channels[channel].readRegister(offset % 0x14);
|
|
267
|
-
}
|
|
268
|
-
switch (offset) {
|
|
269
|
-
case EN:
|
|
270
|
-
return ((this.channels[7].en << 7) |
|
|
271
|
-
(this.channels[6].en << 6) |
|
|
272
|
-
(this.channels[5].en << 5) |
|
|
273
|
-
(this.channels[4].en << 4) |
|
|
274
|
-
(this.channels[3].en << 3) |
|
|
275
|
-
(this.channels[2].en << 2) |
|
|
276
|
-
(this.channels[1].en << 1) |
|
|
277
|
-
(this.channels[0].en << 0));
|
|
278
|
-
case INTR:
|
|
279
|
-
return this.intRaw;
|
|
280
|
-
case INTE:
|
|
281
|
-
return this.intEnable;
|
|
282
|
-
case INTF:
|
|
283
|
-
return this.intForce;
|
|
284
|
-
case INTS:
|
|
285
|
-
return this.intStatus;
|
|
286
|
-
}
|
|
287
|
-
return super.readUint32(offset);
|
|
288
|
-
}
|
|
289
|
-
writeUint32(offset, value) {
|
|
290
|
-
if (offset < EN) {
|
|
291
|
-
const channel = Math.floor(offset / 0x14);
|
|
292
|
-
return this.channels[channel].writeRegister(offset % 0x14, value);
|
|
293
|
-
}
|
|
294
|
-
switch (offset) {
|
|
295
|
-
case EN:
|
|
296
|
-
this.channels[7].en = value & (1 << 7);
|
|
297
|
-
this.channels[6].en = value & (1 << 6);
|
|
298
|
-
this.channels[5].en = value & (1 << 5);
|
|
299
|
-
this.channels[4].en = value & (1 << 4);
|
|
300
|
-
this.channels[3].en = value & (1 << 3);
|
|
301
|
-
this.channels[2].en = value & (1 << 2);
|
|
302
|
-
this.channels[1].en = value & (1 << 1);
|
|
303
|
-
this.channels[0].en = value & (1 << 0);
|
|
304
|
-
break;
|
|
305
|
-
case INTR:
|
|
306
|
-
this.intRaw &= ~(value & INT_MASK);
|
|
307
|
-
this.checkInterrupts();
|
|
308
|
-
break;
|
|
309
|
-
case INTE:
|
|
310
|
-
this.intEnable = value & INT_MASK;
|
|
311
|
-
this.checkInterrupts();
|
|
312
|
-
break;
|
|
313
|
-
case INTF:
|
|
314
|
-
this.intForce = value & INT_MASK;
|
|
315
|
-
this.checkInterrupts();
|
|
316
|
-
break;
|
|
317
|
-
default:
|
|
318
|
-
super.writeUint32(offset, value);
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
get clockFreq() {
|
|
322
|
-
return this.rp2040.clkSys;
|
|
323
|
-
}
|
|
324
|
-
channelInterrupt(index) {
|
|
325
|
-
this.intRaw |= 1 << index;
|
|
326
|
-
this.checkInterrupts();
|
|
327
|
-
// We also set the DMA Request (DREQ) for the channel
|
|
328
|
-
this.rp2040.dma.setDREQ(DREQChannel.DREQ_PWM_WRAP0 + index);
|
|
329
|
-
}
|
|
330
|
-
checkInterrupts() {
|
|
331
|
-
this.rp2040.setInterrupt(IRQ.PWM_WRAP, !!this.intStatus);
|
|
332
|
-
}
|
|
333
|
-
gpioSet(index, value) {
|
|
334
|
-
const bit = 1 << index;
|
|
335
|
-
const newGpioValue = value ? this.gpioValue | bit : this.gpioValue & ~bit;
|
|
336
|
-
if (this.gpioValue != newGpioValue) {
|
|
337
|
-
this.gpioValue = newGpioValue;
|
|
338
|
-
this.rp2040.gpio[index].checkForUpdates();
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
gpioSetDir(index, output) {
|
|
342
|
-
const bit = 1 << index;
|
|
343
|
-
const newGpioDirection = output ? this.gpioDirection | bit : this.gpioDirection & ~bit;
|
|
344
|
-
if (this.gpioDirection != newGpioDirection) {
|
|
345
|
-
this.gpioDirection = newGpioDirection;
|
|
346
|
-
this.rp2040.gpio[index].checkForUpdates();
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
gpioRead(index) {
|
|
350
|
-
return this.rp2040.gpio[index].inputValue;
|
|
351
|
-
}
|
|
352
|
-
gpioOnInput(index) {
|
|
353
|
-
if (this.gpioDirection && 1 << index) {
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
for (const channel of this.channels) {
|
|
357
|
-
if (channel.pinB1 === index || channel.pinB2 === index) {
|
|
358
|
-
channel.gpioBChanged();
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
reset() {
|
|
363
|
-
this.gpioDirection = 0xffffffff;
|
|
364
|
-
for (const channel of this.channels) {
|
|
365
|
-
channel.reset();
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
1
|
+
import { IRQ } from '../irq.js';
|
|
2
|
+
import { Timer32, Timer32PeriodicAlarm, TimerMode } from '../utils/timer32.js';
|
|
3
|
+
import { DREQChannel } from './dma.js';
|
|
4
|
+
import { BasePeripheral } from './peripheral.js';
|
|
5
|
+
/** Control and status register */
|
|
6
|
+
const CHn_CSR = 0x00;
|
|
7
|
+
/**
|
|
8
|
+
* INT and FRAC form a fixed-point fractional number.
|
|
9
|
+
* Counting rate is system clock frequency divided by this number.
|
|
10
|
+
* Fractional division uses simple 1st-order sigma-delta.
|
|
11
|
+
*/
|
|
12
|
+
const CHn_DIV = 0x04;
|
|
13
|
+
/** Direct access to the PWM counter */
|
|
14
|
+
const CHn_CTR = 0x08;
|
|
15
|
+
/** Counter compare values */
|
|
16
|
+
const CHn_CC = 0x0c;
|
|
17
|
+
/** Counter wrap value */
|
|
18
|
+
const CHn_TOP = 0x10;
|
|
19
|
+
/**
|
|
20
|
+
* This register aliases the CSR_EN bits for all channels.
|
|
21
|
+
* Writing to this register allows multiple channels to be enabled
|
|
22
|
+
* or disabled simultaneously, so they can run in perfect sync.
|
|
23
|
+
* For each channel, there is only one physical EN register bit,
|
|
24
|
+
* which can be accessed through here or CHx_CSR.
|
|
25
|
+
*/
|
|
26
|
+
const EN = 0xa0;
|
|
27
|
+
/** Raw Interrupts */
|
|
28
|
+
const INTR = 0xa4;
|
|
29
|
+
/** Interrupt Enable */
|
|
30
|
+
const INTE = 0xa8;
|
|
31
|
+
/** Interrupt Force */
|
|
32
|
+
const INTF = 0xac;
|
|
33
|
+
/** Interrupt status after masking & forcing */
|
|
34
|
+
const INTS = 0xb0;
|
|
35
|
+
const INT_MASK = 0xff;
|
|
36
|
+
/* CHn_CSR bits */
|
|
37
|
+
const CSR_PH_ADV = 1 << 7;
|
|
38
|
+
const CSR_PH_RET = 1 << 6;
|
|
39
|
+
const CSR_DIVMODE_SHIFT = 4;
|
|
40
|
+
const CSR_DIVMODE_MASK = 0x3;
|
|
41
|
+
const CSR_B_INV = 1 << 3;
|
|
42
|
+
const CSR_A_INV = 1 << 2;
|
|
43
|
+
const CSR_PH_CORRECT = 1 << 1;
|
|
44
|
+
const CSR_EN = 1 << 0;
|
|
45
|
+
var PWMDivMode;
|
|
46
|
+
(function (PWMDivMode) {
|
|
47
|
+
PWMDivMode[PWMDivMode["FreeRunning"] = 0] = "FreeRunning";
|
|
48
|
+
PWMDivMode[PWMDivMode["BGated"] = 1] = "BGated";
|
|
49
|
+
PWMDivMode[PWMDivMode["BRisingEdge"] = 2] = "BRisingEdge";
|
|
50
|
+
PWMDivMode[PWMDivMode["BFallingEdge"] = 3] = "BFallingEdge";
|
|
51
|
+
})(PWMDivMode || (PWMDivMode = {}));
|
|
52
|
+
class PWMChannel {
|
|
53
|
+
constructor(pwm, clock, index) {
|
|
54
|
+
this.pwm = pwm;
|
|
55
|
+
this.clock = clock;
|
|
56
|
+
this.index = index;
|
|
57
|
+
this.timer = new Timer32(this.clock, this.pwm.clockFreq);
|
|
58
|
+
this.alarmA = new Timer32PeriodicAlarm(this.timer, () => {
|
|
59
|
+
this.setA(false);
|
|
60
|
+
});
|
|
61
|
+
this.alarmB = new Timer32PeriodicAlarm(this.timer, () => {
|
|
62
|
+
this.setB(false);
|
|
63
|
+
});
|
|
64
|
+
this.alarmBottom = new Timer32PeriodicAlarm(this.timer, () => this.wrap());
|
|
65
|
+
this.csr = 0;
|
|
66
|
+
this.div = 0;
|
|
67
|
+
this.cc = 0;
|
|
68
|
+
this.top = 0;
|
|
69
|
+
this.lastBValue = false;
|
|
70
|
+
this.countingUp = true;
|
|
71
|
+
this.ccUpdated = false;
|
|
72
|
+
this.topUpdated = false;
|
|
73
|
+
this.tickCounter = 0;
|
|
74
|
+
this.divMode = PWMDivMode.FreeRunning;
|
|
75
|
+
// GPIO pin indices: Table 525. Mapping of PWM channels to GPIO pins on RP2040
|
|
76
|
+
this.pinA1 = this.index * 2;
|
|
77
|
+
this.pinB1 = this.index * 2 + 1;
|
|
78
|
+
this.pinA2 = this.index < 7 ? 16 + this.index * 2 : -1;
|
|
79
|
+
this.pinB2 = this.index < 7 ? 16 + this.index * 2 + 1 : -1;
|
|
80
|
+
this.alarmA.enable = true;
|
|
81
|
+
this.alarmB.enable = true;
|
|
82
|
+
this.alarmBottom.enable = true;
|
|
83
|
+
}
|
|
84
|
+
readRegister(offset) {
|
|
85
|
+
switch (offset) {
|
|
86
|
+
case CHn_CSR:
|
|
87
|
+
return this.csr;
|
|
88
|
+
case CHn_DIV:
|
|
89
|
+
return this.div;
|
|
90
|
+
case CHn_CTR:
|
|
91
|
+
return this.timer.counter;
|
|
92
|
+
case CHn_CC:
|
|
93
|
+
return this.cc;
|
|
94
|
+
case CHn_TOP:
|
|
95
|
+
return this.top;
|
|
96
|
+
}
|
|
97
|
+
/* Shouldn't get here */
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
writeRegister(offset, value) {
|
|
101
|
+
switch (offset) {
|
|
102
|
+
case CHn_CSR:
|
|
103
|
+
if (value & CSR_EN && !(this.csr & CSR_EN)) {
|
|
104
|
+
this.updateDoubleBuffered();
|
|
105
|
+
}
|
|
106
|
+
this.csr = value & ~(CSR_PH_ADV | CSR_PH_RET);
|
|
107
|
+
if (this.csr & CSR_PH_ADV) {
|
|
108
|
+
this.timer.advance(1);
|
|
109
|
+
}
|
|
110
|
+
if (this.csr & CSR_PH_RET) {
|
|
111
|
+
this.timer.advance(-1);
|
|
112
|
+
}
|
|
113
|
+
this.divMode = (this.csr >> CSR_DIVMODE_SHIFT) & CSR_DIVMODE_MASK;
|
|
114
|
+
this.setBDirection(this.divMode === PWMDivMode.FreeRunning);
|
|
115
|
+
this.updateEnable();
|
|
116
|
+
this.lastBValue = this.gpioBValue;
|
|
117
|
+
this.timer.mode = value & CSR_PH_CORRECT ? TimerMode.ZigZag : TimerMode.Increment;
|
|
118
|
+
break;
|
|
119
|
+
case CHn_DIV: {
|
|
120
|
+
this.div = value & 1048575;
|
|
121
|
+
const intValue = (value >> 4) & 0xff;
|
|
122
|
+
const fracValue = value & 0xf;
|
|
123
|
+
this.timer.prescaler = (intValue ? intValue : 256) + fracValue / 16;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case CHn_CTR:
|
|
127
|
+
this.timer.set(value & 0xffff);
|
|
128
|
+
break;
|
|
129
|
+
case CHn_CC:
|
|
130
|
+
this.cc = value;
|
|
131
|
+
this.ccUpdated = true;
|
|
132
|
+
break;
|
|
133
|
+
case CHn_TOP:
|
|
134
|
+
this.top = value & 0xffff;
|
|
135
|
+
this.topUpdated = true;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
reset() {
|
|
140
|
+
this.writeRegister(CHn_CSR, 0);
|
|
141
|
+
this.writeRegister(CHn_DIV, 0x01 << 4);
|
|
142
|
+
this.writeRegister(CHn_CTR, 0);
|
|
143
|
+
this.writeRegister(CHn_CC, 0);
|
|
144
|
+
this.writeRegister(CHn_TOP, 0xffff);
|
|
145
|
+
this.countingUp = true;
|
|
146
|
+
this.timer.enable = false;
|
|
147
|
+
this.timer.reset();
|
|
148
|
+
}
|
|
149
|
+
updateDoubleBuffered() {
|
|
150
|
+
if (this.ccUpdated) {
|
|
151
|
+
this.alarmB.target = this.cc >>> 16;
|
|
152
|
+
this.alarmA.target = this.cc & 0xffff;
|
|
153
|
+
this.ccUpdated = false;
|
|
154
|
+
}
|
|
155
|
+
if (this.topUpdated) {
|
|
156
|
+
this.timer.top = this.top;
|
|
157
|
+
this.topUpdated = false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
wrap() {
|
|
161
|
+
this.pwm.channelInterrupt(this.index);
|
|
162
|
+
this.updateDoubleBuffered();
|
|
163
|
+
if (!(this.csr & CSR_PH_CORRECT)) {
|
|
164
|
+
this.setA(this.alarmA.target > 0);
|
|
165
|
+
this.setB(this.alarmB.target > 0);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
setA(value) {
|
|
169
|
+
if (this.csr & CSR_A_INV) {
|
|
170
|
+
value = !value;
|
|
171
|
+
}
|
|
172
|
+
this.pwm.gpioSet(this.pinA1, value);
|
|
173
|
+
if (this.pinA2 >= 0) {
|
|
174
|
+
this.pwm.gpioSet(this.pinA2, value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
setB(value) {
|
|
178
|
+
if (this.csr & CSR_B_INV) {
|
|
179
|
+
value = !value;
|
|
180
|
+
}
|
|
181
|
+
this.pwm.gpioSet(this.pinB1, value);
|
|
182
|
+
if (this.pinB2 >= 0) {
|
|
183
|
+
this.pwm.gpioSet(this.pinB2, value);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
get gpioBValue() {
|
|
187
|
+
return (this.pwm.gpioRead(this.pinB1) || (this.pinB2 > 0 ? this.pwm.gpioRead(this.pinB2) : false));
|
|
188
|
+
}
|
|
189
|
+
setBDirection(value) {
|
|
190
|
+
this.pwm.gpioSetDir(this.pinB1, value);
|
|
191
|
+
if (this.pinB2 >= 0) {
|
|
192
|
+
this.pwm.gpioSetDir(this.pinB2, value);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
gpioBChanged() {
|
|
196
|
+
const value = this.gpioBValue;
|
|
197
|
+
if (value === this.lastBValue) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
this.lastBValue = value;
|
|
201
|
+
switch (this.divMode) {
|
|
202
|
+
case PWMDivMode.BGated:
|
|
203
|
+
this.updateEnable();
|
|
204
|
+
break;
|
|
205
|
+
case PWMDivMode.BRisingEdge:
|
|
206
|
+
if (value) {
|
|
207
|
+
this.tickCounter++;
|
|
208
|
+
}
|
|
209
|
+
break;
|
|
210
|
+
case PWMDivMode.BFallingEdge:
|
|
211
|
+
if (!value) {
|
|
212
|
+
this.tickCounter++;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
if (this.tickCounter >= this.timer.prescaler) {
|
|
217
|
+
this.timer.advance(1);
|
|
218
|
+
this.tickCounter -= this.timer.prescaler;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
updateEnable() {
|
|
222
|
+
const { csr, divMode } = this;
|
|
223
|
+
const enable = !!(csr & CSR_EN);
|
|
224
|
+
this.timer.enable =
|
|
225
|
+
enable &&
|
|
226
|
+
(divMode === PWMDivMode.FreeRunning || (divMode === PWMDivMode.BGated && this.gpioBValue));
|
|
227
|
+
}
|
|
228
|
+
set en(value) {
|
|
229
|
+
if (value && !(this.csr & CSR_EN)) {
|
|
230
|
+
this.updateDoubleBuffered();
|
|
231
|
+
}
|
|
232
|
+
if (value) {
|
|
233
|
+
this.csr |= CSR_EN;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
this.csr &= ~CSR_EN;
|
|
237
|
+
}
|
|
238
|
+
this.updateEnable();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
export class RPPWM extends BasePeripheral {
|
|
242
|
+
constructor() {
|
|
243
|
+
super(...arguments);
|
|
244
|
+
this.channels = [
|
|
245
|
+
new PWMChannel(this, this.rp2040.clock, 0),
|
|
246
|
+
new PWMChannel(this, this.rp2040.clock, 1),
|
|
247
|
+
new PWMChannel(this, this.rp2040.clock, 2),
|
|
248
|
+
new PWMChannel(this, this.rp2040.clock, 3),
|
|
249
|
+
new PWMChannel(this, this.rp2040.clock, 4),
|
|
250
|
+
new PWMChannel(this, this.rp2040.clock, 5),
|
|
251
|
+
new PWMChannel(this, this.rp2040.clock, 6),
|
|
252
|
+
new PWMChannel(this, this.rp2040.clock, 7),
|
|
253
|
+
];
|
|
254
|
+
this.intRaw = 0;
|
|
255
|
+
this.intEnable = 0;
|
|
256
|
+
this.intForce = 0;
|
|
257
|
+
this.gpioValue = 0;
|
|
258
|
+
this.gpioDirection = 0;
|
|
259
|
+
}
|
|
260
|
+
get intStatus() {
|
|
261
|
+
return (this.intRaw & this.intEnable) | this.intForce;
|
|
262
|
+
}
|
|
263
|
+
readUint32(offset) {
|
|
264
|
+
if (offset < EN) {
|
|
265
|
+
const channel = Math.floor(offset / 0x14);
|
|
266
|
+
return this.channels[channel].readRegister(offset % 0x14);
|
|
267
|
+
}
|
|
268
|
+
switch (offset) {
|
|
269
|
+
case EN:
|
|
270
|
+
return ((this.channels[7].en << 7) |
|
|
271
|
+
(this.channels[6].en << 6) |
|
|
272
|
+
(this.channels[5].en << 5) |
|
|
273
|
+
(this.channels[4].en << 4) |
|
|
274
|
+
(this.channels[3].en << 3) |
|
|
275
|
+
(this.channels[2].en << 2) |
|
|
276
|
+
(this.channels[1].en << 1) |
|
|
277
|
+
(this.channels[0].en << 0));
|
|
278
|
+
case INTR:
|
|
279
|
+
return this.intRaw;
|
|
280
|
+
case INTE:
|
|
281
|
+
return this.intEnable;
|
|
282
|
+
case INTF:
|
|
283
|
+
return this.intForce;
|
|
284
|
+
case INTS:
|
|
285
|
+
return this.intStatus;
|
|
286
|
+
}
|
|
287
|
+
return super.readUint32(offset);
|
|
288
|
+
}
|
|
289
|
+
writeUint32(offset, value) {
|
|
290
|
+
if (offset < EN) {
|
|
291
|
+
const channel = Math.floor(offset / 0x14);
|
|
292
|
+
return this.channels[channel].writeRegister(offset % 0x14, value);
|
|
293
|
+
}
|
|
294
|
+
switch (offset) {
|
|
295
|
+
case EN:
|
|
296
|
+
this.channels[7].en = value & (1 << 7);
|
|
297
|
+
this.channels[6].en = value & (1 << 6);
|
|
298
|
+
this.channels[5].en = value & (1 << 5);
|
|
299
|
+
this.channels[4].en = value & (1 << 4);
|
|
300
|
+
this.channels[3].en = value & (1 << 3);
|
|
301
|
+
this.channels[2].en = value & (1 << 2);
|
|
302
|
+
this.channels[1].en = value & (1 << 1);
|
|
303
|
+
this.channels[0].en = value & (1 << 0);
|
|
304
|
+
break;
|
|
305
|
+
case INTR:
|
|
306
|
+
this.intRaw &= ~(value & INT_MASK);
|
|
307
|
+
this.checkInterrupts();
|
|
308
|
+
break;
|
|
309
|
+
case INTE:
|
|
310
|
+
this.intEnable = value & INT_MASK;
|
|
311
|
+
this.checkInterrupts();
|
|
312
|
+
break;
|
|
313
|
+
case INTF:
|
|
314
|
+
this.intForce = value & INT_MASK;
|
|
315
|
+
this.checkInterrupts();
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
super.writeUint32(offset, value);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
get clockFreq() {
|
|
322
|
+
return this.rp2040.clkSys;
|
|
323
|
+
}
|
|
324
|
+
channelInterrupt(index) {
|
|
325
|
+
this.intRaw |= 1 << index;
|
|
326
|
+
this.checkInterrupts();
|
|
327
|
+
// We also set the DMA Request (DREQ) for the channel
|
|
328
|
+
this.rp2040.dma.setDREQ(DREQChannel.DREQ_PWM_WRAP0 + index);
|
|
329
|
+
}
|
|
330
|
+
checkInterrupts() {
|
|
331
|
+
this.rp2040.setInterrupt(IRQ.PWM_WRAP, !!this.intStatus);
|
|
332
|
+
}
|
|
333
|
+
gpioSet(index, value) {
|
|
334
|
+
const bit = 1 << index;
|
|
335
|
+
const newGpioValue = value ? this.gpioValue | bit : this.gpioValue & ~bit;
|
|
336
|
+
if (this.gpioValue != newGpioValue) {
|
|
337
|
+
this.gpioValue = newGpioValue;
|
|
338
|
+
this.rp2040.gpio[index].checkForUpdates();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
gpioSetDir(index, output) {
|
|
342
|
+
const bit = 1 << index;
|
|
343
|
+
const newGpioDirection = output ? this.gpioDirection | bit : this.gpioDirection & ~bit;
|
|
344
|
+
if (this.gpioDirection != newGpioDirection) {
|
|
345
|
+
this.gpioDirection = newGpioDirection;
|
|
346
|
+
this.rp2040.gpio[index].checkForUpdates();
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
gpioRead(index) {
|
|
350
|
+
return this.rp2040.gpio[index].inputValue;
|
|
351
|
+
}
|
|
352
|
+
gpioOnInput(index) {
|
|
353
|
+
if (this.gpioDirection && 1 << index) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
for (const channel of this.channels) {
|
|
357
|
+
if (channel.pinB1 === index || channel.pinB2 === index) {
|
|
358
|
+
channel.gpioBChanged();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
reset() {
|
|
363
|
+
this.gpioDirection = 0xffffffff;
|
|
364
|
+
for (const channel of this.channels) {
|
|
365
|
+
channel.reset();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|