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.
- package/dist/cjs/peripherals/ssi.js +7 -0
- package/dist/cjs/peripherals/uart.d.ts +5 -0
- package/dist/cjs/peripherals/uart.js +47 -1
- package/dist/cjs/peripherals/watchdog.d.ts +19 -0
- package/dist/cjs/peripherals/watchdog.js +130 -0
- package/dist/cjs/rp2040.js +2 -1
- package/dist/esm/peripherals/ssi.js +7 -0
- package/dist/esm/peripherals/uart.d.ts +5 -0
- package/dist/esm/peripherals/uart.js +47 -1
- package/dist/esm/peripherals/watchdog.d.ts +19 -0
- package/dist/esm/peripherals/watchdog.js +126 -0
- package/dist/esm/rp2040.js +2 -1
- package/package.json +1 -1
|
@@ -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;
|
package/dist/cjs/rp2040.js
CHANGED
|
@@ -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
|
|
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
|
+
}
|
package/dist/esm/rp2040.js
CHANGED
|
@@ -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
|
|
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'),
|