Closed flatt3rn closed 3 days ago
Because this is special HW only you have, there's not much we can do here. Most likely it's a timing issue. You could try adjusting the baud up or down a few percent to see if it can match whatever you're connecting it to.
You could also try capturing the devices' serial waveform at high enough resolution to see the actual bit-times to verify.
Quick loopback test (wire from GPIO 0 <-> GPIO 3) looks fine:
#include <SerialPIO.h>
SerialPIO s(2,3);
void setup1() {
Serial1.setRX(1);
Serial1.setTX(0);
Serial1.begin(9600);
while (1) {
delay(10);
Serial1.println("yo, yo, yo baby pop");
}
}
void setup() {
s.begin(9600);
}
void loop() {
while (s.available()) {
Serial.write(s.read());
}
}
and
...
11:49:11.758 -> yo, yo, yo baby pop
11:49:11.789 -> yo, yo, yo baby pop
11:49:11.821 -> yo, yo, yo baby pop
11:49:11.821 -> yo, yo, yo baby pop
11:49:11.854 -> yo, yo, yo baby pop
11:49:11.886 -> yo, yo, yo baby pop
...
Been going a few minutes now, nothing weird popped up...
I just removed the delay
between messages completely and I'm still not seeing anything weird in loopback.
Quick loopback test (wire from GPIO 0 <-> GPIO 3) looks fine:
#include <SerialPIO.h> SerialPIO s(2,3); void setup1() { Serial1.setRX(1); Serial1.setTX(0); Serial1.begin(9600); while (1) { delay(10); Serial1.println("yo, yo, yo baby pop"); } } void setup() { s.begin(9600); } void loop() { while (s.available()) { Serial.write(s.read()); } }
and
... 11:49:11.758 -> yo, yo, yo baby pop 11:49:11.789 -> yo, yo, yo baby pop 11:49:11.821 -> yo, yo, yo baby pop 11:49:11.821 -> yo, yo, yo baby pop 11:49:11.854 -> yo, yo, yo baby pop 11:49:11.886 -> yo, yo, yo baby pop ...
Been going a few minutes now, nothing weird popped up...
I tried the exact code from above and connected GPIO0 to GPIO3. At first it does not output anything over the Serial Monitor. I checked the GPIO Pins => they worked fine. Then I though it is a version issue. I updated Raspberry Pi Pico/RP2040 in the board manager from version 4.0.1 to 4.1.1. There i noticed that also Arduino Mbed OS RP2040 Boards by Arduino was installed. Does that make a difference (I am not to familiar with the Arduino IDE, I mostly use the C SDK)? I deinstalled it and now your sketch is working at least.
Unfortuanelty the NEO6M GPS module still is not working. In the next days I have access to an oscilloscope and will check the actual baud rate. Because a small shift in the baudrate would also be plausible for me. I will give an update on that.
Out of curiosity I tested different baudrates with this code:
#include "SoftwareSerial.h"
#define START_BAUDRATE 9590
#define END_BAUDRATE 9700
#define BAUDRATE_STEP 10
SerialPIO mySerial( 3, 4 );
void setup1() {
for (uint32_t i = START_BAUDRATE; i < END_BAUDRATE; i+=BAUDRATE_STEP) {
Serial.print("\n\n\n\nBaudrate: ");
Serial.println(i);
mySerial.begin(i);
delay(4000);
mySerial.end();
}
}
void setup() {
Serial.begin(115200);
}
void loop() {
while (mySerial.available()) {
Serial.write(mySerial.read());
}
}
My module is starting to work an 9610 baud. Unfortunately I don't have another reference module to check if just mine is faulty. But since others had similar issues it might help other people at least finding the problem.
But I am still interested, if the Arduino Mbed OS RP2040 Boards package is an issue.
The Arduino Mbed OS RP2040 Boards
package isn't an issue, it won't be used at all if you select this core from the IDE.
Does the SerialPIO
class do 8-times oversampling and a majority-vote for the bit value or does it capture the bit once at the time it thinks the bit should be on line?
It samples at 50% of the bit time, starting the clock at the start bit edge.
Maybe a way to debug this is to modify the PIO program to also toggle GPIO pin whenever its read the bit from the line, and compare that to the UART signals. Or there is a bug that the initial delay is not correctly done and it samples the signal right at where it's supposed to change -- with some variance in the actual baud, always missing it.
We can just work through things manually, the logic is simple enough.
The SP sets X/OSR to 19 for 8N1 case here (the 1st insn is overwritten on creation to support different bits/parity/etc.).
So the loop will shift (right) in 20 bits, with the 1st = middle of the start bit, 2nd = edge (thrown out), 3rd = middle of bit 0, etc. (Right shift since UART is LSB-first, and 20 times because the jmp x--
is a post-decrement)
FIFO data is:
xSx7.x6x5.x4x3.x2x1.x0xs.GGGG.GGGG.GGGG
where S
= stop, s
= start, G
= garbage(0, not shifted in), x
= transition
Right-shift 33 - 19 = 14 bits
0000.0000.0000.00xS.x7x6.x5x4.x3x2.x1x0
And take every other bit starting at 0
S76543210
We strip off the stop bit before placing it in the SerialPIO FIFO.
So, as far as I can see, all is well logically with the existing code. We went through a few iterations to get it right, but it hasn't been touched since 2022 (other than the PIO2 support for RP2350 and inversion support).
One thing I just thought of would be the actual 1/2 bit times. We use a 1/2 bit timer countdown running at sysclk.
clock_get_hz(clk_sys) / (_baud * 2) - 7
in this case = 133M / (9600 *2) - 7 = 6920.
Looking at the PIO source code this might be a single 133MHZ cycle too short (because there are now 5 insns, not 7, but it's post-decrement so a loop with 6920 runs for 6921 times) but that's trivial.
Actual bitrate = 133000000 / ( 2 * (6921 + 5) ) = 9601.5 baud sampling rate, a 0.016% error and not significant.
No update in a week and nothing seems wrong, so closing. If we get a waveform w/detained enough timing we can possibly see more...
Hello,
I have quite some trouble getting SerialPIO to work. I am using a Raspi Pico W with a NEO6M GPS Module. When I am using the Hardware Serial interface, I get the right data. When using the Software Serial / Serial PIO I get some part of the data and some corrupted data.
My sample code looks like this:
With that I get the following result:
When using the Hardware Serial on the same device I get:
It looks like some problems with the SerialPIO Class.