rp2040js 0.17.2 → 0.17.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.
@@ -96,8 +96,8 @@ class RPSPI extends peripheral_1.BasePeripheral {
96
96
  doTX() {
97
97
  if (!this.busy && !this.txFIFO.empty) {
98
98
  const value = this.txFIFO.pull();
99
- this.onTransmit(value);
100
99
  this.busy = true;
100
+ this.onTransmit(value);
101
101
  this.fifosUpdated();
102
102
  }
103
103
  }
@@ -8,10 +8,16 @@ const EP1_IN_CONTROL = 0x8;
8
8
  const EP0_IN_BUFFER_CONTROL = 0x80;
9
9
  const EP0_OUT_BUFFER_CONTROL = 0x84;
10
10
  const EP15_OUT_BUFFER_CONTROL = 0xfc;
11
+ // Endpoint Control bits
12
+ const USB_CTRL_DOUBLE_BUF = 1 << 30;
13
+ const USB_CTRL_INTERRUPT_PER_TRANSFER = 1 << 29;
11
14
  // Buffer Control bits
12
15
  const USB_BUF_CTRL_AVAILABLE = 1 << 10;
13
16
  const USB_BUF_CTRL_FULL = 1 << 15;
14
17
  const USB_BUF_CTRL_LEN_MASK = 0x3ff;
18
+ // Buffer1
19
+ const USB_BUF1_SHIFT = 16;
20
+ const USB_BUF1_OFFSET = 64;
15
21
  // USB Peripheral Register
16
22
  const MAIN_CTRL = 0x40;
17
23
  const SIE_STATUS = 0x50;
@@ -161,12 +167,19 @@ class RPUSBController extends peripheral_1.BasePeripheral {
161
167
  return this.readEndpointControlReg(endpoint, out) & 0xffc0;
162
168
  }
163
169
  DPRAMUpdated(offset, value) {
164
- var _a, _b;
170
+ var _a, _b, _c, _d;
165
171
  if (value & USB_BUF_CTRL_AVAILABLE &&
166
172
  offset >= EP0_IN_BUFFER_CONTROL &&
167
173
  offset <= EP15_OUT_BUFFER_CONTROL) {
168
174
  const endpoint = (offset - EP0_IN_BUFFER_CONTROL) >> 3;
169
175
  const bufferOut = offset & 4 ? true : false;
176
+ let doubleBuffer = false;
177
+ let interrupt = true;
178
+ if (endpoint != 0) {
179
+ const control = this.readEndpointControlReg(endpoint, bufferOut);
180
+ doubleBuffer = !!(control & USB_CTRL_DOUBLE_BUF);
181
+ interrupt = !!(control & USB_CTRL_INTERRUPT_PER_TRANSFER);
182
+ }
170
183
  const bufferLength = value & USB_BUF_CTRL_LEN_MASK;
171
184
  const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut);
172
185
  this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
@@ -179,7 +192,9 @@ class RPUSBController extends peripheral_1.BasePeripheral {
179
192
  value &= ~USB_BUF_CTRL_FULL;
180
193
  this.rp2040.usbDPRAMView.setUint32(offset, value, true);
181
194
  const buffer = this.rp2040.usbDPRAM.slice(bufferOffset, bufferOffset + bufferLength);
182
- this.indicateBufferReady(endpoint, false);
195
+ if (interrupt || !doubleBuffer) {
196
+ this.indicateBufferReady(endpoint, false);
197
+ }
183
198
  if (this.writeDelayMicroseconds) {
184
199
  this.rp2040.clock.createTimer(this.writeDelayMicroseconds, () => {
185
200
  var _a;
@@ -190,6 +205,31 @@ class RPUSBController extends peripheral_1.BasePeripheral {
190
205
  (_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
191
206
  }
192
207
  }
208
+ if (doubleBuffer && ((value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE)) {
209
+ const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
210
+ const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
211
+ this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
212
+ value &= ~(USB_BUF_CTRL_AVAILABLE << USB_BUF1_SHIFT);
213
+ this.rp2040.usbDPRAMView.setUint32(offset, value, true);
214
+ if (bufferOut) {
215
+ (_c = this.onEndpointRead) === null || _c === void 0 ? void 0 : _c.call(this, endpoint, bufferLength);
216
+ }
217
+ else {
218
+ value &= ~(USB_BUF_CTRL_FULL << USB_BUF1_SHIFT);
219
+ this.rp2040.usbDPRAMView.setUint32(offset, value, true);
220
+ const buffer = this.rp2040.usbDPRAM.slice(bufferOffset, bufferOffset + bufferLength);
221
+ this.indicateBufferReady(endpoint, false);
222
+ if (this.writeDelayMicroseconds) {
223
+ this.rp2040.clock.createTimer(this.writeDelayMicroseconds, () => {
224
+ var _a;
225
+ (_a = this.onEndpointWrite) === null || _a === void 0 ? void 0 : _a.call(this, endpoint, buffer);
226
+ });
227
+ }
228
+ else {
229
+ (_d = this.onEndpointWrite) === null || _d === void 0 ? void 0 : _d.call(this, endpoint, buffer);
230
+ }
231
+ }
232
+ }
193
233
  }
194
234
  }
195
235
  endpointReadDone(endpoint, buffer, delay = this.readDelayMicroseconds) {
@@ -93,8 +93,8 @@ export class RPSPI extends BasePeripheral {
93
93
  doTX() {
94
94
  if (!this.busy && !this.txFIFO.empty) {
95
95
  const value = this.txFIFO.pull();
96
- this.onTransmit(value);
97
96
  this.busy = true;
97
+ this.onTransmit(value);
98
98
  this.fifosUpdated();
99
99
  }
100
100
  }
@@ -5,10 +5,16 @@ const EP1_IN_CONTROL = 0x8;
5
5
  const EP0_IN_BUFFER_CONTROL = 0x80;
6
6
  const EP0_OUT_BUFFER_CONTROL = 0x84;
7
7
  const EP15_OUT_BUFFER_CONTROL = 0xfc;
8
+ // Endpoint Control bits
9
+ const USB_CTRL_DOUBLE_BUF = 1 << 30;
10
+ const USB_CTRL_INTERRUPT_PER_TRANSFER = 1 << 29;
8
11
  // Buffer Control bits
9
12
  const USB_BUF_CTRL_AVAILABLE = 1 << 10;
10
13
  const USB_BUF_CTRL_FULL = 1 << 15;
11
14
  const USB_BUF_CTRL_LEN_MASK = 0x3ff;
15
+ // Buffer1
16
+ const USB_BUF1_SHIFT = 16;
17
+ const USB_BUF1_OFFSET = 64;
12
18
  // USB Peripheral Register
13
19
  const MAIN_CTRL = 0x40;
14
20
  const SIE_STATUS = 0x50;
@@ -158,12 +164,19 @@ export class RPUSBController extends BasePeripheral {
158
164
  return this.readEndpointControlReg(endpoint, out) & 0xffc0;
159
165
  }
160
166
  DPRAMUpdated(offset, value) {
161
- var _a, _b;
167
+ var _a, _b, _c, _d;
162
168
  if (value & USB_BUF_CTRL_AVAILABLE &&
163
169
  offset >= EP0_IN_BUFFER_CONTROL &&
164
170
  offset <= EP15_OUT_BUFFER_CONTROL) {
165
171
  const endpoint = (offset - EP0_IN_BUFFER_CONTROL) >> 3;
166
172
  const bufferOut = offset & 4 ? true : false;
173
+ let doubleBuffer = false;
174
+ let interrupt = true;
175
+ if (endpoint != 0) {
176
+ const control = this.readEndpointControlReg(endpoint, bufferOut);
177
+ doubleBuffer = !!(control & USB_CTRL_DOUBLE_BUF);
178
+ interrupt = !!(control & USB_CTRL_INTERRUPT_PER_TRANSFER);
179
+ }
167
180
  const bufferLength = value & USB_BUF_CTRL_LEN_MASK;
168
181
  const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut);
169
182
  this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
@@ -176,7 +189,9 @@ export class RPUSBController extends BasePeripheral {
176
189
  value &= ~USB_BUF_CTRL_FULL;
177
190
  this.rp2040.usbDPRAMView.setUint32(offset, value, true);
178
191
  const buffer = this.rp2040.usbDPRAM.slice(bufferOffset, bufferOffset + bufferLength);
179
- this.indicateBufferReady(endpoint, false);
192
+ if (interrupt || !doubleBuffer) {
193
+ this.indicateBufferReady(endpoint, false);
194
+ }
180
195
  if (this.writeDelayMicroseconds) {
181
196
  this.rp2040.clock.createTimer(this.writeDelayMicroseconds, () => {
182
197
  var _a;
@@ -187,6 +202,31 @@ export class RPUSBController extends BasePeripheral {
187
202
  (_b = this.onEndpointWrite) === null || _b === void 0 ? void 0 : _b.call(this, endpoint, buffer);
188
203
  }
189
204
  }
205
+ if (doubleBuffer && ((value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_AVAILABLE)) {
206
+ const bufferLength = (value >> USB_BUF1_SHIFT) & USB_BUF_CTRL_LEN_MASK;
207
+ const bufferOffset = this.getEndpointBufferOffset(endpoint, bufferOut) + USB_BUF1_OFFSET;
208
+ this.debug(`Start USB transfer, endPoint=${endpoint}, direction=${bufferOut ? 'out' : 'in'} buffer=${bufferOffset.toString(16)} length=${bufferLength}`);
209
+ value &= ~(USB_BUF_CTRL_AVAILABLE << USB_BUF1_SHIFT);
210
+ this.rp2040.usbDPRAMView.setUint32(offset, value, true);
211
+ if (bufferOut) {
212
+ (_c = this.onEndpointRead) === null || _c === void 0 ? void 0 : _c.call(this, endpoint, bufferLength);
213
+ }
214
+ else {
215
+ value &= ~(USB_BUF_CTRL_FULL << USB_BUF1_SHIFT);
216
+ this.rp2040.usbDPRAMView.setUint32(offset, value, true);
217
+ const buffer = this.rp2040.usbDPRAM.slice(bufferOffset, bufferOffset + bufferLength);
218
+ this.indicateBufferReady(endpoint, false);
219
+ if (this.writeDelayMicroseconds) {
220
+ this.rp2040.clock.createTimer(this.writeDelayMicroseconds, () => {
221
+ var _a;
222
+ (_a = this.onEndpointWrite) === null || _a === void 0 ? void 0 : _a.call(this, endpoint, buffer);
223
+ });
224
+ }
225
+ else {
226
+ (_d = this.onEndpointWrite) === null || _d === void 0 ? void 0 : _d.call(this, endpoint, buffer);
227
+ }
228
+ }
229
+ }
190
230
  }
191
231
  }
192
232
  endpointReadDone(endpoint, buffer, delay = this.readDelayMicroseconds) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "0.17.2",
3
+ "version": "0.17.4",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [