CapnBry / CRServoF

CRSF to PWM Servo converter for STM32F103
GNU General Public License v3.0
211 stars 54 forks source link

Porting serial passthrough to CRSFJoystick - Stuck on timeout #29

Closed countofkrakow closed 9 months ago

countofkrakow commented 1 year ago

I figured since CRSFJoystick uses the crsfSerial library this should be possble. Here's my attempt at getting this to work on an rp2040 based CRSFJoystick:

https://gist.github.com/countofkrakow/1e26d9006461901a3011a02b911ca8a3

I try flashing an rx with the ELRS configurator and it seems to handle the handshake for going into bootloader mode but then I get a timeout after that. I looked into how serialpasssthrough is done by betaflight and copied the logic into a function and tried that but the configurator just hangs indefinitely that way. This can be found commented out in the gist above in checkSerialInPassthrough.

337919232_1176749242839025_3400717363831921380_n

Here is output from the configurator with my adapted arduino code.

`Building in release mode PLATFORM : 'espressif8266' BUILD ENV: 'HAPPYMODEL_EP_2400_RX_VIA_BETAFLIGHTPASSTHROUGH' Retrieving maximum program size .pio\build\HappyModel_EP_2400_RX_via_BetaflightPassthrough\firmware.elf Checking size .pio\build\HappyModel_EP_2400_RX_via_BetaflightPassthrough\firmware.elf Advanced Memory Usage is available via "PlatformIO Home > Project Inspect" RAM: [==== ] 43.2% (used 35388 bytes from 81920 bytes) Flash: [==== ] 37.1% (used 379552 bytes from 1023984 bytes) Configuring upload protocol... AVAILABLE: custom, espota, esptool CURRENT: upload_protocol = custom Uploading .pio\build\HappyModel_EP_2400_RX_via_BetaflightPassthrough\firmware.bin Uploading .pio\build\HappyModel_EP_2400_RX_via_BetaflightPassthrough\firmware.bin ======== PASSTHROUGH INIT ======== Trying to initialize COM6 @ 420000

Attempting to detect FC UART configuration... ** Serial RX config detected: 'serial 5 64 0 0 0 0' Enabling serial passthrough... CMD: 'serialpassthrough 5 420000' ======== PASSTHROUGH DONE ======== ======== RESET TO BOOTLOADER ========

A fatal error occurred: Failed to connect to ESP8266: Timed out waiting for packet header *** [upload] Error 2 ========================= [FAILED] Took 20.10 seconds =========================

Environment Status Duration


HappyModel_EP_2400_RX_via_BetaflightPassthrough FAILED 00:00:20.101 ==================== 1 failed, 0 succeeded in 00:00:20.101 ====================`

I looked around on the CRSFJoystick page and mikeneiderhauser thinks it's an issue with dynamic baud rate.

Any ideas?

CapnBry commented 1 year ago

I've pushed some changes (https://github.com/CapnBry/CRServoF/commit/f604562036ddd22f4fcfee794cf6f96dd525b144):

Seems to work for me now 19 times out of 20 if the baud rate is the same, but for that 1, it definitely gets to the bootloader and is at the right baud rate so I dunno why esptool will sometimes hang. About the same success rate as going through Betaflight though.

If the baud rate is different, it will always say "Cannot detect RX target, blindly flashing!", this is because the passthrough command from configurator throws out any data from the 200ms between starting passthrough mode and starting flashing. The code here could be made smarter to wait until the reboot command comes, forward on the reboot command at the original baud, then sofuckingfast try to switch the baud rate. However, the flash seems to work maybe 9 times out of 10 anyway so I'm not going to bother. This could be fixed on the ELRS side, but that code is so fragile I'd be wary of trying to "fix" it.

In either case maybe CRSFJoystick can update their code to match and see if that helps. It definitely seems more reliable than before. They should note they now need to call crsf.begin() in their startup as well, since that is now required where it wasn't before.

countofkrakow commented 1 year ago

Hi CapnBry!

I just tried adding your changes to CRSFJoystick here, which didn't seem to work. I'd be happy to send over a physical CRSFJoystick for you to play around with if you're interested.

CapnBry commented 1 year ago

Well that stinks. Have you tried opening a serial terminal at 420000 baud and sending serialpassthrough 5 420000? It should reboot the RX to bootloader and display the target name? That would tell you if it is getting there cleanly at least to maybe figure out at which step things are going off the rails.

I don't see anything in the code that stands out apart from this =0 line needs to be moved up to after 244 so it always gets cleared, but that should affect anything the first passthrough attempt. The crsf.begin() is missing from setup() as well, although you might be using your own CrsfSerial lib? There were a lot of small changes to the lib itself that are required.

countofkrakow commented 1 year ago

I just tried your change, but it seems like there's nothing coming back. This mirrors what I see in the ELRS configurator where there is no serial output from the dongle upon attempting to flash.

I am using your updated CRSFSerial library and here is my updated code.

Email me at chrisnakovski@gmail.com if you're interested in getting a CRSFJoystick free to tinker with.

Thanks

CapnBry commented 1 year ago

I'll poke around some more, I see the latest CRSFJoystick hardware has 2x USB ports? Can I just use an RP2040 dev board (the PiPico) to emulate being the same hardware? I appreciate the offer for test hardware, but hopefully I can save you some money by just using what I've got on hand.

countofkrakow commented 1 year ago

Yep, just a regular rp2040 should work. The dual usb ports connect to the same outputs so there's no need to worry about that.

Thanks for taking a look!

CapnBry commented 1 year ago

Thanks for taking a look!

Piece of cake, dude, the solution was not obvious probably due to my dumb naming.

The issue was that there was no code to send the passthrough data back to the host. This is done in CRServoF using the onShiftyByte(b) callback. A "shifty byte" is any byte which is not CRSF data, which includes all the incoming data in passthrough mode. I've renamed this to be "OobData" or Out of Band Data, maybe making it a little clearer. To fix passthrough flashing just add this code

void crsfOobData(uint8_t b)
{
    // Passthrough data, log messages, and failed packets from the CRSF connection
    Serial.write(b);
}
...
    // Before crsf.begin();
    crsf.onOobData = &crsfOobData;
countofkrakow commented 1 year ago

Hey Bryan,

I just tried adding that and it didn't seem to change anything. I even included your updated CRSFSerial code. Here's the updated gist.

This is what the configurator gives me: image

CapnBry commented 1 year ago

I just tried adding that and it didn't seem to change anything

Welp I dunno what to tell you then. Did you remember to flash the RP2040 with the new code? Have both RX and TX lines hooked up? I took your code, fixed the compile error, put it on my RP240, flashed the first time with the Configurator. Even tried it 4x, 2 back to back, 2 pulling power between them with the last one done through platformio. It always works for me.

You can try connecting a TX module (establish a connection to the RX I mean, like a normal connection), then open a serial terminal and type serialpassthrough 5 420000 (enter) and you should see that echo back, then it will dump CRSF packets to the serial terminal for the next 5 seconds, and stop. That will tell you if you've got it hooked up with the right code running maybe?

I'm going to close this as completed though, I can't reproduce your failure at all. It just always works using the code you've supplied. Test RX was a EP2 style RX (BetaFPV Lite Flat V1.0).

countofkrakow commented 1 year ago

I tried the serial monitor trick and it doesn't give me anything back, Can you show me what yours does when you put in the Serialpassthrough command?

image

Edit: it seems that after I give the serialpassthrough 5 42000 command, all I get back is a null byte. I'm working in Arduino IDE if that helps.

CapnBry commented 1 year ago

It starts passing through the CRSF data from the receiver (because the transmitter is connected to it) image

countofkrakow commented 1 year ago

Yeah I made sure that the radio was connected and showed bars. Same deal. Did you try uploading it with the Arduino IDE?

CapnBry commented 1 year ago

Yeah I used Arduino IDE 1.8.13 for all my testing. Maybe try it with that version? I can't imagine how that would break anything.

If the Joystick part was working, then that would mean the UART stuff was working, and setPassthrough would not close/open the port because it is the same baud rate, so the data should just start coming out the passthrough connection.

countofkrakow commented 1 year ago

I just did an experiment and it appears that no data is being read once it goes into passthrough. This is after giving it the serialpassthrough 5 42000 command. Capture

CapnBry commented 1 year ago

Serial is the UART you're typing into, and CrsfSerial doesn't do anything with that UART, it is fully under your control from the main program, It doesn't even know about it. I think maybe trying to debug the wrong Serial? This is me pressing enter in the serial monitor and CRSF data mixed in there image

countofkrakow commented 1 year ago

It worked!

I realized I was working on my seeed xiao board and needed to change the target def all this time. Thanks for the awesome help!

Looks like CRSFJoystick is getting serial passthrough!

image

Thanks Capn Bry!

CapnBry commented 1 year ago

Nice! Knew it had to be something simple like that. I even just installed Arduino IDE 2.1.0 and it worked there for me as well image

(once I realized after 5 failed Pi upload attempts that I had the wrong port selected 😞)

countofkrakow commented 1 year ago

So I went over and tried again with the crsfjoystick rp2040 dongle itself instead of the seeed xiao. I used the first board definition and it seems to give serial noise in the monitor when I give it the passthrough command. However I get stuck at flashing when the configurator picks up some odd byte instead of the bootloader header and gives up. Any idea?

I'm happy to send you one of these things if you can't repro on available hardware.

Capture

countofkrakow commented 1 year ago

Update: it was an electrical connection that was the issue. Worked after re-soldering the connection. Thanks for the total KO today!