Closed danybd closed 3 years ago
Don't have the hardware to confirm and can't find the message in configurator source. I guess it's an issue with Android not having a driver implementation for Silabs CP210x.
I´ll try to do some research to find out, what is exactly crashing. There should be some kind of logging register in android where events get logged.
This two FC are not maintained anymore, are very old (specially the Naze32). So we can't be sure that the current configurator will work with them. I suppose you have tried both in a computer, so if they work there, it must work in Android if you can find the problem with the driver.
Maybe we need to change this filtering:
To accept other USB definitions?
At least I suppose we need to support the same than we do in other SO:
@McGiverGim yes, I tried on the computer and there is working perfect. But in android prints the message "Failed to open serial port". I discard driver issue as other serial terminal tool are working and establishing connection with the FC. I installed yesterday the last nightly build and right now I´ve got installed 10.8.0 In the tab where ports are listed shows vendorId and productId in decimal as "4292/60000 - 4292/60000" I could try a build with the suggested changes by @McGiverGim
My android devices is detecting the FC as: vendorId: 10C4 productId: EA60
Progress update: I checked out the repository and prepared my system so that I was able to build an .apk including the mod suggested by @McGiverGim. Unfortunately it did not work and I am still not able to connect with the FC. If you have any idea I can keep trying possible fixes.
Well I did some "progress" at debugging. I looks like that in serial_backend.js the callback function onOpen(openInfo) { if (openInfo) { ...
is getting false as input parameter (which actually is the ConnectionInfo). This callback is called in serial.connect(portName, {bitrate: selected_baud}, onOpen);
and as I read in the documentation, the callback gets only called if the port could be opened successfully.
serial.connect(path, options, callback) path (string): If the path associated with your device's port is unknown, you can use the serial.getDevices method options (object): Parameter object with several configuration values. See details at serial.ConnectionOptions callback: Invoked when the port has been successfully opened. The callback will be called with one parameter, connectionInfo, that has several important values. See details at serial.ConnectionInfo.
I do not really understand why ConnectionInfo is false if the port was apparently open successfully. Hopefully somebody knows, what is going on. For me is the first time I have a look into .js
It's part of the chrome API we are using. But still not sure 2104 is included in Android. https://www.silabs.com/documents/public/application-notes/AN809.pdf
Maybe @WalcoFPV can help here, is the one with more knowledge about Android...
I think, there are 2 possible issues.
The first one, which propably causes crashes of the app, is that the preview build of the Android app uses a very old version of an android library called usb-serial-for-android
. This issue is fixed in master so using a nightly build can solve this issue.
The second one is that, on Android, the configurator, will only allow connection to devices listed in /cordova/usb_device_filter.xml
. So adding the vendorId and productId of the CP2104 USB to UART Bridge Controller could solve the issue.
The serial chrome API doesn't exist on Android (more precisely for Cordova). So I had to "simulate it" with existing Cordova plugins as cordovarduino
(which is a bridge between the Configurator and the native Android library usb-serial-for-android
). So it is possible that some information that the serial Chrome API is supposed to return, is not correctly returned on Android. You can take a look at /src/js/cordova_chromeapi.js
@WalcoFPV the crash problem was happening with 10.7.0. This issue does not happen with nightly 10.8.0
Regarding /cordova/usb_device_filter.xml
I did yesterday the change and build an .apk but it did not help. In log area pop-up the message "Failed to open serial port".
I will have a look into the suggested modules. Any advice for online debugging (with breakpoints on target)?
I think, I found something. It seems the vendorId and the productId of the CP2104 USB to UART Bridge Controller contain letters. But during the connection, the configurator converts them to int. https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L158-L159
@danybd I don't know how to debug online. Debugging the app with usb is annoying : having to plug in the flight controller and then plug in the usb to debug the app ... but I don't know other solutions.
@WalcoFPV I readout the vendorId and productId in my android device using a tool from Play Store: vendorId: 10C4 productId: EA60 I assumed these are hex numbers. The same conversion is taking place FC like CrayzBee (STM32F3) and there is no issue at all
I´m confused. Is the module serial.js
being used in the android app? Is replaced by cordova_chromeapi.js
? Both of them have serial routines implemented.
What I observed is that the callback onOpen(openInfo)
gets false as input parameter (openInfo=false)
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial_backend.js#L220-L224
Looking in serial.js
found the function connect
and connectSerial
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L18-L34
The function connectSerial
is calling the callback onOpen
with false
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L137-L143
@danybd yes serial.js
is used. All the configurator uses the serial chrome API. But, on Android, we use Cordova which doesn't provide this api. So, cordova_chromeapi.js
creates the serial Chrome API methods with a Cordova plugin cordovarduino
which uses the usb-serial-for-android
native Android library.
So, I am almost sure the issue come from cordova_chromeapi.js
, the cordovarduino
Cordova plugin or the usb-serial-for-android
native Android library doesn't work for this serial controller.
There is definitely a ChromeRuntimeError at this point: https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L34
I am really having hard to follow the .js execution flow. @WalcoFPV how do you come from
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L33
to
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L151
I don't see the connection. I´m Python and C/C++ guy. First time for me looking .js. I don´t see any "imports" or something similar to understand where are functions called from.
I´ve been investigating cordovarduino
and usb-serial-for-android
and both claim to support cp210x devices.
@danybd In cordova_chromeapi.js
, an object chromeapiSerial
is defined. This object contains the same methods than chrome.serial
but for Cordova.
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L47-L250
Because chrome.serial
is not natively available on Cordova, during the initialization of Cordova, chrome.serial = chromeapiSerial
is set.
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L398-L406
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_startup.js#L51-L67
So, when the configurator runs on Android, chrome.serial.connect
in serial.js
calls chromeapiSerial.connect
in cordova_chromeapi.js
@danybd
There is definitely a ChromeRuntimeError at this point: https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L34
When running on Android, a ChromeRuntimeError can be also set in cordova_chromeapi.js
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L3-L35
But, I think, we don't take the right approach. With the flight controller wired to your phone, what is the name of the port of the fc shown by the configurator ?
@WalcoFPV
But, I think, we don't take the right approach. With the flight controller wired to your phone, what is the name of the port of the fc shown by the configurator ?
It is showing 4292/60000 - 4292/60000 which is the decimal vendorId and productId
Thank you for the explanations! What I still do not understand is how .js "knows" that this
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L398-L406
and this:
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/serial.js#L33
are related. I could more or less follow the flow execution because you said me "look there". I would never find out looking in the code that cordova_chromeapi.js
overloads chrome.serial
and serial.js
"references" cordova_chromeapi.js
. Is this relatiship defined in some kind of build file outside src
?
I look how modules are imported in .js and keywords like export
and require
are needed.
@danybd look again: chromeapiSerial
is assigned to chrome.serial
and as such you should read chrome.serial.connect()
as chromeapiSerial.connect();
but connect
is defined in cordova_chromeapi.js
, so I guess it doesn't use the one in serial.js
.
Also getDevices
is redefined for Android in the same file to build the list of devices attached to USB.
On https://github.com/xseignard/cordovarduino#your-device-is-not-yet-known there is shown how to attach the right driver to the device vid/pid
(usbDevices
in port_handler.js
but it could just be using devices
in cordova_chromeapi.js
), so I'm not sure where to assign .
@haslinghuis
connect
is defined incordova_chromeapi.js
, so I guess it doesn't use the one inserial.js
.
I found the issue #2433 which explains why I am having hard time understanding the code 😄
Yes, it do. Because in serial.js
the code in connect
is actually a callback function, which is called by chrome.serial.connect()
from cordova_chromeapi.js
Is there any possibility to see the console.log()
messages? Currently I am debugging inserting GUI.log()
in the code and building the .apk, but this is extremely inefficient and time consuming (build time +/- 3min). How do you do it? Do you use an emulator?
The driver library usb-serial-for-android says:
Compatible Devices This library supports USB to serial converter chips: FTDI FT232R, FT232H, FT2232H, FT4232H, FT230X, FT231X, FT234XD Prolific PL2303 Silabs CP2102 and all other CP210x Qinheng CH340, CH341A
So I guess the CP2104 should be supported.
Debugging update: I found out another point where the execution is going wrong:
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L163-L175
At this point the chromeCallbackWithError(self.logHeader+error, callback);
is called. I modified the code and insert a debug instruction and built the .apk.
GUI.log("chromeCallbackWithError: " + self.logHeader+error); chromeCallbackWithError(self.logHeader+error, callback);
After doing that I found out what is the value of self.logHeader+error
=> "SERIAL (adapted from Cordova): No control endpoint"
It looks like the problem is in cordova_serial...
I´ve found the bug!!! 🥳
The problem was a wrong driver selection. The function cordova_serial.requestPermission
takes an optional parameter driver
. If no driver parameter is provided then it uses the default one CdcAcmSerialDriver
which is not working for the FC with CP2104 USB-UART chip.
The bugfix is pretty straightforward. Instead:
https://github.com/betaflight/betaflight-configurator/blob/9cedeb23ca7f8c26874eb9556d0ad7d3819c521f/src/js/cordova_chromeapi.js#L161
we have to differentiate the driver depending on the board cordova_serial.requestPermission({vid: vid, pid: pid, driver: "Cp21xxSerialDriver | CdcAcmSerialDriver"}
. I´ll do today a pull request with the bugfix.
Thank you all for the advices.
Is better not to close the issue, and link the PR to it. It will be closed when the PR is merged.
Is better not to close the issue, and link the PR to it. It will be closed when the PR is merged.
@McGiverGim Ok, I reopen the issue. It is my first PR so, I don't really know the workflow. I already did the PR.
@McGiverGim should this issue be labeled as bug? I am not able to do that, right?
Yes, I will add it.
So what do we need to do so we can get past it and connect to BF? I haven't flown in 2 months because of the stupid Cordova bullshit
I´ve installed betaflight configurator in a android device and tried to connect to a FC with an USB UART built-in. I did the same test for 3 different flight controller. Two of them (SPracingF3 and Naze32) with Sil2104 ICs and one with I believe native usb support (CrazyBeeF3). The last one is working properly, the first ones dont. When I try to connect to the FCs I got a popup message "do you want to allow Betaflight Configurator access to CP2104 USB to UART Bridge Controller?" and two buttons below "cancel" / "accept". After clickling on accept the tool crashes and get closed by android task manager. Is these "legacy" hardware not supported or is it just a bug? I´ve got android 10 and betaflight configurator 10.7.0