Skip to content

Commit 0d18010

Browse files
committed
pio: run in sync with CPU core, honor ClockDiv
1 parent 52f89c4 commit 0d18010

File tree

2 files changed

+45
-13
lines changed

2 files changed

+45
-13
lines changed

src/peripherals/pio.ts

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ export class StateMachine {
138138

139139
clockDivInt: number = 1;
140140
clockDivFrac: number = 0;
141+
curClockInt: number = 0;
142+
curClockFrac: number = 0;
143+
remainingDelay: number = 0;
141144
execCtrl = 0x1f << 12;
142145
shiftCtrl = 0b11 << 18;
143146
pinCtrl = 0x5 << 26;
@@ -436,7 +439,7 @@ export class StateMachine {
436439
}
437440
}
438441

439-
executeInstruction(opcode: number) {
442+
executeInstruction(opcode: number): number {
440443
const arg = opcode & 0xff;
441444
switch (opcode >>> 13) {
442445
/* JMP */
@@ -654,14 +657,16 @@ export class StateMachine {
654657

655658
if (this.execValid) {
656659
this.execValid = false;
657-
this.executeInstruction(this.execOpcode);
660+
return this.executeInstruction(this.execOpcode);
658661
} else if (this.waiting) {
659662
if (this.waitDelay < 0) {
660663
this.waitDelay = delay;
661664
}
662665
this.checkWait();
666+
return delay;
663667
} else {
664668
this.cycles += delay;
669+
return delay;
665670
}
666671
}
667672

@@ -683,6 +688,27 @@ export class StateMachine {
683688
}
684689

685690
step() {
691+
if (!this.enabled) {
692+
return;
693+
}
694+
695+
this.curClockFrac += this.clockDivFrac;
696+
if (this.curClockFrac > 0xff) {
697+
this.curClockInt++;
698+
this.curClockFrac -= 0x100;
699+
}
700+
this.curClockInt++;
701+
if (this.curClockInt < this.clockDivInt) {
702+
return;
703+
} else {
704+
this.curClockInt -= this.clockDivInt;
705+
}
706+
707+
if (this.remainingDelay > 0) {
708+
this.remainingDelay--;
709+
return;
710+
}
711+
686712
if (this.waiting) {
687713
this.checkWait();
688714
if (this.waiting) {
@@ -691,7 +717,7 @@ export class StateMachine {
691717
}
692718

693719
this.updatePC = true;
694-
this.executeInstruction(this.pio.instructions[this.pc]);
720+
this.remainingDelay += this.executeInstruction(this.pio.instructions[this.pc]);
695721
if (this.updatePC) {
696722
this.nextPC();
697723
}
@@ -833,6 +859,9 @@ export class StateMachine {
833859

834860
restart() {
835861
this.cycles = 0;
862+
this.curClockInt = 0;
863+
this.curClockFrac = 0;
864+
this.remainingDelay = 0;
836865
this.inputShiftCount = 0;
837866
this.outputShiftCount = 32;
838867
this.inputShiftReg = 0;
@@ -1080,7 +1109,6 @@ export class RPPIO extends BasePeripheral implements Peripheral {
10801109
const shouldRun = value & 0xf;
10811110
if (this.stopped && shouldRun) {
10821111
this.stopped = false;
1083-
this.run();
10841112
}
10851113
if (!shouldRun) {
10861114
this.stopped = true;
@@ -1179,21 +1207,15 @@ export class RPPIO extends BasePeripheral implements Peripheral {
11791207
}
11801208

11811209
step() {
1210+
if (this.stopped) {
1211+
return;
1212+
}
11821213
for (const machine of this.machines) {
11831214
machine.step();
11841215
}
11851216
this.checkChangedPins();
11861217
}
11871218

1188-
run() {
1189-
for (let i = 0; i < 1000 && !this.stopped; i++) {
1190-
this.step();
1191-
}
1192-
if (!this.stopped) {
1193-
this.runTimer = setTimeout(() => this.run(), 0);
1194-
}
1195-
}
1196-
11971219
stop() {
11981220
for (const machine of this.machines) {
11991221
machine.enabled = false;

src/rp2040.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,15 +350,25 @@ export class RP2040 {
350350
}
351351

352352
step() {
353+
let coreStartCycles = this.core.cycles;
353354
this.core.executeInstruction();
355+
for (let cycle = coreStartCycles; cycle < this.core.cycles; cycle++) {
356+
this.pio[0].step();
357+
this.pio[1].step();
358+
}
354359
}
355360

356361
execute() {
357362
this.clock.resume();
358363
this.executeTimer = null;
359364
this.stopped = false;
360365
for (let i = 0; i < 100000 && !this.stopped && !this.core.waiting; i++) {
366+
let coreStartCycles = this.core.cycles;
361367
this.core.executeInstruction();
368+
for (let cycle = coreStartCycles; cycle < this.core.cycles; cycle++) {
369+
this.pio[0].step();
370+
this.pio[1].step();
371+
}
362372
}
363373
if (!this.stopped) {
364374
this.executeTimer = setTimeout(() => this.execute(), 0);

0 commit comments

Comments
 (0)