I'm just doubling checking something I noticed and I could not find a topic related to this.
On the RP2040 Connect, with MBED OS, I am trying to sense an analog input at the highest possible sample rate I can. To test is I set tone(8,4000) and feed this output (D8) into the analog sense pin. What I noticed is that as I increase the frequency past about 8KHz, the overall performance of my sense loop drops dramatically. At 4KHz tone output frequency, I was getting about 100ksps (not bad!). If I increase the tone to 8Kz the sample rate drops to about 80-90ksps. If I increase to 16Khz tone output frequency, the sample rate has dropped to about 33ksps.
I'm guessing this is because the RP2040 emulates the tone output with software (running through the MBED OS) which is slowing down execution of my sample loop.
Can someone confirm this? I did not notice this on the Arduino Nano IOT 33, but the sample rates that are much lower, so perhaps it was not a factor.
Not a crushing problem, just curious. I can also use another Arduino to generate the tone output if I need to.
I don't know but that makes sense. Every instruction takes processor cycles and that will limit how fast you can loop and sample. One the regular Arduino (ATmega chip) PWM is built-into the chip and it doesn't slow-down processing so I wouldn't be surprised if tone() works similarly on that chip.
Unfortunately my sketch is pretty complicated because I have to dump the resulting samples to my PC and display them through another program. It also includes custom libraries for the I/O to the other PC. Its impossible to see the resulting sample rate without that. I will post the sketch as it is, but it probably won't help you much.
is where I flash sample 256 samples as fast as possible. There is no additional code
other than pushing the resulting analogRead output into a buffer. No I/O is done
until the whole buffer is full.
The only difference in observed sample rate is when I change the tone command in setup to something like tone(8,4000).
I think I answered my own question. Looking in the MBED OS source code there is a file called Tone.cpp which defines the tone() function and also declares a timer and attached a callback (presumably for an interrupt):
ticker.attach(mbed::callback(this, &Tone::toggle), 500000us / frequency );
if (duration != 0) {
start_timeout();
This would create a timer which times out every time the output needs to be toggled to create that frequency of oscillation.
The toggle routine is not complex but the overhead of swapping out registers, storing pointers etc. is probably going to be somewhat expensive. Doing it every ~31.25 us is pretty expensive computationally.