rp2040js 0.18.1 → 0.19.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.
@@ -9,6 +9,9 @@ const SSI_DR0 = 0x00000060;
9
9
  const SSI_SR_TFNF_BITS = 0x00000002;
10
10
  const SSI_SR_TFE_BITS = 0x00000004;
11
11
  const SSI_SR_RFNE_BITS = 0x00000008;
12
+ /** Identification register */
13
+ const SSI_IDR = 0x00000058;
14
+ const SSI_VERSION_ID = 0x0000005c;
12
15
  const CMD_READ_STATUS = 0x05;
13
16
  class RPSSI extends peripheral_js_1.BasePeripheral {
14
17
  constructor() {
@@ -23,6 +26,10 @@ class RPSSI extends peripheral_js_1.BasePeripheral {
23
26
  return 0;
24
27
  case SSI_SR:
25
28
  return SSI_SR_TFE_BITS | SSI_SR_RFNE_BITS | SSI_SR_TFNF_BITS;
29
+ case SSI_IDR:
30
+ return 0x51535049;
31
+ case SSI_VERSION_ID:
32
+ return 0x3430312a;
26
33
  case SSI_DR0:
27
34
  return this.dr0;
28
35
  }
@@ -13,7 +13,10 @@ export declare class RPUART extends BasePeripheral implements Peripheral {
13
13
  private rxFIFO;
14
14
  private interruptMask;
15
15
  private interruptStatus;
16
+ private intDivisor;
17
+ private fracDivisor;
16
18
  onByte?: (value: number) => void;
19
+ onBaudRateChange?: (baudRate: number) => void;
17
20
  constructor(rp2040: RP2040, name: string, irq: number, dreq: IUARTDMAChannels);
18
21
  get enabled(): boolean;
19
22
  get txEnabled(): boolean;
@@ -23,6 +26,8 @@ export declare class RPUART extends BasePeripheral implements Peripheral {
23
26
  * Number of bits per UART character
24
27
  */
25
28
  get wordLength(): 5 | 6 | 7 | 8 | undefined;
29
+ get baudDivider(): number;
30
+ get baudRate(): number;
26
31
  get flags(): number;
27
32
  checkInterrupts(): void;
28
33
  feedByte(value: number): void;
@@ -5,12 +5,22 @@ const fifo_js_1 = require("../utils/fifo.js");
5
5
  const peripheral_js_1 = require("./peripheral.js");
6
6
  const UARTDR = 0x0;
7
7
  const UARTFR = 0x18;
8
+ const UARTIBRD = 0x24;
9
+ const UARTFBRD = 0x28;
8
10
  const UARTLCR_H = 0x2c;
9
11
  const UARTCR = 0x30;
10
12
  const UARTIMSC = 0x38;
11
13
  const UARTIRIS = 0x3c;
12
14
  const UARTIMIS = 0x40;
13
15
  const UARTICR = 0x44;
16
+ const UARTPERIPHID0 = 0xfe0;
17
+ const UARTPERIPHID1 = 0xfe4;
18
+ const UARTPERIPHID2 = 0xfe8;
19
+ const UARTPERIPHID3 = 0xfec;
20
+ const UARTPCELLID0 = 0xff0;
21
+ const UARTPCELLID1 = 0xff4;
22
+ const UARTPCELLID2 = 0xff8;
23
+ const UARTPCELLID3 = 0xffc;
14
24
  // UARTFR bits:
15
25
  const TXFE = 1 << 7;
16
26
  const RXFF = 1 << 6;
@@ -33,6 +43,8 @@ class RPUART extends peripheral_js_1.BasePeripheral {
33
43
  this.rxFIFO = new fifo_js_1.FIFO(32);
34
44
  this.interruptMask = 0;
35
45
  this.interruptStatus = 0;
46
+ this.intDivisor = 0;
47
+ this.fracDivisor = 0;
36
48
  }
37
49
  get enabled() {
38
50
  return !!(this.ctrlRegister & UARTEN);
@@ -61,6 +73,12 @@ class RPUART extends peripheral_js_1.BasePeripheral {
61
73
  return 8;
62
74
  }
63
75
  }
76
+ get baudDivider() {
77
+ return this.intDivisor + this.fracDivisor / 64;
78
+ }
79
+ get baudRate() {
80
+ return Math.round(this.rp2040.clkPeri / (this.baudDivider * 16));
81
+ }
64
82
  get flags() {
65
83
  return (this.rxFIFO.full ? RXFF : 0) | (this.rxFIFO.empty ? RXFE : 0) | TXFE;
66
84
  }
@@ -85,6 +103,10 @@ class RPUART extends peripheral_js_1.BasePeripheral {
85
103
  }
86
104
  case UARTFR:
87
105
  return this.flags;
106
+ case UARTIBRD:
107
+ return this.intDivisor;
108
+ case UARTFBRD:
109
+ return this.fracDivisor;
88
110
  case UARTLCR_H:
89
111
  return this.lineCtrlRegister;
90
112
  case UARTCR:
@@ -95,15 +117,39 @@ class RPUART extends peripheral_js_1.BasePeripheral {
95
117
  return this.interruptStatus;
96
118
  case UARTIMIS:
97
119
  return this.interruptStatus & this.interruptMask;
120
+ case UARTPERIPHID0:
121
+ return 0x11;
122
+ case UARTPERIPHID1:
123
+ return 0x10;
124
+ case UARTPERIPHID2:
125
+ return 0x34;
126
+ case UARTPERIPHID3:
127
+ return 0x00;
128
+ case UARTPCELLID0:
129
+ return 0x0d;
130
+ case UARTPCELLID1:
131
+ return 0xf0;
132
+ case UARTPCELLID2:
133
+ return 0x05;
134
+ case UARTPCELLID3:
135
+ return 0xb1;
98
136
  }
99
137
  return super.readUint32(offset);
100
138
  }
101
139
  writeUint32(offset, value) {
102
- var _a;
140
+ var _a, _b, _c;
103
141
  switch (offset) {
104
142
  case UARTDR:
105
143
  (_a = this.onByte) === null || _a === void 0 ? void 0 : _a.call(this, value & 0xff);
106
144
  break;
145
+ case UARTIBRD:
146
+ this.intDivisor = value & 0xffff;
147
+ (_b = this.onBaudRateChange) === null || _b === void 0 ? void 0 : _b.call(this, this.baudRate);
148
+ break;
149
+ case UARTFBRD:
150
+ this.fracDivisor = value & 0x3f;
151
+ (_c = this.onBaudRateChange) === null || _c === void 0 ? void 0 : _c.call(this, this.baudRate);
152
+ break;
107
153
  case UARTLCR_H:
108
154
  this.lineCtrlRegister = value;
109
155
  break;
@@ -0,0 +1,19 @@
1
+ import { RP2040 } from '../rp2040.js';
2
+ import { Timer32, Timer32PeriodicAlarm } from '../utils/timer32.js';
3
+ import { BasePeripheral, Peripheral } from './peripheral.js';
4
+ export declare class RPWatchdog extends BasePeripheral implements Peripheral {
5
+ readonly timer: Timer32;
6
+ readonly alarm: Timer32PeriodicAlarm;
7
+ readonly scratchData: Uint32Array;
8
+ private enable;
9
+ private tickEnable;
10
+ private reason;
11
+ private pauseDbg0;
12
+ private pauseDbg1;
13
+ private pauseJtag;
14
+ /** Called when the watchdog triggers - override with your own soft reset implementation */
15
+ onWatchdogTrigger: () => void;
16
+ constructor(rp2040: RP2040, name: string);
17
+ readUint32(offset: number): number;
18
+ writeUint32(offset: number, value: number): void;
19
+ }
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RPWatchdog = void 0;
4
+ const timer32_js_1 = require("../utils/timer32.js");
5
+ const peripheral_js_1 = require("./peripheral.js");
6
+ const CTRL = 0x00; // Control register
7
+ const LOAD = 0x04; // Load the watchdog timer.
8
+ const REASON = 0x08; // Logs the reason for the last reset.
9
+ const SCRATCH0 = 0x0c; // Scratch register
10
+ const SCRATCH1 = 0x10; // Scratch register
11
+ const SCRATCH2 = 0x14; // Scratch register
12
+ const SCRATCH3 = 0x18; // Scratch register
13
+ const SCRATCH4 = 0x1c; // Scratch register
14
+ const SCRATCH5 = 0x20; // Scratch register
15
+ const SCRATCH6 = 0x24; // Scratch register
16
+ const SCRATCH7 = 0x28; // Scratch register
17
+ const TICK = 0x2c; // Controls the tick generator
18
+ // CTRL bits:
19
+ const TRIGGER = 1 << 31;
20
+ const ENABLE = 1 << 30;
21
+ const PAUSE_DBG1 = 1 << 26;
22
+ const PAUSE_DBG0 = 1 << 25;
23
+ const PAUSE_JTAG = 1 << 24;
24
+ const TIME_MASK = 0xffffff;
25
+ const TIME_SHIFT = 0;
26
+ // LOAD bits
27
+ const LOAD_MASK = 0xffffff;
28
+ const LOAD_SHIFT = 0;
29
+ // REASON bits:
30
+ const FORCE = 1 << 1;
31
+ const TIMER = 1 << 0;
32
+ // TICK bits:
33
+ const COUNT_MASK = 0x1ff;
34
+ const COUNT_SHIFT = 11;
35
+ const RUNNING = 1 << 10;
36
+ const TICK_ENABLE = 1 << 9;
37
+ const CYCLES_MASK = 0x1ff;
38
+ const CYCLES_SHIFT = 0;
39
+ const TICK_FREQUENCY = 2000000; // Actually 1 MHz, but due to errata RP2040-E1, the timer is decremented twice per tick
40
+ class RPWatchdog extends peripheral_js_1.BasePeripheral {
41
+ // User provided
42
+ constructor(rp2040, name) {
43
+ super(rp2040, name);
44
+ this.scratchData = new Uint32Array(8);
45
+ this.enable = false;
46
+ this.tickEnable = true;
47
+ this.reason = 0;
48
+ this.pauseDbg0 = true;
49
+ this.pauseDbg1 = true;
50
+ this.pauseJtag = true;
51
+ /** Called when the watchdog triggers - override with your own soft reset implementation */
52
+ this.onWatchdogTrigger = () => {
53
+ this.rp2040.logger.warn(this.name, 'Watchdog triggered, but no reset handler provided');
54
+ };
55
+ this.timer = new timer32_js_1.Timer32(rp2040.clock, TICK_FREQUENCY);
56
+ this.timer.mode = timer32_js_1.TimerMode.Decrement;
57
+ this.timer.enable = false;
58
+ this.alarm = new timer32_js_1.Timer32PeriodicAlarm(this.timer, () => {
59
+ var _a;
60
+ this.reason = TIMER;
61
+ (_a = this.onWatchdogTrigger) === null || _a === void 0 ? void 0 : _a.call(this);
62
+ });
63
+ this.alarm.target = 0;
64
+ this.alarm.enable = false;
65
+ }
66
+ readUint32(offset) {
67
+ switch (offset) {
68
+ case CTRL:
69
+ return ((this.timer.enable ? ENABLE : 0) |
70
+ (this.pauseDbg0 ? PAUSE_DBG0 : 0) |
71
+ (this.pauseDbg1 ? PAUSE_DBG1 : 0) |
72
+ (this.pauseJtag ? PAUSE_JTAG : 0) |
73
+ ((this.timer.counter & TIME_MASK) << TIME_SHIFT));
74
+ case REASON:
75
+ return this.reason;
76
+ case SCRATCH0:
77
+ case SCRATCH1:
78
+ case SCRATCH2:
79
+ case SCRATCH3:
80
+ case SCRATCH4:
81
+ case SCRATCH5:
82
+ case SCRATCH6:
83
+ case SCRATCH7:
84
+ return this.scratchData[(offset - SCRATCH0) >> 2];
85
+ case TICK:
86
+ // TODO COUNT bits
87
+ return this.tickEnable ? RUNNING | TICK_ENABLE : 0;
88
+ }
89
+ return super.readUint32(offset);
90
+ }
91
+ writeUint32(offset, value) {
92
+ var _a;
93
+ switch (offset) {
94
+ case CTRL:
95
+ if (value & TRIGGER) {
96
+ this.reason = FORCE;
97
+ (_a = this.onWatchdogTrigger) === null || _a === void 0 ? void 0 : _a.call(this);
98
+ }
99
+ this.enable = !!(value & ENABLE);
100
+ this.timer.enable = this.enable && this.tickEnable;
101
+ this.alarm.enable = this.enable && this.tickEnable;
102
+ this.pauseDbg0 = !!(value & PAUSE_DBG0);
103
+ this.pauseDbg1 = !!(value & PAUSE_DBG1);
104
+ this.pauseJtag = !!(value & PAUSE_JTAG);
105
+ break;
106
+ case LOAD:
107
+ this.timer.set((value >>> LOAD_SHIFT) & LOAD_MASK);
108
+ break;
109
+ case SCRATCH0:
110
+ case SCRATCH1:
111
+ case SCRATCH2:
112
+ case SCRATCH3:
113
+ case SCRATCH4:
114
+ case SCRATCH5:
115
+ case SCRATCH6:
116
+ case SCRATCH7:
117
+ this.scratchData[(offset - SCRATCH0) >> 2] = value;
118
+ break;
119
+ case TICK:
120
+ this.tickEnable = !!(value & TICK_ENABLE);
121
+ this.timer.enable = this.enable && this.tickEnable;
122
+ this.alarm.enable = this.enable && this.tickEnable;
123
+ // TODO - handle CYCLES (tick also affectes timer)
124
+ break;
125
+ default:
126
+ super.writeUint32(offset, value);
127
+ }
128
+ }
129
+ }
130
+ exports.RPWatchdog = RPWatchdog;
@@ -26,6 +26,7 @@ const tbman_js_1 = require("./peripherals/tbman.js");
26
26
  const timer_js_1 = require("./peripherals/timer.js");
27
27
  const uart_js_1 = require("./peripherals/uart.js");
28
28
  const usb_js_1 = require("./peripherals/usb.js");
29
+ const watchdog_js_1 = require("./peripherals/watchdog.js");
29
30
  const sio_js_1 = require("./sio.js");
30
31
  const logging_js_1 = require("./utils/logging.js");
31
32
  exports.FLASH_START_ADDRESS = 0x10000000;
@@ -150,7 +151,7 @@ class RP2040 {
150
151
  0x4004c: this.adc,
151
152
  0x40050: this.pwm,
152
153
  0x40054: new timer_js_1.RPTimer(this, 'TIMER_BASE'),
153
- 0x40058: new peripheral_js_1.UnimplementedPeripheral(this, 'WATCHDOG_BASE'),
154
+ 0x40058: new watchdog_js_1.RPWatchdog(this, 'WATCHDOG_BASE'),
154
155
  0x4005c: new rtc_js_1.RP2040RTC(this, 'RTC_BASE'),
155
156
  0x40060: new peripheral_js_1.UnimplementedPeripheral(this, 'ROSC_BASE'),
156
157
  0x40064: new peripheral_js_1.UnimplementedPeripheral(this, 'VREG_AND_CHIP_RESET_BASE'),
@@ -6,6 +6,9 @@ const SSI_DR0 = 0x00000060;
6
6
  const SSI_SR_TFNF_BITS = 0x00000002;
7
7
  const SSI_SR_TFE_BITS = 0x00000004;
8
8
  const SSI_SR_RFNE_BITS = 0x00000008;
9
+ /** Identification register */
10
+ const SSI_IDR = 0x00000058;
11
+ const SSI_VERSION_ID = 0x0000005c;
9
12
  const CMD_READ_STATUS = 0x05;
10
13
  export class RPSSI extends BasePeripheral {
11
14
  constructor() {
@@ -20,6 +23,10 @@ export class RPSSI extends BasePeripheral {
20
23
  return 0;
21
24
  case SSI_SR:
22
25
  return SSI_SR_TFE_BITS | SSI_SR_RFNE_BITS | SSI_SR_TFNF_BITS;
26
+ case SSI_IDR:
27
+ return 0x51535049;
28
+ case SSI_VERSION_ID:
29
+ return 0x3430312a;
23
30
  case SSI_DR0:
24
31
  return this.dr0;
25
32
  }
@@ -13,7 +13,10 @@ export declare class RPUART extends BasePeripheral implements Peripheral {
13
13
  private rxFIFO;
14
14
  private interruptMask;
15
15
  private interruptStatus;
16
+ private intDivisor;
17
+ private fracDivisor;
16
18
  onByte?: (value: number) => void;
19
+ onBaudRateChange?: (baudRate: number) => void;
17
20
  constructor(rp2040: RP2040, name: string, irq: number, dreq: IUARTDMAChannels);
18
21
  get enabled(): boolean;
19
22
  get txEnabled(): boolean;
@@ -23,6 +26,8 @@ export declare class RPUART extends BasePeripheral implements Peripheral {
23
26
  * Number of bits per UART character
24
27
  */
25
28
  get wordLength(): 5 | 6 | 7 | 8 | undefined;
29
+ get baudDivider(): number;
30
+ get baudRate(): number;
26
31
  get flags(): number;
27
32
  checkInterrupts(): void;
28
33
  feedByte(value: number): void;
@@ -2,12 +2,22 @@ import { FIFO } from '../utils/fifo.js';
2
2
  import { BasePeripheral } from './peripheral.js';
3
3
  const UARTDR = 0x0;
4
4
  const UARTFR = 0x18;
5
+ const UARTIBRD = 0x24;
6
+ const UARTFBRD = 0x28;
5
7
  const UARTLCR_H = 0x2c;
6
8
  const UARTCR = 0x30;
7
9
  const UARTIMSC = 0x38;
8
10
  const UARTIRIS = 0x3c;
9
11
  const UARTIMIS = 0x40;
10
12
  const UARTICR = 0x44;
13
+ const UARTPERIPHID0 = 0xfe0;
14
+ const UARTPERIPHID1 = 0xfe4;
15
+ const UARTPERIPHID2 = 0xfe8;
16
+ const UARTPERIPHID3 = 0xfec;
17
+ const UARTPCELLID0 = 0xff0;
18
+ const UARTPCELLID1 = 0xff4;
19
+ const UARTPCELLID2 = 0xff8;
20
+ const UARTPCELLID3 = 0xffc;
11
21
  // UARTFR bits:
12
22
  const TXFE = 1 << 7;
13
23
  const RXFF = 1 << 6;
@@ -30,6 +40,8 @@ export class RPUART extends BasePeripheral {
30
40
  this.rxFIFO = new FIFO(32);
31
41
  this.interruptMask = 0;
32
42
  this.interruptStatus = 0;
43
+ this.intDivisor = 0;
44
+ this.fracDivisor = 0;
33
45
  }
34
46
  get enabled() {
35
47
  return !!(this.ctrlRegister & UARTEN);
@@ -58,6 +70,12 @@ export class RPUART extends BasePeripheral {
58
70
  return 8;
59
71
  }
60
72
  }
73
+ get baudDivider() {
74
+ return this.intDivisor + this.fracDivisor / 64;
75
+ }
76
+ get baudRate() {
77
+ return Math.round(this.rp2040.clkPeri / (this.baudDivider * 16));
78
+ }
61
79
  get flags() {
62
80
  return (this.rxFIFO.full ? RXFF : 0) | (this.rxFIFO.empty ? RXFE : 0) | TXFE;
63
81
  }
@@ -82,6 +100,10 @@ export class RPUART extends BasePeripheral {
82
100
  }
83
101
  case UARTFR:
84
102
  return this.flags;
103
+ case UARTIBRD:
104
+ return this.intDivisor;
105
+ case UARTFBRD:
106
+ return this.fracDivisor;
85
107
  case UARTLCR_H:
86
108
  return this.lineCtrlRegister;
87
109
  case UARTCR:
@@ -92,15 +114,39 @@ export class RPUART extends BasePeripheral {
92
114
  return this.interruptStatus;
93
115
  case UARTIMIS:
94
116
  return this.interruptStatus & this.interruptMask;
117
+ case UARTPERIPHID0:
118
+ return 0x11;
119
+ case UARTPERIPHID1:
120
+ return 0x10;
121
+ case UARTPERIPHID2:
122
+ return 0x34;
123
+ case UARTPERIPHID3:
124
+ return 0x00;
125
+ case UARTPCELLID0:
126
+ return 0x0d;
127
+ case UARTPCELLID1:
128
+ return 0xf0;
129
+ case UARTPCELLID2:
130
+ return 0x05;
131
+ case UARTPCELLID3:
132
+ return 0xb1;
95
133
  }
96
134
  return super.readUint32(offset);
97
135
  }
98
136
  writeUint32(offset, value) {
99
- var _a;
137
+ var _a, _b, _c;
100
138
  switch (offset) {
101
139
  case UARTDR:
102
140
  (_a = this.onByte) === null || _a === void 0 ? void 0 : _a.call(this, value & 0xff);
103
141
  break;
142
+ case UARTIBRD:
143
+ this.intDivisor = value & 0xffff;
144
+ (_b = this.onBaudRateChange) === null || _b === void 0 ? void 0 : _b.call(this, this.baudRate);
145
+ break;
146
+ case UARTFBRD:
147
+ this.fracDivisor = value & 0x3f;
148
+ (_c = this.onBaudRateChange) === null || _c === void 0 ? void 0 : _c.call(this, this.baudRate);
149
+ break;
104
150
  case UARTLCR_H:
105
151
  this.lineCtrlRegister = value;
106
152
  break;
@@ -0,0 +1,19 @@
1
+ import { RP2040 } from '../rp2040.js';
2
+ import { Timer32, Timer32PeriodicAlarm } from '../utils/timer32.js';
3
+ import { BasePeripheral, Peripheral } from './peripheral.js';
4
+ export declare class RPWatchdog extends BasePeripheral implements Peripheral {
5
+ readonly timer: Timer32;
6
+ readonly alarm: Timer32PeriodicAlarm;
7
+ readonly scratchData: Uint32Array;
8
+ private enable;
9
+ private tickEnable;
10
+ private reason;
11
+ private pauseDbg0;
12
+ private pauseDbg1;
13
+ private pauseJtag;
14
+ /** Called when the watchdog triggers - override with your own soft reset implementation */
15
+ onWatchdogTrigger: () => void;
16
+ constructor(rp2040: RP2040, name: string);
17
+ readUint32(offset: number): number;
18
+ writeUint32(offset: number, value: number): void;
19
+ }
@@ -0,0 +1,126 @@
1
+ import { Timer32, Timer32PeriodicAlarm, TimerMode } from '../utils/timer32.js';
2
+ import { BasePeripheral } from './peripheral.js';
3
+ const CTRL = 0x00; // Control register
4
+ const LOAD = 0x04; // Load the watchdog timer.
5
+ const REASON = 0x08; // Logs the reason for the last reset.
6
+ const SCRATCH0 = 0x0c; // Scratch register
7
+ const SCRATCH1 = 0x10; // Scratch register
8
+ const SCRATCH2 = 0x14; // Scratch register
9
+ const SCRATCH3 = 0x18; // Scratch register
10
+ const SCRATCH4 = 0x1c; // Scratch register
11
+ const SCRATCH5 = 0x20; // Scratch register
12
+ const SCRATCH6 = 0x24; // Scratch register
13
+ const SCRATCH7 = 0x28; // Scratch register
14
+ const TICK = 0x2c; // Controls the tick generator
15
+ // CTRL bits:
16
+ const TRIGGER = 1 << 31;
17
+ const ENABLE = 1 << 30;
18
+ const PAUSE_DBG1 = 1 << 26;
19
+ const PAUSE_DBG0 = 1 << 25;
20
+ const PAUSE_JTAG = 1 << 24;
21
+ const TIME_MASK = 0xffffff;
22
+ const TIME_SHIFT = 0;
23
+ // LOAD bits
24
+ const LOAD_MASK = 0xffffff;
25
+ const LOAD_SHIFT = 0;
26
+ // REASON bits:
27
+ const FORCE = 1 << 1;
28
+ const TIMER = 1 << 0;
29
+ // TICK bits:
30
+ const COUNT_MASK = 0x1ff;
31
+ const COUNT_SHIFT = 11;
32
+ const RUNNING = 1 << 10;
33
+ const TICK_ENABLE = 1 << 9;
34
+ const CYCLES_MASK = 0x1ff;
35
+ const CYCLES_SHIFT = 0;
36
+ const TICK_FREQUENCY = 2000000; // Actually 1 MHz, but due to errata RP2040-E1, the timer is decremented twice per tick
37
+ export class RPWatchdog extends BasePeripheral {
38
+ // User provided
39
+ constructor(rp2040, name) {
40
+ super(rp2040, name);
41
+ this.scratchData = new Uint32Array(8);
42
+ this.enable = false;
43
+ this.tickEnable = true;
44
+ this.reason = 0;
45
+ this.pauseDbg0 = true;
46
+ this.pauseDbg1 = true;
47
+ this.pauseJtag = true;
48
+ /** Called when the watchdog triggers - override with your own soft reset implementation */
49
+ this.onWatchdogTrigger = () => {
50
+ this.rp2040.logger.warn(this.name, 'Watchdog triggered, but no reset handler provided');
51
+ };
52
+ this.timer = new Timer32(rp2040.clock, TICK_FREQUENCY);
53
+ this.timer.mode = TimerMode.Decrement;
54
+ this.timer.enable = false;
55
+ this.alarm = new Timer32PeriodicAlarm(this.timer, () => {
56
+ var _a;
57
+ this.reason = TIMER;
58
+ (_a = this.onWatchdogTrigger) === null || _a === void 0 ? void 0 : _a.call(this);
59
+ });
60
+ this.alarm.target = 0;
61
+ this.alarm.enable = false;
62
+ }
63
+ readUint32(offset) {
64
+ switch (offset) {
65
+ case CTRL:
66
+ return ((this.timer.enable ? ENABLE : 0) |
67
+ (this.pauseDbg0 ? PAUSE_DBG0 : 0) |
68
+ (this.pauseDbg1 ? PAUSE_DBG1 : 0) |
69
+ (this.pauseJtag ? PAUSE_JTAG : 0) |
70
+ ((this.timer.counter & TIME_MASK) << TIME_SHIFT));
71
+ case REASON:
72
+ return this.reason;
73
+ case SCRATCH0:
74
+ case SCRATCH1:
75
+ case SCRATCH2:
76
+ case SCRATCH3:
77
+ case SCRATCH4:
78
+ case SCRATCH5:
79
+ case SCRATCH6:
80
+ case SCRATCH7:
81
+ return this.scratchData[(offset - SCRATCH0) >> 2];
82
+ case TICK:
83
+ // TODO COUNT bits
84
+ return this.tickEnable ? RUNNING | TICK_ENABLE : 0;
85
+ }
86
+ return super.readUint32(offset);
87
+ }
88
+ writeUint32(offset, value) {
89
+ var _a;
90
+ switch (offset) {
91
+ case CTRL:
92
+ if (value & TRIGGER) {
93
+ this.reason = FORCE;
94
+ (_a = this.onWatchdogTrigger) === null || _a === void 0 ? void 0 : _a.call(this);
95
+ }
96
+ this.enable = !!(value & ENABLE);
97
+ this.timer.enable = this.enable && this.tickEnable;
98
+ this.alarm.enable = this.enable && this.tickEnable;
99
+ this.pauseDbg0 = !!(value & PAUSE_DBG0);
100
+ this.pauseDbg1 = !!(value & PAUSE_DBG1);
101
+ this.pauseJtag = !!(value & PAUSE_JTAG);
102
+ break;
103
+ case LOAD:
104
+ this.timer.set((value >>> LOAD_SHIFT) & LOAD_MASK);
105
+ break;
106
+ case SCRATCH0:
107
+ case SCRATCH1:
108
+ case SCRATCH2:
109
+ case SCRATCH3:
110
+ case SCRATCH4:
111
+ case SCRATCH5:
112
+ case SCRATCH6:
113
+ case SCRATCH7:
114
+ this.scratchData[(offset - SCRATCH0) >> 2] = value;
115
+ break;
116
+ case TICK:
117
+ this.tickEnable = !!(value & TICK_ENABLE);
118
+ this.timer.enable = this.enable && this.tickEnable;
119
+ this.alarm.enable = this.enable && this.tickEnable;
120
+ // TODO - handle CYCLES (tick also affectes timer)
121
+ break;
122
+ default:
123
+ super.writeUint32(offset, value);
124
+ }
125
+ }
126
+ }
@@ -23,6 +23,7 @@ import { RPTBMAN } from './peripherals/tbman.js';
23
23
  import { RPTimer } from './peripherals/timer.js';
24
24
  import { RPUART } from './peripherals/uart.js';
25
25
  import { RPUSBController } from './peripherals/usb.js';
26
+ import { RPWatchdog } from './peripherals/watchdog.js';
26
27
  import { RPSIO } from './sio.js';
27
28
  import { ConsoleLogger, LogLevel } from './utils/logging.js';
28
29
  export const FLASH_START_ADDRESS = 0x10000000;
@@ -147,7 +148,7 @@ export class RP2040 {
147
148
  0x4004c: this.adc,
148
149
  0x40050: this.pwm,
149
150
  0x40054: new RPTimer(this, 'TIMER_BASE'),
150
- 0x40058: new UnimplementedPeripheral(this, 'WATCHDOG_BASE'),
151
+ 0x40058: new RPWatchdog(this, 'WATCHDOG_BASE'),
151
152
  0x4005c: new RP2040RTC(this, 'RTC_BASE'),
152
153
  0x40060: new UnimplementedPeripheral(this, 'ROSC_BASE'),
153
154
  0x40064: new UnimplementedPeripheral(this, 'VREG_AND_CHIP_RESET_BASE'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [