I prepared simple test code to benchmark pin bit banging for RP2040.
I am using board Raspberry Pi Pico programmed using manager Arduino Mbed OS RP2040 Boards.
There are no issues with programming. Everything looks working fine. But looking on scope record I observed strange behavior. It looks like commands execution is interrupted for short while every 1 ms. Normally it gets bit banging speed of 2 MHz but with some breaks in the output signal:
In the Arduino I do not disable it I use the appropriate PWM pins which are driven by the internal counter/timer. These pins are well documented in the Arduino literature and on the forums. In the RP I do not have a clue.
I encountered the same issue when reading data from a camera (and missing bytes every milliseconds). I fixed it by surrounding my code with "noInterrupts();"/"interrupts()".
I do wonder why Arduino needs a millisecond timer given that the RP2040 comes with a microsecond clock already... Is there a way to get the Arduino IDE but with as little as possible "help" from the framework?
Could also be the USB tick.
mBed may need the tick for multitasking as well. Digging through several layers of complex OS stuff (Arduino, MBed, Pico SDK, hardware) is annoyingly more difficult than you might expect ''
Disabling interrupts improved stability a lot. There is still some jitter when generating periodical signal. This jitter seems to be in range of few instructions. That is acceptable for slow UART/SPI/I2C and similar applications when software implementation of the protocol is necessary.
Thank you.
If you are using Earle Philhower's RP2040 board package then you can use the 2nd processor easily as that is not disturbed by interrupts. The code below produces a stable clock output on GPIO 18 of about 38KHz for example:
void setup() {
pinMode(18, OUTPUT);
}
void loop() {
}
void setup1() {
}
// Use 2nd processor so timing loop not disturbed by interrupts.
void loop1() {
sio_hw->gpio_set = (1ul << 18); // fast equivalent to digitalWrite(18, HIGH);
delayMicroseconds(13);
sio_hw->gpio_clr = (1ul << 18); // fast equivalent to digitalWrite(18, LOW);
delayMicroseconds(13);
}