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

Add support for Raspberry Pi Pico #668

Closed
wants to merge 6 commits into from
Closed

Conversation

neilenns
Copy link
Contributor

Companion draft pull request to the Firmware side of things. As with the firmware this leverages the amazing work by @elral where he figured out how to use the rpi2040load.exe command to upload firmware to the Raspberry Pi Pico.

Additions to Ralf's work:

  • Added a new section to the board definition file called PicoToolSettings for the pico-specific flash options.
  • Added a general purpose DelayBeforeFirmwareUpload setting to control how long to wait for a board to reconnect before trying to flash the firmware.
  • Use the presence of that new settings block to determine whether firmware should be uploaded using that method.
  • Added a new method to encapsulate the Pico flash process

This does work, I successfully used it to flash a Pico from 0.0.1 to 2.0.1. It's still draft though.

Questions I have:

  1. Why do people talk about using picotool.exe for this when it's actually rpi2040load.exe that does the work?
  2. Is picotool.exe even needed?
  3. I think this should be called Rpi2040LoadSettings, RunRpi2040Load() etc. instead since that's the actual command that gets run?
  4. Why did I have to leave the extension off of the firmware when passing it to rpi2040load.exe? In Ralf's code he includes .elf on the end of the firmware, but when I did that (even on the command line manually) it got an extra .uf2 added to the end which caused a failure.
  5. Why did Ralf use .elf when as far as I can tell the tool wants the .uf2 version of the firmware? Is that because I never bothered to download the elf2uf2.exe app?

(Side note: this rpi2040load.exe is the most obscure and opaque piece of software I've seen in a long time!!!)

@neilenns neilenns requested review from DocMoebiuz and elral January 21, 2022 02:30
@neilenns
Copy link
Contributor Author

Answering some of my questions...

I found the source for rpi2040load.exe. It's just a wrapper around elf2uf2 and picotool. I'm going to take a pass at updating this PR so it only uses picotool and gets rid of the other two apps.

@neilenns
Copy link
Contributor Author

I've spent a bunch more time on this and unfortunately picotool doesn't seem to handle talking to specific boards by address on my Windows machine. I can't tell if it's just me or some wider issue with the tool, but without direct bus & address support it'll be impossible to pick which attached Pico to flash.

I've opened raspberrypi/picotool#48 on their side, hopefully there will either be a "you're doing X wrong" or "yeah we can fix that" response soon.

@elral
Copy link
Contributor

elral commented Jan 24, 2022

Questions I have:

  1. Why do people talk about using picotool.exe for this when it's actually rpi2040load.exe that does the work?
  2. Is picotool.exe even needed?
  3. I think this should be called Rpi2040LoadSettings, RunRpi2040Load() etc. instead since that's the actual command that gets run?
  4. Why did I have to leave the extension off of the firmware when passing it to rpi2040load.exe? In Ralf's code he includes .elf on the end of the firmware, but when I did that (even on the command line manually) it got an extra .uf2 added to the end which caused a failure.
  5. Why did Ralf use .elf when as far as I can tell the tool wants the .uf2 version of the firmware? Is that because I never bothered to download the elf2uf2.exe app?

Unfortunetely I can not answer these questions. I made it very simple, I flashed the Pico from PlatformIO with verbose output and copied what they are doing. I was wondering too why they used the .elf file and it is converted to an .uf2 file. But I didn't make such a deep dive as Neil did (and does).

@neilenns
Copy link
Contributor Author

I've made a ton of progress on this in the last few days. The .elf extension is a debug-enabled version of the code. .uf2 is what we'll want to flash to the device in production.

The rpi2040load.exe app is just a thin wrapper around elf2uf2 (which converts from the debug-enabled firmware to release firmware) and then runs picotool that makes all sorts of (bad?) assumptions. We don't need it.

I was successfully able to build picotool locally this morning and talk to a Pico via device address. The remaining problem is how to discover that device address. According to device manager my pico's address is 5 but according to picotool it is 15.

@neilenns
Copy link
Contributor Author

After two days of digging into this I've given up on finding a way to flash from within MobiFlight. For any connected board (regardless of type, Arduino or Raspberry Pi, doesn't matter) MobiFlight needs to know two things:

  1. What COM port to use when doing serial communication with the device
  2. What address to use when flashing the device

On Arduinos the COM port is the address for flashing. This is obtained by looking in the Windows Registry.

On the Pico the COM port is used for serial communication but the address is a combination of bus number and address that come from libusb. It's highly specific to libusb and its underlying libraries and after two days of investigation the only way I found to get them is to enumerate connected USB devices using libusb.

MobiFlight can successfully get the COM port for Picos during getSupportedPorts(), no problem. The challenge is, somewhere, somehow, getting the bus number and address that matches the device connected at that COM port. Everything I've tried gets me either the COM port or the bus number, not both.

You might think "ok, split the two. Get the COM port and then later on look up the bus number and address". Unfortunately there's no way I can find to make a connection between the two.

Imagine you have two Picos connected, one on COM1 and one on COM2, and you want to flash the second one. How does MobiFlight know after enumerating the bus number and address for all connected Picos that the one at bus 5 address 15 is the device connected to COM2? There's no unique identifier I can find for connected USB devices that could be used to make this link.

So... I'm giving up for now :(

@neilenns
Copy link
Contributor Author

The closest thing I can find that would make this link is LocationInformation in the registry. For my connected Mega 2560 it reports Port_#0003.Hub_#0009.

On the libusb side of things PortNumber is available and matches (it shows 3). I can't find anywhere to get the hub though :(

Soooooooooo close.

// This method would, in theory, return the bus number and address for the supplied module.
// Unforutnately I can't find any way to do that.

public static Tuple<int, int> GetBusNumberAndAddress(MobiFlightModule module)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is where to start reading.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool work, but honestly and no offense: I don't like the strong dependency to the flash tool in the configuration.
As I described on Discord already, we should find a more flexible way to allow for adding additional boards without modifying the MobiFlight code every time. This would allow for something like a community board repository where you can simply drop the boards definition together with a updater file into the MobiFlight installation. The benefit of this would be that the community can come up with more exotic and (experimental) boards that implement the MobiFlight API without having to "officially" support them with the core project.

When we started to discuss custom boards, then you proposed a flag to say: i am not updateable. don't worry about me, I can update my firmware myself. And I find that idea still cool! Why do we have to put in these specific implementations. tomorrow there might be another board.

it is super cool that you were able to add it into mobiflight and maybe we could leave it now since we have done it, but i am sure there will be another board.

With the avr dude it is quite simple, we can put all config required for starting the script into the boards definition file. I understand the lookup is different for the pico, but MobiFlight at the moment needs a serial port. Can we not pass the serial port to a little wrapper exe that then does the lookup and starts the pico flasher correctly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't matter where the code lives because I can't find any way to take the serial port and do a lookup of the necessary values. Whether the code lives inside Mobiflight or as a separate tool is irrelevant if there's no way to do it in the first place ;)

After days of digging into this I'm convinced it isn't possible. The best we could do is provide a pico firmware file and ship a board.json for it with MobiFlight. People will have to manually flash.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the manual flashing is totally acceptable.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and for clarification: this now works or still doesn't? because in the initial comments it sounds as if had figured it out how to do it through MF

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this now works or still doesn't?

Calling PicoTool works, but there is no way to get the address and bus to pass to PicoTool so it knows what device to flash.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it doesn't work with MF

@neilenns
Copy link
Contributor Author

neilenns commented Feb 4, 2022

Will open a new PR sometime with just the board definition file.

@neilenns neilenns closed this Feb 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants