rp2040js 1.0.2 → 1.1.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.
@@ -4,7 +4,8 @@ export declare enum GPIOPinState {
4
4
  High = 1,
5
5
  Input = 2,
6
6
  InputPullUp = 3,
7
- InputPullDown = 4
7
+ InputPullDown = 4,
8
+ InputBusKeeper = 5
8
9
  }
9
10
  export declare const FUNCTION_PWM = 4;
10
11
  export declare const FUNCTION_SIO = 5;
@@ -9,6 +9,7 @@ var GPIOPinState;
9
9
  GPIOPinState[GPIOPinState["Input"] = 2] = "Input";
10
10
  GPIOPinState[GPIOPinState["InputPullUp"] = 3] = "InputPullUp";
11
11
  GPIOPinState[GPIOPinState["InputPullDown"] = 4] = "InputPullDown";
12
+ GPIOPinState[GPIOPinState["InputBusKeeper"] = 5] = "InputBusKeeper";
12
13
  })(GPIOPinState || (exports.GPIOPinState = GPIOPinState = {}));
13
14
  exports.FUNCTION_PWM = 4;
14
15
  exports.FUNCTION_SIO = 5;
@@ -149,10 +150,15 @@ class GPIOPin {
149
150
  }
150
151
  else {
151
152
  // TODO: check what happens when we enable both pullup/pulldown
152
- if (this.pulldownEnabled) {
153
+ // ANSWER: It is valid, see: 2.19.4.1. Bus Keeper Mode, datasheet p240
154
+ if (this.pulldownEnabled && this.pullupEnabled) {
155
+ // Pull high when high, pull low when low:
156
+ return GPIOPinState.InputBusKeeper;
157
+ }
158
+ else if (this.pulldownEnabled) {
153
159
  return GPIOPinState.InputPullDown;
154
160
  }
155
- if (this.pullupEnabled) {
161
+ else if (this.pullupEnabled) {
156
162
  return GPIOPinState.InputPullUp;
157
163
  }
158
164
  return GPIOPinState.Input;
@@ -1,8 +1,26 @@
1
1
  import { RP2040 } from '../rp2040.js';
2
2
  import { BasePeripheral, Peripheral } from './peripheral.js';
3
3
  export declare class RPClocks extends BasePeripheral implements Peripheral {
4
+ gpout0Ctrl: number;
5
+ gpout0Div: number;
6
+ gpout1Ctrl: number;
7
+ gpout1Div: number;
8
+ gpout2Ctrl: number;
9
+ gpout2Div: number;
10
+ gpout3Ctrl: number;
11
+ gpout3Div: number;
4
12
  refCtrl: number;
13
+ refDiv: number;
14
+ periCtrl: number;
15
+ periDiv: number;
16
+ usbCtrl: number;
17
+ usbDiv: number;
5
18
  sysCtrl: number;
19
+ sysDiv: number;
20
+ adcCtrl: number;
21
+ adcDiv: number;
22
+ rtcCtrl: number;
23
+ rtcDiv: number;
6
24
  constructor(rp2040: RP2040, name: string);
7
25
  readUint32(offset: number): number;
8
26
  writeUint32(offset: number, value: number): void;
@@ -2,37 +2,195 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RPClocks = void 0;
4
4
  const peripheral_js_1 = require("./peripheral.js");
5
+ const CLK_GPOUT0_CTRL = 0x00;
6
+ const CLK_GPOUT0_DIV = 0x04;
7
+ const CLK_GPOUT0_SELECTED = 0x8;
8
+ const CLK_GPOUT1_CTRL = 0x0c;
9
+ const CLK_GPOUT1_DIV = 0x10;
10
+ const CLK_GPOUT1_SELECTED = 0x14;
11
+ const CLK_GPOUT2_CTRL = 0x18;
12
+ const CLK_GPOUT2_DIV = 0x01c;
13
+ const CLK_GPOUT2_SELECTED = 0x20;
14
+ const CLK_GPOUT3_CTRL = 0x24;
15
+ const CLK_GPOUT3_DIV = 0x28;
16
+ const CLK_GPOUT3_SELECTED = 0x2c;
5
17
  const CLK_REF_CTRL = 0x30;
18
+ const CLK_REF_DIV = 0x34;
6
19
  const CLK_REF_SELECTED = 0x38;
7
20
  const CLK_SYS_CTRL = 0x3c;
21
+ const CLK_SYS_DIV = 0x40;
8
22
  const CLK_SYS_SELECTED = 0x44;
23
+ const CLK_PERI_CTRL = 0x48;
24
+ const CLK_PERI_DIV = 0x4c;
25
+ const CLK_PERI_SELECTED = 0x50;
26
+ const CLK_USB_CTRL = 0x54;
27
+ const CLK_USB_DIV = 0x58;
28
+ const CLK_USB_SELECTED = 0x5c;
29
+ const CLK_ADC_CTRL = 0x60;
30
+ const CLK_ADC_DIV = 0x64;
31
+ const CLK_ADC_SELECTED = 0x68;
32
+ const CLK_RTC_CTRL = 0x6c;
33
+ const CLK_RTC_DIV = 0x70;
34
+ const CLK_RTC_SELECTED = 0x74;
35
+ const CLK_SYS_RESUS_CTRL = 0x78;
36
+ const CLK_SYS_RESUS_STATUS = 0x7c;
9
37
  class RPClocks extends peripheral_js_1.BasePeripheral {
10
38
  constructor(rp2040, name) {
11
39
  super(rp2040, name);
40
+ this.gpout0Ctrl = 0;
41
+ this.gpout0Div = 0x100;
42
+ this.gpout1Ctrl = 0;
43
+ this.gpout1Div = 0x100;
44
+ this.gpout2Ctrl = 0;
45
+ this.gpout2Div = 0x100;
46
+ this.gpout3Ctrl = 0;
47
+ this.gpout3Div = 0x100;
12
48
  this.refCtrl = 0;
49
+ this.refDiv = 0x100;
50
+ this.periCtrl = 0;
51
+ this.periDiv = 0x100;
52
+ this.usbCtrl = 0;
53
+ this.usbDiv = 0x100;
13
54
  this.sysCtrl = 0;
55
+ this.sysDiv = 0x100;
56
+ this.adcCtrl = 0;
57
+ this.adcDiv = 0x100;
58
+ this.rtcCtrl = 0;
59
+ this.rtcDiv = 0x100;
14
60
  }
15
61
  readUint32(offset) {
16
62
  switch (offset) {
63
+ case CLK_GPOUT0_CTRL:
64
+ return this.gpout0Ctrl & 0b100110001110111100000;
65
+ case CLK_GPOUT0_DIV:
66
+ return this.gpout0Div;
67
+ case CLK_GPOUT0_SELECTED:
68
+ return 1;
69
+ case CLK_GPOUT1_CTRL:
70
+ return this.gpout1Ctrl & 0b100110001110111100000;
71
+ case CLK_GPOUT1_DIV:
72
+ return this.gpout1Div;
73
+ case CLK_GPOUT1_SELECTED:
74
+ return 1;
75
+ case CLK_GPOUT2_CTRL:
76
+ return this.gpout2Ctrl & 0b100110001110111100000;
77
+ case CLK_GPOUT2_DIV:
78
+ return this.gpout2Div;
79
+ case CLK_GPOUT2_SELECTED:
80
+ return 1;
81
+ case CLK_GPOUT3_CTRL:
82
+ return this.gpout3Ctrl & 0b100110001110111100000;
83
+ case CLK_GPOUT3_DIV:
84
+ return this.gpout3Div;
85
+ case CLK_GPOUT3_SELECTED:
86
+ return 1;
17
87
  case CLK_REF_CTRL:
18
- return this.refCtrl;
88
+ return this.refCtrl & 0b000001100011;
89
+ case CLK_REF_DIV:
90
+ return this.refDiv & 0x30; // b8..9 = int divisor. no frac divisor present
19
91
  case CLK_REF_SELECTED:
20
92
  return 1 << (this.refCtrl & 0x03);
21
93
  case CLK_SYS_CTRL:
22
- return this.sysCtrl;
94
+ return this.sysCtrl & 0b000011100001;
95
+ case CLK_SYS_DIV:
96
+ return this.sysDiv;
23
97
  case CLK_SYS_SELECTED:
24
98
  return 1 << (this.sysCtrl & 0x01);
99
+ case CLK_PERI_CTRL:
100
+ return this.periCtrl & 0b110011100000;
101
+ case CLK_PERI_DIV:
102
+ return this.periDiv;
103
+ case CLK_PERI_SELECTED:
104
+ return 1;
105
+ case CLK_USB_CTRL:
106
+ return this.usbCtrl & 0b100110000110011100000;
107
+ case CLK_USB_DIV:
108
+ return this.usbDiv;
109
+ case CLK_USB_SELECTED:
110
+ return 1;
111
+ case CLK_ADC_CTRL:
112
+ return this.adcCtrl & 0b100110000110011100000;
113
+ case CLK_ADC_DIV:
114
+ return this.adcDiv & 0x30;
115
+ case CLK_ADC_SELECTED:
116
+ return 1;
117
+ case CLK_RTC_CTRL:
118
+ return this.rtcCtrl & 0b100110000110011100000;
119
+ case CLK_RTC_DIV:
120
+ return this.rtcDiv & 0x30;
121
+ case CLK_RTC_SELECTED:
122
+ return 1;
123
+ case CLK_SYS_RESUS_CTRL:
124
+ return 0xff;
125
+ case CLK_SYS_RESUS_STATUS:
126
+ return 0; /* clock resus not implemented */
25
127
  }
26
128
  return super.readUint32(offset);
27
129
  }
28
130
  writeUint32(offset, value) {
29
131
  switch (offset) {
132
+ case CLK_GPOUT0_CTRL:
133
+ this.gpout0Ctrl = value;
134
+ break;
135
+ case CLK_GPOUT0_DIV:
136
+ this.gpout0Div = value;
137
+ break;
138
+ case CLK_GPOUT1_CTRL:
139
+ this.gpout1Ctrl = value;
140
+ break;
141
+ case CLK_GPOUT1_DIV:
142
+ this.gpout1Div = value;
143
+ break;
144
+ case CLK_GPOUT2_CTRL:
145
+ this.gpout2Ctrl = value;
146
+ break;
147
+ case CLK_GPOUT2_DIV:
148
+ this.gpout2Div = value;
149
+ break;
150
+ case CLK_GPOUT3_CTRL:
151
+ this.gpout3Ctrl = value;
152
+ break;
153
+ case CLK_GPOUT3_DIV:
154
+ this.gpout3Div = value;
155
+ break;
30
156
  case CLK_REF_CTRL:
31
157
  this.refCtrl = value;
32
158
  break;
159
+ case CLK_REF_DIV:
160
+ this.refDiv = value;
161
+ break;
33
162
  case CLK_SYS_CTRL:
34
163
  this.sysCtrl = value;
35
164
  break;
165
+ case CLK_SYS_DIV:
166
+ this.sysDiv = value;
167
+ break;
168
+ case CLK_PERI_CTRL:
169
+ this.periCtrl = value;
170
+ break;
171
+ case CLK_PERI_DIV:
172
+ this.periDiv = value;
173
+ break;
174
+ case CLK_USB_CTRL:
175
+ this.usbCtrl = value;
176
+ break;
177
+ case CLK_USB_DIV:
178
+ this.usbDiv = value;
179
+ break;
180
+ case CLK_ADC_CTRL:
181
+ this.adcCtrl = value;
182
+ break;
183
+ case CLK_ADC_DIV:
184
+ this.adcDiv = value;
185
+ break;
186
+ case CLK_RTC_CTRL:
187
+ this.rtcCtrl = value;
188
+ break;
189
+ case CLK_RTC_DIV:
190
+ this.rtcDiv = value;
191
+ break;
192
+ case CLK_SYS_RESUS_CTRL:
193
+ return; /* clock resus not implemented */
36
194
  default:
37
195
  super.writeUint32(offset, value);
38
196
  break;
@@ -37,6 +37,7 @@ export declare class RPI2C extends BasePeripheral implements Peripheral {
37
37
  abortSource: number;
38
38
  intRaw: number;
39
39
  intEnable: number;
40
+ private spikelen;
40
41
  get intStatus(): number;
41
42
  get speed(): I2CSpeed;
42
43
  get sclLowPeriod(): number;
@@ -180,6 +180,7 @@ class RPI2C extends peripheral_js_1.BasePeripheral {
180
180
  this.abortSource = 0;
181
181
  this.intRaw = 0;
182
182
  this.intEnable = 0;
183
+ this.spikelen = 0x07;
183
184
  }
184
185
  checkInterrupts() {
185
186
  this.rp2040.setInterrupt(this.irq, !!this.intStatus);
@@ -396,11 +397,18 @@ class RPI2C extends peripheral_js_1.BasePeripheral {
396
397
  return this.txFIFO.itemCount;
397
398
  case IC_RXFLR:
398
399
  return this.rxFIFO.itemCount;
400
+ case IC_SDA_HOLD:
401
+ return 0x01;
399
402
  case IC_TX_ABRT_SOURCE: {
400
403
  const value = this.abortSource;
401
404
  this.abortSource &= ABRT_SBYTE_NORSTRT; // Clear IC_TX_ABRT_SOURCE, expect for bit 9
402
405
  return value;
403
406
  }
407
+ case IC_ENABLE_STATUS:
408
+ // I2C status - read only. bit 0 reflects IC_ENABLE, bit 1,2 relate to i2c slave mode.
409
+ return this.enable & 0x1;
410
+ case IC_FS_SPKLEN:
411
+ return this.spikelen & 0xff;
404
412
  case IC_COMP_PARAM_1:
405
413
  // From the datasheet:
406
414
  // Note This register is not implemented and therefore reads as 0. If it was implemented it would be a constant read-only
@@ -449,6 +457,13 @@ class RPI2C extends peripheral_js_1.BasePeripheral {
449
457
  case IC_FS_SCL_LCNT:
450
458
  this.fsClockLowPeriod = value & 0xffff;
451
459
  return;
460
+ case IC_SDA_HOLD:
461
+ if (!(value & ENABLE)) {
462
+ if (value != 0x1) {
463
+ this.warn('Unimplemented write to IC_SDA_HOLD');
464
+ }
465
+ }
466
+ return;
452
467
  case IC_RX_TL:
453
468
  this.rxThreshold = value & 0xff;
454
469
  if (this.rxThreshold > this.rxFIFO.size) {
@@ -480,6 +495,11 @@ class RPI2C extends peripheral_js_1.BasePeripheral {
480
495
  this.enable = value;
481
496
  this.nextCommand(); // TX_CMD_BLOCK may have changed
482
497
  return;
498
+ case IC_FS_SPKLEN:
499
+ if (!(value & ENABLE) && value > 0) {
500
+ this.spikelen = value;
501
+ }
502
+ return;
483
503
  default:
484
504
  super.writeUint32(offset, value);
485
505
  }
@@ -26,14 +26,14 @@ class BasePeripheral {
26
26
  this.rawWriteValue = 0;
27
27
  }
28
28
  readUint32(offset) {
29
- this.warn(`Unimplemented peripheral read from ${offset.toString(16)}`);
29
+ this.warn(`Unimplemented peripheral read from 0x${offset.toString(16)}`);
30
30
  if (offset > 0x1000) {
31
31
  this.warn('Unimplemented read from peripheral in the atomic operation region');
32
32
  }
33
33
  return 0xffffffff;
34
34
  }
35
35
  writeUint32(offset, value) {
36
- this.warn(`Unimplemented peripheral write to ${offset.toString(16)}: ${value}`);
36
+ this.warn(`Unimplemented peripheral write to 0x${offset.toString(16)}: 0x${value.toString(16)}`);
37
37
  }
38
38
  writeUint32Atomic(offset, value, atomicType) {
39
39
  this.rawWriteValue = value;
@@ -1,6 +1,15 @@
1
1
  import { BasePeripheral, Peripheral } from './peripheral.js';
2
2
  export declare class RPSSI extends BasePeripheral implements Peripheral {
3
3
  private dr0;
4
+ private txflr;
5
+ private rxflr;
6
+ private baudr;
7
+ private crtlr0;
8
+ private crtlr1;
9
+ private ssienr;
10
+ private spictlr0;
11
+ private rxsampldly;
12
+ private txddriveedge;
4
13
  readUint32(offset: number): number;
5
14
  writeUint32(offset: number, value: number): void;
6
15
  }
@@ -2,34 +2,80 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RPSSI = void 0;
4
4
  const peripheral_js_1 = require("./peripheral.js");
5
+ /* See RP2040 datasheet sect 4.10.13 */
6
+ const SSI_CTRLR0 = 0x00000000;
7
+ const SSI_CTRLR1 = 0x00000004;
8
+ const SSI_SSIENR = 0x00000008;
9
+ const SSI_MWCR = 0x0000000c;
10
+ const SSI_SER = 0x00000010;
11
+ const SSI_BAUDR = 0x00000014;
12
+ const SSI_TXFTLR = 0x00000018;
13
+ const SSI_RXFTLR = 0x0000001c;
5
14
  const SSI_TXFLR = 0x00000020;
6
15
  const SSI_RXFLR = 0x00000024;
7
16
  const SSI_SR = 0x00000028;
8
- const SSI_DR0 = 0x00000060;
9
17
  const SSI_SR_TFNF_BITS = 0x00000002;
10
18
  const SSI_SR_TFE_BITS = 0x00000004;
11
19
  const SSI_SR_RFNE_BITS = 0x00000008;
20
+ const SSI_IMR = 0x0000002c;
21
+ const SSI_ISR = 0x00000030;
22
+ const SSI_RISR = 0x00000034;
23
+ const SSI_TXOICR = 0x00000038;
24
+ const SSI_RXOICR = 0x0000003c;
25
+ const SSI_RXUICR = 0x00000040;
26
+ const SSI_MSTICR = 0x00000044;
27
+ const SSI_ICR = 0x00000048;
28
+ const SSI_DMACR = 0x0000004c;
29
+ const SSI_DMATDLR = 0x00000050;
30
+ const SSI_DMARDLR = 0x00000054;
12
31
  /** Identification register */
13
32
  const SSI_IDR = 0x00000058;
14
33
  const SSI_VERSION_ID = 0x0000005c;
34
+ const SSI_DR0 = 0x00000060;
35
+ const SSI_RX_SAMPLE_DLY = 0x000000f0;
36
+ const SSI_SPI_CTRL_R0 = 0x000000f4;
37
+ const SSI_TXD_DRIVE_EDGE = 0x000000f8;
15
38
  const CMD_READ_STATUS = 0x05;
16
39
  class RPSSI extends peripheral_js_1.BasePeripheral {
17
40
  constructor() {
18
41
  super(...arguments);
19
42
  this.dr0 = 0;
43
+ this.txflr = 0;
44
+ this.rxflr = 0;
45
+ this.baudr = 0;
46
+ this.crtlr0 = 0;
47
+ this.crtlr1 = 0;
48
+ this.ssienr = 0;
49
+ this.spictlr0 = 0;
50
+ this.rxsampldly = 0;
51
+ this.txddriveedge = 0;
20
52
  }
21
53
  readUint32(offset) {
22
54
  switch (offset) {
23
55
  case SSI_TXFLR:
24
- return 0;
56
+ return this.txflr;
25
57
  case SSI_RXFLR:
26
- return 0;
58
+ return this.rxflr;
59
+ case SSI_CTRLR0:
60
+ return this.crtlr0; /* & 0x017FFFFF = b23,b25..31 reserved */
61
+ case SSI_CTRLR1:
62
+ return this.crtlr1;
63
+ case SSI_SSIENR:
64
+ return this.ssienr;
65
+ case SSI_BAUDR:
66
+ return this.baudr;
27
67
  case SSI_SR:
28
68
  return SSI_SR_TFE_BITS | SSI_SR_RFNE_BITS | SSI_SR_TFNF_BITS;
29
69
  case SSI_IDR:
30
70
  return 0x51535049;
31
71
  case SSI_VERSION_ID:
32
72
  return 0x3430312a;
73
+ case SSI_RX_SAMPLE_DLY:
74
+ return this.rxsampldly;
75
+ case SSI_TXD_DRIVE_EDGE:
76
+ return this.txddriveedge;
77
+ case SSI_SPI_CTRL_R0:
78
+ return this.spictlr0; /* b6,7,10,19..23 reserved */
33
79
  case SSI_DR0:
34
80
  return this.dr0;
35
81
  }
@@ -37,6 +83,33 @@ class RPSSI extends peripheral_js_1.BasePeripheral {
37
83
  }
38
84
  writeUint32(offset, value) {
39
85
  switch (offset) {
86
+ case SSI_TXFLR:
87
+ this.txflr = value;
88
+ return;
89
+ case SSI_RXFLR:
90
+ this.rxflr = value;
91
+ return;
92
+ case SSI_CTRLR0:
93
+ this.crtlr0 = value; /* & 0x017FFFFF = b23,b25..31 reserved */
94
+ return;
95
+ case SSI_CTRLR1:
96
+ this.crtlr1 = value;
97
+ return;
98
+ case SSI_SSIENR:
99
+ this.ssienr = value;
100
+ return;
101
+ case SSI_BAUDR:
102
+ this.baudr = value;
103
+ return;
104
+ case SSI_RX_SAMPLE_DLY:
105
+ this.rxsampldly = value & 0xff;
106
+ return;
107
+ case SSI_TXD_DRIVE_EDGE:
108
+ this.txddriveedge = value & 0xff;
109
+ return;
110
+ case SSI_SPI_CTRL_R0:
111
+ this.spictlr0 = value;
112
+ return;
40
113
  case SSI_DR0:
41
114
  if (value === CMD_READ_STATUS) {
42
115
  this.dr0 = 0; // tell stage2 that we completed a write
@@ -1,6 +1,7 @@
1
1
  import { RP2040 } from '../rp2040.js';
2
2
  import { BasePeripheral } from './peripheral.js';
3
3
  export declare class RPUSBController extends BasePeripheral {
4
+ private addrEndp;
4
5
  private mainCtrl;
5
6
  private intRaw;
6
7
  private intEnable;
@@ -20,6 +20,7 @@ const USB_BUF_CTRL_LEN_MASK = 0x3ff;
20
20
  const USB_BUF1_SHIFT = 16;
21
21
  const USB_BUF1_OFFSET = 64;
22
22
  // USB Peripheral Register
23
+ const ADDR_ENDP = 0x0;
23
24
  const MAIN_CTRL = 0x40;
24
25
  const SIE_STATUS = 0x50;
25
26
  const BUFF_STATUS = 0x58;
@@ -97,6 +98,7 @@ class RPUSBController extends peripheral_js_1.BasePeripheral {
97
98
  }
98
99
  constructor(rp2040, name) {
99
100
  super(rp2040, name);
101
+ this.addrEndp = 0;
100
102
  this.mainCtrl = 0;
101
103
  this.intRaw = 0;
102
104
  this.intEnable = 0;
@@ -130,6 +132,8 @@ class RPUSBController extends peripheral_js_1.BasePeripheral {
130
132
  }
131
133
  readUint32(offset) {
132
134
  switch (offset) {
135
+ case ADDR_ENDP:
136
+ return this.addrEndp & 0b1111000000001111111;
133
137
  case MAIN_CTRL:
134
138
  return this.mainCtrl;
135
139
  case SIE_STATUS:
@@ -152,6 +156,9 @@ class RPUSBController extends peripheral_js_1.BasePeripheral {
152
156
  writeUint32(offset, value) {
153
157
  var _a, _b;
154
158
  switch (offset) {
159
+ case ADDR_ENDP:
160
+ this.addrEndp = value;
161
+ break;
155
162
  case MAIN_CTRL:
156
163
  this.mainCtrl = value & (SIM_TIMING | CONTROLLER_EN | HOST_NDEVICE);
157
164
  if (value & CONTROLLER_EN && !(value & HOST_NDEVICE)) {
@@ -4,7 +4,8 @@ export declare enum GPIOPinState {
4
4
  High = 1,
5
5
  Input = 2,
6
6
  InputPullUp = 3,
7
- InputPullDown = 4
7
+ InputPullDown = 4,
8
+ InputBusKeeper = 5
8
9
  }
9
10
  export declare const FUNCTION_PWM = 4;
10
11
  export declare const FUNCTION_SIO = 5;
@@ -6,6 +6,7 @@ export var GPIOPinState;
6
6
  GPIOPinState[GPIOPinState["Input"] = 2] = "Input";
7
7
  GPIOPinState[GPIOPinState["InputPullUp"] = 3] = "InputPullUp";
8
8
  GPIOPinState[GPIOPinState["InputPullDown"] = 4] = "InputPullDown";
9
+ GPIOPinState[GPIOPinState["InputBusKeeper"] = 5] = "InputBusKeeper";
9
10
  })(GPIOPinState || (GPIOPinState = {}));
10
11
  export const FUNCTION_PWM = 4;
11
12
  export const FUNCTION_SIO = 5;
@@ -146,10 +147,15 @@ export class GPIOPin {
146
147
  }
147
148
  else {
148
149
  // TODO: check what happens when we enable both pullup/pulldown
149
- if (this.pulldownEnabled) {
150
+ // ANSWER: It is valid, see: 2.19.4.1. Bus Keeper Mode, datasheet p240
151
+ if (this.pulldownEnabled && this.pullupEnabled) {
152
+ // Pull high when high, pull low when low:
153
+ return GPIOPinState.InputBusKeeper;
154
+ }
155
+ else if (this.pulldownEnabled) {
150
156
  return GPIOPinState.InputPullDown;
151
157
  }
152
- if (this.pullupEnabled) {
158
+ else if (this.pullupEnabled) {
153
159
  return GPIOPinState.InputPullUp;
154
160
  }
155
161
  return GPIOPinState.Input;
@@ -1,8 +1,26 @@
1
1
  import { RP2040 } from '../rp2040.js';
2
2
  import { BasePeripheral, Peripheral } from './peripheral.js';
3
3
  export declare class RPClocks extends BasePeripheral implements Peripheral {
4
+ gpout0Ctrl: number;
5
+ gpout0Div: number;
6
+ gpout1Ctrl: number;
7
+ gpout1Div: number;
8
+ gpout2Ctrl: number;
9
+ gpout2Div: number;
10
+ gpout3Ctrl: number;
11
+ gpout3Div: number;
4
12
  refCtrl: number;
13
+ refDiv: number;
14
+ periCtrl: number;
15
+ periDiv: number;
16
+ usbCtrl: number;
17
+ usbDiv: number;
5
18
  sysCtrl: number;
19
+ sysDiv: number;
20
+ adcCtrl: number;
21
+ adcDiv: number;
22
+ rtcCtrl: number;
23
+ rtcDiv: number;
6
24
  constructor(rp2040: RP2040, name: string);
7
25
  readUint32(offset: number): number;
8
26
  writeUint32(offset: number, value: number): void;
@@ -1,35 +1,193 @@
1
1
  import { BasePeripheral } from './peripheral.js';
2
+ const CLK_GPOUT0_CTRL = 0x00;
3
+ const CLK_GPOUT0_DIV = 0x04;
4
+ const CLK_GPOUT0_SELECTED = 0x8;
5
+ const CLK_GPOUT1_CTRL = 0x0c;
6
+ const CLK_GPOUT1_DIV = 0x10;
7
+ const CLK_GPOUT1_SELECTED = 0x14;
8
+ const CLK_GPOUT2_CTRL = 0x18;
9
+ const CLK_GPOUT2_DIV = 0x01c;
10
+ const CLK_GPOUT2_SELECTED = 0x20;
11
+ const CLK_GPOUT3_CTRL = 0x24;
12
+ const CLK_GPOUT3_DIV = 0x28;
13
+ const CLK_GPOUT3_SELECTED = 0x2c;
2
14
  const CLK_REF_CTRL = 0x30;
15
+ const CLK_REF_DIV = 0x34;
3
16
  const CLK_REF_SELECTED = 0x38;
4
17
  const CLK_SYS_CTRL = 0x3c;
18
+ const CLK_SYS_DIV = 0x40;
5
19
  const CLK_SYS_SELECTED = 0x44;
20
+ const CLK_PERI_CTRL = 0x48;
21
+ const CLK_PERI_DIV = 0x4c;
22
+ const CLK_PERI_SELECTED = 0x50;
23
+ const CLK_USB_CTRL = 0x54;
24
+ const CLK_USB_DIV = 0x58;
25
+ const CLK_USB_SELECTED = 0x5c;
26
+ const CLK_ADC_CTRL = 0x60;
27
+ const CLK_ADC_DIV = 0x64;
28
+ const CLK_ADC_SELECTED = 0x68;
29
+ const CLK_RTC_CTRL = 0x6c;
30
+ const CLK_RTC_DIV = 0x70;
31
+ const CLK_RTC_SELECTED = 0x74;
32
+ const CLK_SYS_RESUS_CTRL = 0x78;
33
+ const CLK_SYS_RESUS_STATUS = 0x7c;
6
34
  export class RPClocks extends BasePeripheral {
7
35
  constructor(rp2040, name) {
8
36
  super(rp2040, name);
37
+ this.gpout0Ctrl = 0;
38
+ this.gpout0Div = 0x100;
39
+ this.gpout1Ctrl = 0;
40
+ this.gpout1Div = 0x100;
41
+ this.gpout2Ctrl = 0;
42
+ this.gpout2Div = 0x100;
43
+ this.gpout3Ctrl = 0;
44
+ this.gpout3Div = 0x100;
9
45
  this.refCtrl = 0;
46
+ this.refDiv = 0x100;
47
+ this.periCtrl = 0;
48
+ this.periDiv = 0x100;
49
+ this.usbCtrl = 0;
50
+ this.usbDiv = 0x100;
10
51
  this.sysCtrl = 0;
52
+ this.sysDiv = 0x100;
53
+ this.adcCtrl = 0;
54
+ this.adcDiv = 0x100;
55
+ this.rtcCtrl = 0;
56
+ this.rtcDiv = 0x100;
11
57
  }
12
58
  readUint32(offset) {
13
59
  switch (offset) {
60
+ case CLK_GPOUT0_CTRL:
61
+ return this.gpout0Ctrl & 0b100110001110111100000;
62
+ case CLK_GPOUT0_DIV:
63
+ return this.gpout0Div;
64
+ case CLK_GPOUT0_SELECTED:
65
+ return 1;
66
+ case CLK_GPOUT1_CTRL:
67
+ return this.gpout1Ctrl & 0b100110001110111100000;
68
+ case CLK_GPOUT1_DIV:
69
+ return this.gpout1Div;
70
+ case CLK_GPOUT1_SELECTED:
71
+ return 1;
72
+ case CLK_GPOUT2_CTRL:
73
+ return this.gpout2Ctrl & 0b100110001110111100000;
74
+ case CLK_GPOUT2_DIV:
75
+ return this.gpout2Div;
76
+ case CLK_GPOUT2_SELECTED:
77
+ return 1;
78
+ case CLK_GPOUT3_CTRL:
79
+ return this.gpout3Ctrl & 0b100110001110111100000;
80
+ case CLK_GPOUT3_DIV:
81
+ return this.gpout3Div;
82
+ case CLK_GPOUT3_SELECTED:
83
+ return 1;
14
84
  case CLK_REF_CTRL:
15
- return this.refCtrl;
85
+ return this.refCtrl & 0b000001100011;
86
+ case CLK_REF_DIV:
87
+ return this.refDiv & 0x30; // b8..9 = int divisor. no frac divisor present
16
88
  case CLK_REF_SELECTED:
17
89
  return 1 << (this.refCtrl & 0x03);
18
90
  case CLK_SYS_CTRL:
19
- return this.sysCtrl;
91
+ return this.sysCtrl & 0b000011100001;
92
+ case CLK_SYS_DIV:
93
+ return this.sysDiv;
20
94
  case CLK_SYS_SELECTED:
21
95
  return 1 << (this.sysCtrl & 0x01);
96
+ case CLK_PERI_CTRL:
97
+ return this.periCtrl & 0b110011100000;
98
+ case CLK_PERI_DIV:
99
+ return this.periDiv;
100
+ case CLK_PERI_SELECTED:
101
+ return 1;
102
+ case CLK_USB_CTRL:
103
+ return this.usbCtrl & 0b100110000110011100000;
104
+ case CLK_USB_DIV:
105
+ return this.usbDiv;
106
+ case CLK_USB_SELECTED:
107
+ return 1;
108
+ case CLK_ADC_CTRL:
109
+ return this.adcCtrl & 0b100110000110011100000;
110
+ case CLK_ADC_DIV:
111
+ return this.adcDiv & 0x30;
112
+ case CLK_ADC_SELECTED:
113
+ return 1;
114
+ case CLK_RTC_CTRL:
115
+ return this.rtcCtrl & 0b100110000110011100000;
116
+ case CLK_RTC_DIV:
117
+ return this.rtcDiv & 0x30;
118
+ case CLK_RTC_SELECTED:
119
+ return 1;
120
+ case CLK_SYS_RESUS_CTRL:
121
+ return 0xff;
122
+ case CLK_SYS_RESUS_STATUS:
123
+ return 0; /* clock resus not implemented */
22
124
  }
23
125
  return super.readUint32(offset);
24
126
  }
25
127
  writeUint32(offset, value) {
26
128
  switch (offset) {
129
+ case CLK_GPOUT0_CTRL:
130
+ this.gpout0Ctrl = value;
131
+ break;
132
+ case CLK_GPOUT0_DIV:
133
+ this.gpout0Div = value;
134
+ break;
135
+ case CLK_GPOUT1_CTRL:
136
+ this.gpout1Ctrl = value;
137
+ break;
138
+ case CLK_GPOUT1_DIV:
139
+ this.gpout1Div = value;
140
+ break;
141
+ case CLK_GPOUT2_CTRL:
142
+ this.gpout2Ctrl = value;
143
+ break;
144
+ case CLK_GPOUT2_DIV:
145
+ this.gpout2Div = value;
146
+ break;
147
+ case CLK_GPOUT3_CTRL:
148
+ this.gpout3Ctrl = value;
149
+ break;
150
+ case CLK_GPOUT3_DIV:
151
+ this.gpout3Div = value;
152
+ break;
27
153
  case CLK_REF_CTRL:
28
154
  this.refCtrl = value;
29
155
  break;
156
+ case CLK_REF_DIV:
157
+ this.refDiv = value;
158
+ break;
30
159
  case CLK_SYS_CTRL:
31
160
  this.sysCtrl = value;
32
161
  break;
162
+ case CLK_SYS_DIV:
163
+ this.sysDiv = value;
164
+ break;
165
+ case CLK_PERI_CTRL:
166
+ this.periCtrl = value;
167
+ break;
168
+ case CLK_PERI_DIV:
169
+ this.periDiv = value;
170
+ break;
171
+ case CLK_USB_CTRL:
172
+ this.usbCtrl = value;
173
+ break;
174
+ case CLK_USB_DIV:
175
+ this.usbDiv = value;
176
+ break;
177
+ case CLK_ADC_CTRL:
178
+ this.adcCtrl = value;
179
+ break;
180
+ case CLK_ADC_DIV:
181
+ this.adcDiv = value;
182
+ break;
183
+ case CLK_RTC_CTRL:
184
+ this.rtcCtrl = value;
185
+ break;
186
+ case CLK_RTC_DIV:
187
+ this.rtcDiv = value;
188
+ break;
189
+ case CLK_SYS_RESUS_CTRL:
190
+ return; /* clock resus not implemented */
33
191
  default:
34
192
  super.writeUint32(offset, value);
35
193
  break;
@@ -37,6 +37,7 @@ export declare class RPI2C extends BasePeripheral implements Peripheral {
37
37
  abortSource: number;
38
38
  intRaw: number;
39
39
  intEnable: number;
40
+ private spikelen;
40
41
  get intStatus(): number;
41
42
  get speed(): I2CSpeed;
42
43
  get sclLowPeriod(): number;
@@ -177,6 +177,7 @@ export class RPI2C extends BasePeripheral {
177
177
  this.abortSource = 0;
178
178
  this.intRaw = 0;
179
179
  this.intEnable = 0;
180
+ this.spikelen = 0x07;
180
181
  }
181
182
  checkInterrupts() {
182
183
  this.rp2040.setInterrupt(this.irq, !!this.intStatus);
@@ -393,11 +394,18 @@ export class RPI2C extends BasePeripheral {
393
394
  return this.txFIFO.itemCount;
394
395
  case IC_RXFLR:
395
396
  return this.rxFIFO.itemCount;
397
+ case IC_SDA_HOLD:
398
+ return 0x01;
396
399
  case IC_TX_ABRT_SOURCE: {
397
400
  const value = this.abortSource;
398
401
  this.abortSource &= ABRT_SBYTE_NORSTRT; // Clear IC_TX_ABRT_SOURCE, expect for bit 9
399
402
  return value;
400
403
  }
404
+ case IC_ENABLE_STATUS:
405
+ // I2C status - read only. bit 0 reflects IC_ENABLE, bit 1,2 relate to i2c slave mode.
406
+ return this.enable & 0x1;
407
+ case IC_FS_SPKLEN:
408
+ return this.spikelen & 0xff;
401
409
  case IC_COMP_PARAM_1:
402
410
  // From the datasheet:
403
411
  // Note This register is not implemented and therefore reads as 0. If it was implemented it would be a constant read-only
@@ -446,6 +454,13 @@ export class RPI2C extends BasePeripheral {
446
454
  case IC_FS_SCL_LCNT:
447
455
  this.fsClockLowPeriod = value & 0xffff;
448
456
  return;
457
+ case IC_SDA_HOLD:
458
+ if (!(value & ENABLE)) {
459
+ if (value != 0x1) {
460
+ this.warn('Unimplemented write to IC_SDA_HOLD');
461
+ }
462
+ }
463
+ return;
449
464
  case IC_RX_TL:
450
465
  this.rxThreshold = value & 0xff;
451
466
  if (this.rxThreshold > this.rxFIFO.size) {
@@ -477,6 +492,11 @@ export class RPI2C extends BasePeripheral {
477
492
  this.enable = value;
478
493
  this.nextCommand(); // TX_CMD_BLOCK may have changed
479
494
  return;
495
+ case IC_FS_SPKLEN:
496
+ if (!(value & ENABLE) && value > 0) {
497
+ this.spikelen = value;
498
+ }
499
+ return;
480
500
  default:
481
501
  super.writeUint32(offset, value);
482
502
  }
@@ -22,14 +22,14 @@ export class BasePeripheral {
22
22
  this.rawWriteValue = 0;
23
23
  }
24
24
  readUint32(offset) {
25
- this.warn(`Unimplemented peripheral read from ${offset.toString(16)}`);
25
+ this.warn(`Unimplemented peripheral read from 0x${offset.toString(16)}`);
26
26
  if (offset > 0x1000) {
27
27
  this.warn('Unimplemented read from peripheral in the atomic operation region');
28
28
  }
29
29
  return 0xffffffff;
30
30
  }
31
31
  writeUint32(offset, value) {
32
- this.warn(`Unimplemented peripheral write to ${offset.toString(16)}: ${value}`);
32
+ this.warn(`Unimplemented peripheral write to 0x${offset.toString(16)}: 0x${value.toString(16)}`);
33
33
  }
34
34
  writeUint32Atomic(offset, value, atomicType) {
35
35
  this.rawWriteValue = value;
@@ -1,6 +1,15 @@
1
1
  import { BasePeripheral, Peripheral } from './peripheral.js';
2
2
  export declare class RPSSI extends BasePeripheral implements Peripheral {
3
3
  private dr0;
4
+ private txflr;
5
+ private rxflr;
6
+ private baudr;
7
+ private crtlr0;
8
+ private crtlr1;
9
+ private ssienr;
10
+ private spictlr0;
11
+ private rxsampldly;
12
+ private txddriveedge;
4
13
  readUint32(offset: number): number;
5
14
  writeUint32(offset: number, value: number): void;
6
15
  }
@@ -1,32 +1,78 @@
1
1
  import { BasePeripheral } from './peripheral.js';
2
+ /* See RP2040 datasheet sect 4.10.13 */
3
+ const SSI_CTRLR0 = 0x00000000;
4
+ const SSI_CTRLR1 = 0x00000004;
5
+ const SSI_SSIENR = 0x00000008;
6
+ const SSI_MWCR = 0x0000000c;
7
+ const SSI_SER = 0x00000010;
8
+ const SSI_BAUDR = 0x00000014;
9
+ const SSI_TXFTLR = 0x00000018;
10
+ const SSI_RXFTLR = 0x0000001c;
2
11
  const SSI_TXFLR = 0x00000020;
3
12
  const SSI_RXFLR = 0x00000024;
4
13
  const SSI_SR = 0x00000028;
5
- const SSI_DR0 = 0x00000060;
6
14
  const SSI_SR_TFNF_BITS = 0x00000002;
7
15
  const SSI_SR_TFE_BITS = 0x00000004;
8
16
  const SSI_SR_RFNE_BITS = 0x00000008;
17
+ const SSI_IMR = 0x0000002c;
18
+ const SSI_ISR = 0x00000030;
19
+ const SSI_RISR = 0x00000034;
20
+ const SSI_TXOICR = 0x00000038;
21
+ const SSI_RXOICR = 0x0000003c;
22
+ const SSI_RXUICR = 0x00000040;
23
+ const SSI_MSTICR = 0x00000044;
24
+ const SSI_ICR = 0x00000048;
25
+ const SSI_DMACR = 0x0000004c;
26
+ const SSI_DMATDLR = 0x00000050;
27
+ const SSI_DMARDLR = 0x00000054;
9
28
  /** Identification register */
10
29
  const SSI_IDR = 0x00000058;
11
30
  const SSI_VERSION_ID = 0x0000005c;
31
+ const SSI_DR0 = 0x00000060;
32
+ const SSI_RX_SAMPLE_DLY = 0x000000f0;
33
+ const SSI_SPI_CTRL_R0 = 0x000000f4;
34
+ const SSI_TXD_DRIVE_EDGE = 0x000000f8;
12
35
  const CMD_READ_STATUS = 0x05;
13
36
  export class RPSSI extends BasePeripheral {
14
37
  constructor() {
15
38
  super(...arguments);
16
39
  this.dr0 = 0;
40
+ this.txflr = 0;
41
+ this.rxflr = 0;
42
+ this.baudr = 0;
43
+ this.crtlr0 = 0;
44
+ this.crtlr1 = 0;
45
+ this.ssienr = 0;
46
+ this.spictlr0 = 0;
47
+ this.rxsampldly = 0;
48
+ this.txddriveedge = 0;
17
49
  }
18
50
  readUint32(offset) {
19
51
  switch (offset) {
20
52
  case SSI_TXFLR:
21
- return 0;
53
+ return this.txflr;
22
54
  case SSI_RXFLR:
23
- return 0;
55
+ return this.rxflr;
56
+ case SSI_CTRLR0:
57
+ return this.crtlr0; /* & 0x017FFFFF = b23,b25..31 reserved */
58
+ case SSI_CTRLR1:
59
+ return this.crtlr1;
60
+ case SSI_SSIENR:
61
+ return this.ssienr;
62
+ case SSI_BAUDR:
63
+ return this.baudr;
24
64
  case SSI_SR:
25
65
  return SSI_SR_TFE_BITS | SSI_SR_RFNE_BITS | SSI_SR_TFNF_BITS;
26
66
  case SSI_IDR:
27
67
  return 0x51535049;
28
68
  case SSI_VERSION_ID:
29
69
  return 0x3430312a;
70
+ case SSI_RX_SAMPLE_DLY:
71
+ return this.rxsampldly;
72
+ case SSI_TXD_DRIVE_EDGE:
73
+ return this.txddriveedge;
74
+ case SSI_SPI_CTRL_R0:
75
+ return this.spictlr0; /* b6,7,10,19..23 reserved */
30
76
  case SSI_DR0:
31
77
  return this.dr0;
32
78
  }
@@ -34,6 +80,33 @@ export class RPSSI extends BasePeripheral {
34
80
  }
35
81
  writeUint32(offset, value) {
36
82
  switch (offset) {
83
+ case SSI_TXFLR:
84
+ this.txflr = value;
85
+ return;
86
+ case SSI_RXFLR:
87
+ this.rxflr = value;
88
+ return;
89
+ case SSI_CTRLR0:
90
+ this.crtlr0 = value; /* & 0x017FFFFF = b23,b25..31 reserved */
91
+ return;
92
+ case SSI_CTRLR1:
93
+ this.crtlr1 = value;
94
+ return;
95
+ case SSI_SSIENR:
96
+ this.ssienr = value;
97
+ return;
98
+ case SSI_BAUDR:
99
+ this.baudr = value;
100
+ return;
101
+ case SSI_RX_SAMPLE_DLY:
102
+ this.rxsampldly = value & 0xff;
103
+ return;
104
+ case SSI_TXD_DRIVE_EDGE:
105
+ this.txddriveedge = value & 0xff;
106
+ return;
107
+ case SSI_SPI_CTRL_R0:
108
+ this.spictlr0 = value;
109
+ return;
37
110
  case SSI_DR0:
38
111
  if (value === CMD_READ_STATUS) {
39
112
  this.dr0 = 0; // tell stage2 that we completed a write
@@ -1,6 +1,7 @@
1
1
  import { RP2040 } from '../rp2040.js';
2
2
  import { BasePeripheral } from './peripheral.js';
3
3
  export declare class RPUSBController extends BasePeripheral {
4
+ private addrEndp;
4
5
  private mainCtrl;
5
6
  private intRaw;
6
7
  private intEnable;
@@ -17,6 +17,7 @@ const USB_BUF_CTRL_LEN_MASK = 0x3ff;
17
17
  const USB_BUF1_SHIFT = 16;
18
18
  const USB_BUF1_OFFSET = 64;
19
19
  // USB Peripheral Register
20
+ const ADDR_ENDP = 0x0;
20
21
  const MAIN_CTRL = 0x40;
21
22
  const SIE_STATUS = 0x50;
22
23
  const BUFF_STATUS = 0x58;
@@ -94,6 +95,7 @@ export class RPUSBController extends BasePeripheral {
94
95
  }
95
96
  constructor(rp2040, name) {
96
97
  super(rp2040, name);
98
+ this.addrEndp = 0;
97
99
  this.mainCtrl = 0;
98
100
  this.intRaw = 0;
99
101
  this.intEnable = 0;
@@ -127,6 +129,8 @@ export class RPUSBController extends BasePeripheral {
127
129
  }
128
130
  readUint32(offset) {
129
131
  switch (offset) {
132
+ case ADDR_ENDP:
133
+ return this.addrEndp & 0b1111000000001111111;
130
134
  case MAIN_CTRL:
131
135
  return this.mainCtrl;
132
136
  case SIE_STATUS:
@@ -149,6 +153,9 @@ export class RPUSBController extends BasePeripheral {
149
153
  writeUint32(offset, value) {
150
154
  var _a, _b;
151
155
  switch (offset) {
156
+ case ADDR_ENDP:
157
+ this.addrEndp = value;
158
+ break;
152
159
  case MAIN_CTRL:
153
160
  this.mainCtrl = value & (SIM_TIMING | CONTROLLER_EN | HOST_NDEVICE);
154
161
  if (value & CONTROLLER_EN && !(value & HOST_NDEVICE)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [