Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRSF frame parsing timeout repeatedly expires thus dropping all frames #108

Open
1 task done
Tracked by #111
britannio opened this issue Apr 10, 2024 · 5 comments
Open
1 task done
Tracked by #111
Assignees
Labels
🐞 Bug 🐞 OH DEAR!!! You seem to have spotted a bug! Pending 📌 This is waiting for me to check it out
Milestone

Comments

@britannio
Copy link

britannio commented Apr 10, 2024

Is there an existing issue for this bug?

  • I have searched the issues and there is no existing issue for this bug.

What development environment are you using?

PlatformIO

What board are you using?

Raspberry Pi Pico RP2040

What part of CRSF for Arduino is this bug related to?

RC Channels

Current behaviour

When I set up the library to get rc channel data, the callback will run but the channel data never changes.
I only encounter this issue when my Pi Pico is connected to the Adafruit PiCowbell CAN Bus.

Expected behaviour

The rc data should update as normal.

Steps to reproduce

I'm unsure how to reproduce this issue without the mentioned hardware.

Additional information

Removing the following lines fixes the issue.

/* Reset the frame position if the frame time has expired. */
if (currentTime - frameStartTime > timePerFrame)
{
framePosition = 0;
if (currentTime < frameStartTime)
{
frameStartTime = currentTime;
}
}
So the frame expires before it is fully parsed, causing framePosition to be reset to 0 mid-way through parsing a frame and thus the CRC check will fail.

@britannio britannio added Pending 📌 This is waiting for me to check it out 🐞 Bug 🐞 OH DEAR!!! You seem to have spotted a bug! labels Apr 10, 2024
@britannio
Copy link
Author

While I'm here, is it necessary to run the rc channels callback upon parsing a frame with a different frame type such as a telemetry frame? Likewise for link statistics.
https://github.com/ZZ-Cat/CRSFforArduino/blob/Main-Trunk/src/SerialReceiver/SerialReceiver.cpp#L297

@britannio
Copy link
Author

void CRSF::setFrameTime(uint32_t baudRate, uint8_t packetCount)

Increasing the timeout here may fix the issue but is the timeout necessary?

@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Apr 12, 2024

...is the timeout necessary?

Oh gods, you have my intrusive thoughts in a nutshell, here. 😆

The time-out is calculated based on the number of possible size of CRSF packets (which is 64 bytes), the number of packets that are expected to be received, and the baud rate.
From what I understand of the protocol, a timeout of approximately 1500 µS is required to receive all bytes before the buffer is reset.
If an incomplete packet is received, it is assumed that the connection between your receiver and your target (EG development board) is either janky or broken... at least this is the theory behind it.

Removing the time-out altogether may fix your Issue. However, without the timeout, CRSF for Arduino will have no way of knowing the time difference between each byte received. This could create more issues than what your issue is trying to solve, here. It's more likely that my implementation of the time-out could do with a re-factor, as it was derived from Betaflight's implementation, and it's more likely that calling it in the context of the main loop() could be coming back to bite me here, because Betaflight's timeout is executed within interrupt context.


Increasing the timeout here may fix the issue but is the timeout necessary?

If you expand that function, you will see the calculation I am using:

timePerFrame = ((1000000 * packetCount) / (baudRate / (CRSF_FRAME_SIZE_MAX - 1)))

Punch that into your calculator with packetCount at 10 and baudRate of 420000, this yields 1500 µS exactly.
Full disclosure, I have no idea where the Betaflight devs even got 1500 µS from, because it makes zero sense.
You can increase the timePerFrame by passing in a packetCount higher than 10 when you use setFrameTime().

If you set the packetCount to 12, it will set the timePerFrame to 1800 µS. This may work for you.


While I'm here, is it necessary to run the rc channels callback upon parsing a frame with a different frame type such as a telemetry frame? Likewise for link statistics.

What do you mean by this? Could you elaborate on this a little more?

@ZZ-Cat ZZ-Cat self-assigned this Apr 12, 2024
@ZZ-Cat ZZ-Cat added this to the Version 1.1.0 milestone Apr 12, 2024
@britannio
Copy link
Author

What do you mean by this? Could you elaborate on this a little more?

Each invocation of CRSF::receiveFrames() parses a single frame. The frame has a frame type and the ones accepted by the library are:

  • CRSF_FRAMETYPE_RC_CHANNELS_PACKED
  • CRSF_FRAMETYPE_LINK_STATISTICS

If the received frame is RC_CHANNELS_PACKED then the callback set in CRSFforArduino::setRcChannelsCallback should be invoked.
Likewise, if the frame is LINK_STATISTICS then the CRSFforArduino::setLinkStatisticsCallback callback should be invoked.
But right now the callbacks are being invoked irrespective of the frame type or whether the CRC check for the current frame passes.

If this change is made, the failsafe flag may need to be moved as it only relies on link statistics data.

@ZZ-Cat
Copy link
Owner

ZZ-Cat commented Apr 12, 2024

Each invocation of CRSF::receiveFrames() parses a single frame. The frame has a frame type and the ones accepted by the library are:

* `CRSF_FRAMETYPE_RC_CHANNELS_PACKED`

* `CRSF_FRAMETYPE_LINK_STATISTICS`

If the received frame is RC_CHANNELS_PACKED then the callback set in CRSFforArduino::setRcChannelsCallback should be invoked. Likewise, if the frame is LINK_STATISTICS then the CRSFforArduino::setLinkStatisticsCallback callback should be invoked. But right now the callbacks are being invoked irrespective of the frame type or whether the CRC check for the current frame passes.

Interesting. 🤔
Yea, nah. It shouldn't be doing that, and I will look into it.
At this time, my focus is primarily with #103 (which has taken priority). So, it may be some time before I sort this issue out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 Bug 🐞 OH DEAR!!! You seem to have spotted a bug! Pending 📌 This is waiting for me to check it out
Projects
Status: On hold
Development

No branches or pull requests

2 participants