Tag

Showing blog posts sorted under the tag: maple

Dreamwave - Turning a Dreamcast Controller into a Bluetooth Wireless Gamepad

As the Pico2Maple project (a Dreamcast USB/Bluetooth to controller adapter) reaches a recognizable level of maturity. I started thinking about what else could be done with the same core Maple bus implementation and eventually decided on modifying a standard Dreamcast controller to work over Bluetooth. Using an Xbox controller on the Dreamcast is great, but sometimes you just want to use the real deal.

I use the Pico 2 W to emulate the Dreamcast's Maple bus, pretending to be the console itself, and send Maple packets to the controller. The controller happily reports back its current state when asked, and that can then be sent over Bluetooth. Taking it a step further, the Pico 2 W can also communicate with any peripherals connected to the controller. I use this to send image data to any connected VMU (Visual Memory Unit) that is received on a separate Bluetooth channel.

The end result is a wireless Dreamcast controller I can use on both a PC and on the Dreamcast itself (with some additional hardware, and have a working VMU display!

Dreamwave controller and Dreamcast.

Polling the Controller

The Dreamcast's Maple bus is the protocol that the console uses to talk to peripherals through the controller ports. For the most part, the console sends commands to a peripheral and the peripheral then responds appropriately. Request and response commands all have the same core packet structure, just with different data payloads relevant to a given command. And so, while Pico2Maple takes on the role of a peripheral responding to the console, it is not much of a change to turn this around and take on the role of the console requesting data from the controller.

This is exactly what is going on with this project. The Raspberry Pi 2 W sends commands to the controller as if it were a Dreamcast console. The controller then responds as it normally does and all is well.

Only 2 commands are needed to get the controller to start responding: GET_INFORMATION and GET_CONDITION. The GET_INFORMATION command requests some data about the connected peripheral. This includes stuff like its name, available functions, and power usage among other things. Well-behaved peripherals won't respond to any other commands until after responding to this information request, so it is always the first step.

Once the peripheral's information has been requested, we can start sending GET_CONDITION commands to the controller. This requests the current state of the controller, like what buttons are pressed and what the values of the analog axes are. This is recorded and used by the Bluetooth stack to send the controller state over Bluetooth.

Bluetooth

Dreamwave uses BTstack and its HID protocol implementation to send input state over Bluetooth and with the help of some BTStack examples, it wasn't too much hassle to initially get the device appearing as a Bluetooth controller on my PC.

Getting my desired reconnect and pairing behaviour did take some trial-and-error but was a fun time learning about Bluetooth. At power-on, Dreamwave will try to reconnect to it's last known host. This barely takes more than a couple seconds and feels great especially with Pico2Maple. It will fall back into pairing mode if it can't reconnect to the previous host which does take some a bit of time, so the pairing experience is not perfect. But it means I didn't have to worry about wiring up another button to enter Bluetooth pairing. Another option would have been a controller button combo to trigger pairing. That might be a future improvement.

I did not write a driver for the controller but the Linux HID generic driver seems to pick everything up just fine. Steam let me remap the buttons to match an Xbox layout and I was playing Sonic Adventure DX in no-time. So, as long as Steam is running, everything just sort of works.

On a Dreamcast Console

I also wanted to use the controller on a real Dreamcast. To do this I added support for Dreamwave to Pico2Maple so it could connect to and treat this setup like any other controller, and that seemed to work great as well.

One of the really cool features I added to Dreamwave is the ability for a Bluetooth host to open up a second channel, separate from the HID stream, to exchange data back and forth. Currently, this is being used for sending VMU LCD display data from Pico2Maple to Dreamwave. This means that I still get to enjoy the experience of having a VMU in my controller and wireless input.

Only the VMU screen data is shared between Dreamwave and Pico2Maple, game saves and whatnot still happen on the console side of things. I would like to eventually share save data from a VMU plugged into the controller. I think that'd be pretty cool.

Hardware

Hardware-wise there isn't much to what I was able to put together. The brains behind everything is, of course, a Pico 2 W. That combined with a rechargeable battery and a bit of extra power circuitry is all there really is to it.

For the battery charging and discharging circuitry, the Pimoroni LiPo shim was a pretty convenient solution for this project. It takes care of charging the battery and has a built-in power button which saved me the effort of including one.

Raspberry Pi Pico 2 W and battery in a VMU-sized box.

I really didn't want to modify the controller at all for this project. These things are 25 years old by now and it feels wrong to chop them up. To minimize needing to make modifications to the controller itself, I built everything into a memory-card-shaped box that fits into the second expansion slot of the controller. I did cut away a small piece of the controller to make sure the wires could get where they needed to, but this was ultimately unnecessary and I do regret doing that.

Overall, the final product doesn't look too bad. With a smaller battery, or a bit better Tetris-ing of components, it could definitely be shrunk down a bit. But I'm pretty happy with how it turned out. I've been using it for a couple weeks now with my VMUPro and it's easily my favourite Dreamcast controller now.


Tags:


Pico2Maple - Sega Dreamcast Controller Adapter using Raspberry Pi Pico 2

Pico2Maple prototypes powered on during Power Stone 2.

Since getting the Steam Controller working on the Sega Dreamcast, I've been expanding the idea into a general-purpose USB-to-Dreamcast device with an eye on potentially selling it as a product. To that end, I've created a few prototype devices of something I'm calling Pico2Maple.

Pico2Maple is a dongle that plugs into the Dreamcast and allows USB devices to be used on the system in place of original Dreamcast peripherals. Several controllers, keyboards, and even some mice are supported (yes the Dreamcast had an official keyboard and mouse). Additionally, Pico2Maple emulates a VMU - the Dreamcast's memory card - complete with a tiny OLED screen and saving files to a microSD card for easy backups.

So far, I've confirmed the following controllers to work:

  • Steam Controller
  • 8BitDo SN30 Xbox
  • XInput controllers (Xbox 360, One, Series)
  • Sony DualSense5
  • 8BitDo Wireless Dongle (great for connecting a variety of other controllers wirelessly)

Most USB keyboards should work for games like Typing of the Dead or chatting in Phantasy Star Online. Mouse support does need a bit of improvement but chances are good most will work; it's hard to find enough hardware to test things like this.

Some USB devices will report multiple descriptors (a mouse may report as a mouse and a keyboard) for extra functionality. Pico2Maple will try and use the first valid device it sees and pass that through to the Dreamcast. Unfortunately, it's not possible to report multiple devices through a single Dreamcast controller port.

Pico2Maple prototypes.

The brains of the device is a Raspberry Pi Pico 2 with my custom firmware and Maple bus implementation. The firmware is not open source at the moment, but the binaries are available on my GitHub if anybody wants to make their own version of the hardware.

When I started working on this project, the RP2350 chip powering the Pico 2 was not readily available, so I designed a custom PCB where the Pico 2 board could be soldered directly to it. Since most of the 'real' electronics are on the Pico board, my PCB is more-or-less just a way to connect all the extra components and peripherals, with a form factor that would work well for a dongle.

Surprisingly, the prototype PCBs I ordered worked great! I must have gotten lucky because there were no functional issues with the boards. Due to the insane shipping times to where I live though, I was moving a bit fast and wasn't completely decided on a final design when I ordered the PCBs. This is why the USB port is facing the wrong direction and meant I had to do a bit of extra manual prep work on the boards. I hope to do a second revision to fix that, and move around a few components for a better overall fit.

Pico2Maple PCB render.

In addition to the custom PCB, this project was also my first experience with CAD and 3D printing. I designed the entire enclosure for the dongle in FreeCAD and printed them on a BambuLab P1S. The main body of the dongle is made up of 3 pieces that sandwich the electronics together and four m2 screws, with threaded inserts, extend through the whole dongle and squeeze everything tight.

It took quite a bit of tweaking a test-printing to get the fit I was going for but I think it was worth it in the end. They came out looking almost exactly like what I had imagined! (Wavebird dongle vibes anyone?)

The final dimensions of the dongle are roughly 30mm wide, 25mm deep, and 61mm tall. I would say they are a smidge too wide and are therefore a bit too snug when multiple are plugged in. The microSD card also sticks out about 1-2mm so, even though four can fit in the console by themselves, not all would be able to have SD cards plugged in. Ideally I'd shave off maybe 2mm from the width and have the microSD cards be flush for a better fit.

Other than being a bit too wide, I think the rest of the dimensions are perfect and they look pretty slick when plugged into the Dreamcast.

A Dreamcast-coloured Pico2Maple powered on.

I mentioned earlier that I hope to produce and sell these to fellow Dreamcast enthusiasts but the current road block is that assembly simply takes way too long to make it worth it. Between soldering the Pico to the main board, wiring up the Dreamcast plug, and final assembly, the whole process takes maybe 45-60 minutes which is too long for me. Plus I don't really like being hunched over a soldering iron for so long.

I could save some time if JLCPCB could presolder the Pico 2 boards for me, or if I could design a PCB using the RP2350 chip directly. But that still leaves wiring up the Dreamcast plug which is what really takes the bulk of the time, trimming wires and soldering the pins. I'd guess it would still take around 30 minutes to put one together which still seems too long.

If anybody has any tips on speeding up manufacturing I'd leave to hear it. I would also be open to potentially licensing the firmware and letting somebody else handle the manufacturing. Either way, feel free to reach out!

Thanks for reading!


Tags: