Usb games loader

Hi,

This is what we do:

Since I can’t access the forums at this time I can’t see the history of this thread,
so I have no idea what language you’re using. However our core library runs on the RaspberryPI
and when I have some time I’ll give it a try to see if there’s anything specific to the Pi (or ARM in general) that prevents it from working.
First of all you should check you enabled DTR.

Ok now I have access to the forums, seems my code didn’t go through so here it is:

private  async Task RebootToBootloaderAsync()
{
    progress.Report("Searching for the Arduboy...");         
    var portName = await GetArduinoPortNameAsync(ArduinoMode.Normal);
    progress.Report($"Arduboy found on port {portName}");

    progress.Report("Reboot the Arduboy into bootloader mode...");
    using (var port = new SerialPort(portName, 1200) { DtrEnable = true })
    {
        port.Open();
        await Task.Delay(500);
        port.Close();
        await Task.Delay(1000);
    }
}

After the reboot has been triggered, the time for the device to come online will differ
from system to system, so we then apply a retry policy on the function that searches for the device:

var searchPolicy = Policy.Handle<Exception>()
                         .WaitAndRetryAsync(new[]
                         {
                             TimeSpan.FromMilliseconds(150),
                             TimeSpan.FromMilliseconds(200),
                             TimeSpan.FromMilliseconds(500),
                             TimeSpan.FromMilliseconds(1000)
                          });

We try to detect the device, then wait 150ms, then 200ms, then 500ms, then 1000ms and
if it’s not found by then we assume the reboot failed.

I’m sure you can cook up something similar in go-lang.

It seems that the stty application has DTR enabled by default, so you should be good there.
But since you’re using go-lang, I suggest you use the following library: https://github.com/tarm/serial

1 Like

So I’ve hit a problem with the USB port on the Raspberry Pi Zero. It doesn’t appear to have enough power on the serial bus to successfully run the following two commands:

stty -F /dev/ttyACM0 1200
avrdude -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D -Uflash:w:evade.hex:i

So I’d have to use a powered USB hub in order to send games to the Arduboy. Which would add to the complexity that I’m trying to avoid. Any thoughts on this?

I know that the technique of what I’m doing should work, as it does from an Apple Mac terminal window using the very similar commands:

stty -f /dev/tty.usbmodemFD121 1200
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avrdude -C/Applications/Arduino.app/Contents/Java/hardware/tools/avr/etc/avrdude.conf -v -patmega32u4 -cavr109 -P/dev/cu.usbmodemFD121 -b57600 -D -Uflash:w:Downloads/castleboy.hex:i

But carrying a Mac around is also not quite what I was going for… :wink:

I noticed that on some computers, when reseting the Arduboy via AVRDude, the port number changes. If your command isn’t working, it is possible your OS is swapping the port to a different one? This is rare, but it happens on my computer. Oddly enough, the official Arduino IDE doesn’t seem to be bothered by this.

How do you know you have a power problem? Have you tried a powered hub and seen it work, when a direct connection doesn’t?

According to what I’ve read, the power available on a Pi Zero’s USB port is unrestricted. If whatever you’re using to power the Pi has enough extra power, it should be available on the USB port.

The Arduboy should need less than 500mA when charging the battery and much less than that if the battery is charged (red charge LED is not lit). @bateske may be able to tell us what charge current the charge controller chip on the Arduboy is set for.

Success! I’ve finally managed to successfully upload a .hex file from a Raspberry Pi Zero to the Arduboy. It wasn’t anything to do with USB power, it was the simple fact that I hadn’t enabled ‘Serial’ in the Raspberry Pi Configuration panel! Oops :wink: Thanks to everyone for their input on this.

Anyway, with that milestone completed, I can now start on the ‘file server’ program for the Pi and the ‘client’ menu program for the Arduboy. Here’s how I envisage it working:

  1. Pi boots up and automatically starts the file server program. The Pi is in a waiting state.
  2. Pi recognises that an Arduboy has been connected, and uploads the menu program to the Arduboy
  3. On the Arduboy, the menu program contacts the Pi via serial and asks for the list of .hex files available and the Pi sends the list. The Arduboy menu program lists them on screen for the user to scroll through and select.
  4. Once selected, the menu program sends the name of the selected file via serial to the Pi, and the Pi uploads that hex file to the Arduboy.
  5. The user can then disconnect the Pi and enjoy their game. The Pi then reverts to a waiting state (step 1 onwards)

Although initially it will only support .hex files, a later version will intelligently handle .arduboy files for ease of use.

I’ll keep you all posted with my progress.

3 Likes

By uploading a menu sketch between each user sketch, you’ll be halving the life of the Arduboy’s program flash memory.

The datasheet specifies 10000 write/erase cycles (minimum).

I think I’ll risk it. I’m unlikely to swap games 5000 times. If I played Arduboy non-stop 24 hours a day, gave each game 20 minutes, then swapped, it would last 41 days. That’s not bad :wink:

I may also work on an alternative web interface so you could use a smartphone to select a game. But that adds complexity as the Raspberry Pi Zero would have to be on the same wifi network as the phone. You might be somewhere with no wifi (e.g. in the park). And I’m trying to keep it simple.

Then configure the Pi as an access point so it becomes its own WiFi network.

It was going so well…

So I finally got the Arduboy Game Changer working, and was about to film an introductory video to put on this forum, when… OOPS!

I seem to have bricked my Arduboy. Here is the sequence of events:

  1. In the Arduino IDE on my Mac, I went to ‘Export Compiled Binary’ so I could get a .hex file of my menu program (called ‘agc’)
  2. This seemed to create two binaries - called ‘agc.ino.leonardo.hex’ and ‘agc.ino.with_bootloader.leonardo.hex’
  3. I copied the ‘with_bootloader’ version onto my Pi and used avrdude to put it on the Arduboy. This appears to have been a big mistake, as the screen went slightly corrupted as my program started.
  4. When restarting the Arduboy, my menu program starts but I am unable to upload anything to Arduboy, including other games, by any means.
  5. I’ve tried using avrdude, the Arduino IDE, flashlight mode, reset button.
  6. What seems to happen is that the first step of uploading works (i.e. the screen goes blank) but then the Arduboy doesn’t appear as a valid USB device to my Mac or PC (or Pi)

Could I have screwed up the bootloader? Is it not protected? I don’t have an AVR ISP programmer so I’m unable to upload via the pins rather than USB.

Is your Arduboy a Kickstarter version or a retail verson?

If it has Kickstarter Edition and 1 of 10,000 printed on the back then it’s possible that the bootloader is not protected, due to a factory oversight. In this case it’s possible that you may have corrupted the bootloader, which would require an external programmer to recover it.

Otherwise, if flashlight mode doesn’t work, you should still be able to recover using the reset button, but it can be tricky and require multiple attempts to get the timing just right.

this is precisely the problem i have with your game loader

Pretty sure you might have indeed reflashed your bootloader… though the question is with what… does the Arduboy not have the standard Leonardo bootloader in the first place? Or perhaps the software permits reflashing itself but that doesn’t work in reality so now its’ borked.

I’d think if you were flashing the SAME bootloader it would work, but if you were flashing a NEW/different one and the addresses didn’t line up just right I can see things going off the rails, since you’d only get part of it reflashed and then when it get to reflashing the code it was running it would all fall apart.

It’s a retail version. Will keep trying the reset button method…

Yes, it’s the standard Leonardo “caterina” bootloader (Arduino USB IDs and all). Even if it wasn’t, the hardware is identical to a Leonardo, so the standard Leonardo bootloader would work.

I think the issue is that the bootloader would be trying to burn itself. To burn flash memory you have to erase it first. Somewhere along the line the bootloader would end up erasing the instructions it was actually executing, in preparation for rewriting them. The code would go “off in space” when it executed this erased area, before it had a chance to rewrite it with the proper code. You would end up with an incompletely burned, thus damaged, bootloader.

However, if @marvbloke has a retail Arduboy, in this case it’s all moot, assuming @bateske’s assurance that the retail Arduboy bootloaders have been protected is correct.

No, that’s not how it works AFAIK. Pretty sure bootloader is all non-RWW (read while write)… so a write to flash should PAUSE the cpu from executing instructions until it completed. So as long as you wrote the SAME instructions back it could pick up where it left off and keep flashing over itself. But if you had recompiled a boot loader and things shifted by even 1 byte that could be some really bad mojo.

Or else part of it is RWW and mlxxxp is entirely correct. :slight_smile:

I’m right. PART of the application could be in NRWW land but in our case where the bootloader in max size the entire boot-loader should be NRWW. So if it was done properly (with fixed addresses for the flashing code) you should be able to reflash the boot-loader with the bootloader. :slight_smile:

I don’t think Caterina guarantees fixed flashing code addresses though across different compiles.

I don’t think the bootloader is re-compiled each time to create a “with_bootloader” .hex file. It’s been pre-compiled and its .hex output is just appended to the compiled sketch’s .hex output.

Still, if this pre-compiled bootloader didn’t exactly match ours, you could still have the problem.

Right, I think it’s a static file in the distribution - but if it wasn’t a match, as you said.