Skip to content

Commit bedfbda

Browse files
Clear PIO FIFOs when updating Tone and Servos (#206)
The PIO programs that generate tone() and Servo() use the TX FIFO to receive updates to the period/duty cycle. The original code would push into the FIFO (potentially blocking the app if the FIFO was full) and generate at least one cycle of every value written into the control. Basically, the output would lag the changes by 1 cycle or more (which could be 20ms+ on Servo). Fix this by clearing any old, ungrabbed values from the FIFO before sending a new one to the program. Instead of a FIFO, there is effectively now just a control register and updates will be immediate. Update the Siren.ino example with delays because now the tone() calls will not block and run 10x+ faster.
1 parent 9fbf6ab commit bedfbda

File tree

3 files changed

+4
-1
lines changed

3 files changed

+4
-1
lines changed

cores/rp2040/Tone.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
8888
newTone->alarm = 0;
8989
}
9090
}
91+
pio_sm_clear_fifos(newTone->pio, newTone->sm); // Remove any old updates that haven't yet taken effect
9192
pio_sm_put_blocking(newTone->pio, newTone->sm, RP2040::usToPIOCycles(us));
9293
pio_sm_set_enabled(newTone->pio, newTone->sm, true);
9394

libraries/Servo/src/Servo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ void Servo::writeMicroseconds(int value) {
135135
value = constrain(value, _minUs, _maxUs);
136136
_valueUs = value;
137137
if (_attached) {
138+
pio_sm_clear_fifos(_pio, _smIdx); // Remove any old updates that haven't yet taken effect
138139
pio_sm_put_blocking(_pio, _smIdx, RP2040::usToPIOCycles(value) / 3);
139140
}
140141
}

libraries/rp2040/examples/Siren/Siren.ino

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ void setup() {
77
}
88

99
void loop() {
10-
for (int i = 100; i < 10000; i += 5) {
10+
for (int i = 100; i < 10000; i += 1) {
1111
tone(TONEPIN, i);
12+
delayMicroseconds(20);
1213
}
1314
}

0 commit comments

Comments
 (0)