rp2040js 0.17.9 → 0.17.11

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.
@@ -1,4 +1,5 @@
1
- import { IClockTimer } from '../clock/clock';
1
+ import { RP2040 } from '../rp2040';
2
+ import { Timer32, Timer32PeriodicAlarm } from '../utils/timer32';
2
3
  import { BasePeripheral, Peripheral } from './peripheral';
3
4
  export declare const CPUID = 3328;
4
5
  export declare const ICSR = 3332;
@@ -12,10 +13,13 @@ export declare const SHPR3 = 3360;
12
13
  */
13
14
  export declare class RPPPB extends BasePeripheral implements Peripheral {
14
15
  systickCountFlag: boolean;
15
- systickControl: number;
16
- systickLastZero: number;
16
+ systickClkSource: boolean;
17
+ systickIntEnable: boolean;
17
18
  systickReload: number;
18
- systickTimer: IClockTimer | null;
19
+ readonly systickTimer: Timer32;
20
+ readonly systickAlarm: Timer32PeriodicAlarm;
21
+ constructor(rp2040: RP2040, name: string);
22
+ reset(): void;
19
23
  readUint32(offset: number): number;
20
24
  writeUint32(offset: number, value: number): void;
21
25
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RPPPB = exports.SHPR3 = exports.SHPR2 = exports.VTOR = exports.ICSR = exports.CPUID = void 0;
4
4
  const irq_1 = require("../irq");
5
+ const timer32_1 = require("../utils/timer32");
5
6
  const peripheral_1 = require("./peripheral");
6
7
  exports.CPUID = 0xd00;
7
8
  exports.ICSR = 0xd04;
@@ -43,14 +44,32 @@ const VECTACTIVE_SHIFT = 0;
43
44
  * Included peripheral: NVIC, SysTick timer
44
45
  */
45
46
  class RPPPB extends peripheral_1.BasePeripheral {
46
- constructor() {
47
- super(...arguments);
47
+ constructor(rp2040, name) {
48
+ super(rp2040, name);
48
49
  // Systick
49
50
  this.systickCountFlag = false;
50
- this.systickControl = 0;
51
- this.systickLastZero = 0;
51
+ this.systickClkSource = false;
52
+ this.systickIntEnable = false;
52
53
  this.systickReload = 0;
53
- this.systickTimer = null;
54
+ this.systickTimer = new timer32_1.Timer32(this.rp2040.clock, this.rp2040.clkSys);
55
+ this.systickAlarm = new timer32_1.Timer32PeriodicAlarm(this.systickTimer, () => {
56
+ this.systickCountFlag = true;
57
+ if (this.systickIntEnable) {
58
+ this.rp2040.core.pendingSystick = true;
59
+ this.rp2040.core.interruptsUpdated = true;
60
+ }
61
+ this.systickTimer.set(this.systickReload);
62
+ });
63
+ this.systickTimer.top = 0xffffff;
64
+ this.systickTimer.mode = timer32_1.TimerMode.Decrement;
65
+ this.systickAlarm.target = 0;
66
+ this.systickAlarm.enable = true;
67
+ this.reset();
68
+ }
69
+ reset() {
70
+ this.writeUint32(SYST_CSR, 0);
71
+ this.writeUint32(SYST_RVR, 0xffffff);
72
+ this.systickTimer.set(0xffffff);
54
73
  }
55
74
  readUint32(offset) {
56
75
  const { rp2040 } = this;
@@ -106,16 +125,14 @@ class RPPPB extends peripheral_1.BasePeripheral {
106
125
  /* SysTick */
107
126
  case SYST_CSR: {
108
127
  const countFlagValue = this.systickCountFlag ? 1 << 16 : 0;
128
+ const clkSourceValue = this.systickClkSource ? 1 << 2 : 0;
129
+ const tickIntValue = this.systickIntEnable ? 1 << 1 : 0;
130
+ const enableFlagValue = this.systickTimer.enable ? 1 << 0 : 0;
109
131
  this.systickCountFlag = false;
110
- return countFlagValue | (this.systickControl & 0x7);
111
- }
112
- case SYST_CVR: {
113
- const delta = (rp2040.clock.micros - this.systickLastZero) % (this.systickReload + 1);
114
- if (!delta) {
115
- return 0;
116
- }
117
- return this.systickReload - (delta - 1);
132
+ return countFlagValue | clkSourceValue | tickIntValue | enableFlagValue;
118
133
  }
134
+ case SYST_CVR:
135
+ return this.systickTimer.counter;
119
136
  case SYST_RVR:
120
137
  return this.systickReload;
121
138
  case SYST_CALIB:
@@ -194,32 +211,12 @@ class RPPPB extends peripheral_1.BasePeripheral {
194
211
  return;
195
212
  // SysTick
196
213
  case SYST_CSR:
197
- {
198
- const prevInterrupt = this.systickControl === 0x7;
199
- const interrupt = value === 0x7;
200
- if (interrupt && !prevInterrupt) {
201
- // TODO: adjust the timer based on the current systick value
202
- const systickCallback = () => {
203
- core.pendingSystick = true;
204
- core.interruptsUpdated = true;
205
- if (core.waiting && core.checkForInterrupts()) {
206
- core.waiting = false;
207
- }
208
- this.systickTimer = rp2040.clock.createTimer(this.systickReload + 1, systickCallback);
209
- };
210
- this.systickTimer = rp2040.clock.createTimer(this.systickReload + 1, systickCallback);
211
- }
212
- if (prevInterrupt && interrupt) {
213
- if (this.systickTimer) {
214
- rp2040.clock.deleteTimer(this.systickTimer);
215
- }
216
- this.systickTimer = null;
217
- }
218
- this.systickControl = value & 0x7;
219
- }
214
+ this.systickClkSource = value & (1 << 2) ? true : false;
215
+ this.systickIntEnable = value & (1 << 1) ? true : false;
216
+ this.systickTimer.enable = value & (1 << 0) ? true : false;
220
217
  return;
221
218
  case SYST_CVR:
222
- this.warn(`SYSTICK CVR: not implemented yet, value=${value}`);
219
+ this.systickTimer.set(0);
223
220
  return;
224
221
  case SYST_RVR:
225
222
  this.systickReload = value;
@@ -192,7 +192,7 @@ class Timer32PeriodicAlarm {
192
192
  }
193
193
  }
194
194
  if (mode === TimerMode.Decrement) {
195
- cycleDelta = top - cycleDelta;
195
+ cycleDelta = top + 1 - cycleDelta;
196
196
  }
197
197
  const cyclesToAlarm = cycleDelta >>> 0;
198
198
  const microsToAlarm = timer.toMicros(cyclesToAlarm);
@@ -1,4 +1,5 @@
1
- import { IClockTimer } from '../clock/clock';
1
+ import { RP2040 } from '../rp2040';
2
+ import { Timer32, Timer32PeriodicAlarm } from '../utils/timer32';
2
3
  import { BasePeripheral, Peripheral } from './peripheral';
3
4
  export declare const CPUID = 3328;
4
5
  export declare const ICSR = 3332;
@@ -12,10 +13,13 @@ export declare const SHPR3 = 3360;
12
13
  */
13
14
  export declare class RPPPB extends BasePeripheral implements Peripheral {
14
15
  systickCountFlag: boolean;
15
- systickControl: number;
16
- systickLastZero: number;
16
+ systickClkSource: boolean;
17
+ systickIntEnable: boolean;
17
18
  systickReload: number;
18
- systickTimer: IClockTimer | null;
19
+ readonly systickTimer: Timer32;
20
+ readonly systickAlarm: Timer32PeriodicAlarm;
21
+ constructor(rp2040: RP2040, name: string);
22
+ reset(): void;
19
23
  readUint32(offset: number): number;
20
24
  writeUint32(offset: number, value: number): void;
21
25
  }
@@ -1,4 +1,5 @@
1
1
  import { MAX_HARDWARE_IRQ } from '../irq';
2
+ import { Timer32, Timer32PeriodicAlarm, TimerMode } from '../utils/timer32';
2
3
  import { BasePeripheral } from './peripheral';
3
4
  export const CPUID = 0xd00;
4
5
  export const ICSR = 0xd04;
@@ -40,14 +41,32 @@ const VECTACTIVE_SHIFT = 0;
40
41
  * Included peripheral: NVIC, SysTick timer
41
42
  */
42
43
  export class RPPPB extends BasePeripheral {
43
- constructor() {
44
- super(...arguments);
44
+ constructor(rp2040, name) {
45
+ super(rp2040, name);
45
46
  // Systick
46
47
  this.systickCountFlag = false;
47
- this.systickControl = 0;
48
- this.systickLastZero = 0;
48
+ this.systickClkSource = false;
49
+ this.systickIntEnable = false;
49
50
  this.systickReload = 0;
50
- this.systickTimer = null;
51
+ this.systickTimer = new Timer32(this.rp2040.clock, this.rp2040.clkSys);
52
+ this.systickAlarm = new Timer32PeriodicAlarm(this.systickTimer, () => {
53
+ this.systickCountFlag = true;
54
+ if (this.systickIntEnable) {
55
+ this.rp2040.core.pendingSystick = true;
56
+ this.rp2040.core.interruptsUpdated = true;
57
+ }
58
+ this.systickTimer.set(this.systickReload);
59
+ });
60
+ this.systickTimer.top = 0xffffff;
61
+ this.systickTimer.mode = TimerMode.Decrement;
62
+ this.systickAlarm.target = 0;
63
+ this.systickAlarm.enable = true;
64
+ this.reset();
65
+ }
66
+ reset() {
67
+ this.writeUint32(SYST_CSR, 0);
68
+ this.writeUint32(SYST_RVR, 0xffffff);
69
+ this.systickTimer.set(0xffffff);
51
70
  }
52
71
  readUint32(offset) {
53
72
  const { rp2040 } = this;
@@ -103,16 +122,14 @@ export class RPPPB extends BasePeripheral {
103
122
  /* SysTick */
104
123
  case SYST_CSR: {
105
124
  const countFlagValue = this.systickCountFlag ? 1 << 16 : 0;
125
+ const clkSourceValue = this.systickClkSource ? 1 << 2 : 0;
126
+ const tickIntValue = this.systickIntEnable ? 1 << 1 : 0;
127
+ const enableFlagValue = this.systickTimer.enable ? 1 << 0 : 0;
106
128
  this.systickCountFlag = false;
107
- return countFlagValue | (this.systickControl & 0x7);
108
- }
109
- case SYST_CVR: {
110
- const delta = (rp2040.clock.micros - this.systickLastZero) % (this.systickReload + 1);
111
- if (!delta) {
112
- return 0;
113
- }
114
- return this.systickReload - (delta - 1);
129
+ return countFlagValue | clkSourceValue | tickIntValue | enableFlagValue;
115
130
  }
131
+ case SYST_CVR:
132
+ return this.systickTimer.counter;
116
133
  case SYST_RVR:
117
134
  return this.systickReload;
118
135
  case SYST_CALIB:
@@ -191,32 +208,12 @@ export class RPPPB extends BasePeripheral {
191
208
  return;
192
209
  // SysTick
193
210
  case SYST_CSR:
194
- {
195
- const prevInterrupt = this.systickControl === 0x7;
196
- const interrupt = value === 0x7;
197
- if (interrupt && !prevInterrupt) {
198
- // TODO: adjust the timer based on the current systick value
199
- const systickCallback = () => {
200
- core.pendingSystick = true;
201
- core.interruptsUpdated = true;
202
- if (core.waiting && core.checkForInterrupts()) {
203
- core.waiting = false;
204
- }
205
- this.systickTimer = rp2040.clock.createTimer(this.systickReload + 1, systickCallback);
206
- };
207
- this.systickTimer = rp2040.clock.createTimer(this.systickReload + 1, systickCallback);
208
- }
209
- if (prevInterrupt && interrupt) {
210
- if (this.systickTimer) {
211
- rp2040.clock.deleteTimer(this.systickTimer);
212
- }
213
- this.systickTimer = null;
214
- }
215
- this.systickControl = value & 0x7;
216
- }
211
+ this.systickClkSource = value & (1 << 2) ? true : false;
212
+ this.systickIntEnable = value & (1 << 1) ? true : false;
213
+ this.systickTimer.enable = value & (1 << 0) ? true : false;
217
214
  return;
218
215
  case SYST_CVR:
219
- this.warn(`SYSTICK CVR: not implemented yet, value=${value}`);
216
+ this.systickTimer.set(0);
220
217
  return;
221
218
  case SYST_RVR:
222
219
  this.systickReload = value;
@@ -188,7 +188,7 @@ export class Timer32PeriodicAlarm {
188
188
  }
189
189
  }
190
190
  if (mode === TimerMode.Decrement) {
191
- cycleDelta = top - cycleDelta;
191
+ cycleDelta = top + 1 - cycleDelta;
192
192
  }
193
193
  const cyclesToAlarm = cycleDelta >>> 0;
194
194
  const microsToAlarm = timer.toMicros(cyclesToAlarm);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rp2040js",
3
- "version": "0.17.9",
3
+ "version": "0.17.11",
4
4
  "description": "Raspberry Pi Pico (RP2040) Emulator",
5
5
  "repository": "https://github.com/wokwi/rp2040js",
6
6
  "keywords": [