pbio/drv/bluetooth_stm32_cc2640: Only restart observe when needed. #307
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This partially fixes pybricks/support#2206. I don't think there is a true cure but it turns out we can reduce the symptoms significantly.
We used to believe that alternating between observing and broadcasting was the right workaround, but on closer look it appears that this might not be the case. The freezes are not random. When the Bluetooth chip locks up, it is always just after an observe restart. It will then get stuck at the very next Bluetooth command, whatever that is. That was usually broadcasting, so this is why we assumed they were conflicting.
So every time we restart observing, there is a small chance of locking up the Bluetooth chip. The restart was added in the first place as a workaround for the scan queue getting full so new scan events were not coming in (pybricks/support#1096). This usually doesn't happen for a long time, so we can avoid restarting observing until that happens.
This reduces the number of restart from once every 10 seconds to a few times per hour, significantly reducing the odds of a lock up. In practice, some applications that used to get stuck after 10 minutes can now run for hours.
Since there isn't a good way to know if the queue is full, we can request a restart if we are not receiving data when the user is expecting some data. In the worst case, this will still restart it every 10 seconds as it used to do. If all of the subscribed channels get incoming data, restarting is delayed, thus reducing the likelihood of a freeze.
This could potentially be made to work better if we told
bluetooth_stm32_cc2640which channels to expect, but this resides at the module level. If it was at the driver level, we could do it at the right time even if the user wasn't callingobserve. This requires much bigger changes though, so probably isn't worth it.