Law
.
- Joined
- Mar 24, 2016
- Messages
- 11
- Likes
- 24
So I've been working on this Bluetooth module replacement. I've been too busy to get farther recently but I thought I'd share some progress in the meantime for your reading pleasure (note: you may want to sit down and perhaps fetch a beverage of some variety if you plan to read all of this)
Some background first. The purpose of this is to expand on the Wiimote emulator I built a while ago and address its shortcomings by removing actual wireless Bluetooth from the equation altogether. The end result could be used to create a highly configurable setup that supports any kind of custom wired or wireless inputs and even real Wii controllers at the same time. I realize that there are other ways to accomplish something similar, particularly software-based approaches that could arguably have some advantages over this. In any case, this is the way I'm interested in doing it right now, mainly because it involves the likes of USB, Bluetooth, Wiimotes, etc. all in one ridiculous project, it is maximally flexible, and requires no software modifications whatsoever.
The idea is to implement a USB device that mimics the descriptors and functionality of the Wii's internal (USB) Bluetooth module. To do this, I set up an FTDI MM90EV-LITE board, which is a FT900 development board. The FT900 is a microcontroller with lots of features, including flexible USB functionality, so it seem(ed) like a pretty good candidate for this project (more on this later).
Here is the testing setup (edit: the FT900 board and the debugger labels should be swapped, too lazy to fix right now, sorry):
Alongside the dev board is a USB capture device (for sniffing traffic between USB devices), a programmer/debugger attachment to the dev board, and various Wii guts spilled all over the place. I've soldered a USB jack onto the bus where the Bluetooth module used to be and added a USB plug to the original module so I can switch out the modules easily as well as connect both modules to the capture device or a PC.
After writing some USB enumeration code and copying the USB descriptors of the Wii's module, the custom module is connected. Bluetooth has a standard interface called HCI that is used for communication between the Bluetooth host (Wii) and controller (module). Before it finishes booting, the Wii issues several HCI commands to initialize and configure the module, most of which require responses from the controller in the form of HCI events. Once proper responses to all of said HCI commands are implemented, the Wii boots right up:
At this point, the next step is to connect a controller. This is done through some HCI events to establish the "Bluetooth" connection and then the Wii and Wiimote exchange higher level packets that consist mainly of what a real Wiimote (or the Wiimote emulator) outputs over real Bluetooth. In fact, most of the Wiimote emulator code can be chopped right into this project for the Wiimote's functionality.
There's just one unfortunate problem I ran into... and it's a bit subtle so for your convenience I've hidden the gory details to shorten this already lengthy post. Expand the spoiler for the curious/interested.
tl;dr: The FT900 microcontroller I have been using will not work.
What now then? Unless I've missed something, there don't appear to be any USB+microcontroller devices out there that fit the bill (at least none that are still in production). This is annoying, but it isn't a showstopper. What is needed now is to roll a custom USB device with an FPGA. Fortunately, there already exist open source codez for USB 2.0 hardware devices that can pretty easily be adapted to this, saving time. The hardest part at this point is picking a decent FPGA part that is accessible, well-supported, cheap, and capable enough.
Also, if anything is curious about anything related to the Wiimote or Bluetooth module, I've pretty much turned them inside out at this point. Consider this a brief overview
Some background first. The purpose of this is to expand on the Wiimote emulator I built a while ago and address its shortcomings by removing actual wireless Bluetooth from the equation altogether. The end result could be used to create a highly configurable setup that supports any kind of custom wired or wireless inputs and even real Wii controllers at the same time. I realize that there are other ways to accomplish something similar, particularly software-based approaches that could arguably have some advantages over this. In any case, this is the way I'm interested in doing it right now, mainly because it involves the likes of USB, Bluetooth, Wiimotes, etc. all in one ridiculous project, it is maximally flexible, and requires no software modifications whatsoever.
The idea is to implement a USB device that mimics the descriptors and functionality of the Wii's internal (USB) Bluetooth module. To do this, I set up an FTDI MM90EV-LITE board, which is a FT900 development board. The FT900 is a microcontroller with lots of features, including flexible USB functionality, so it seem(ed) like a pretty good candidate for this project (more on this later).
Here is the testing setup (edit: the FT900 board and the debugger labels should be swapped, too lazy to fix right now, sorry):
Alongside the dev board is a USB capture device (for sniffing traffic between USB devices), a programmer/debugger attachment to the dev board, and various Wii guts spilled all over the place. I've soldered a USB jack onto the bus where the Bluetooth module used to be and added a USB plug to the original module so I can switch out the modules easily as well as connect both modules to the capture device or a PC.
After writing some USB enumeration code and copying the USB descriptors of the Wii's module, the custom module is connected. Bluetooth has a standard interface called HCI that is used for communication between the Bluetooth host (Wii) and controller (module). Before it finishes booting, the Wii issues several HCI commands to initialize and configure the module, most of which require responses from the controller in the form of HCI events. Once proper responses to all of said HCI commands are implemented, the Wii boots right up:
At this point, the next step is to connect a controller. This is done through some HCI events to establish the "Bluetooth" connection and then the Wii and Wiimote exchange higher level packets that consist mainly of what a real Wiimote (or the Wiimote emulator) outputs over real Bluetooth. In fact, most of the Wiimote emulator code can be chopped right into this project for the Wiimote's functionality.
There's just one unfortunate problem I ran into... and it's a bit subtle so for your convenience I've hidden the gory details to shorten this already lengthy post. Expand the spoiler for the curious/interested.
First, it is important to establish the concept of a USB endpoint. An endpoint in USB is an abstraction for a source or sink of data. Any data transferred over USB must be assigned an endpoint to be sent to/from. This is not only useful to differentiate between types/uses of data being sent, but also determines how the USB hardware will handle the data. Typically, USB hardware will contain a buffer used to store incoming data and/or outgoing data for each endpoint that can be read or written by a microcontroller, for example.
In USB Bluetooth devices, there is a typical, recommended endpoint configuration for USB Bluetooth adapters. Here is the relevant part of a table from the Bluetooth HCI spec:
From the table, HCI commands are sent OUT (from the Wii) on endpoint 0, HCI events are sent IN (to the Wii) on endpoint 1. The 0x80 bit flag in the endpoint address indicates the endpoint direction is IN. Notice that ACL data, which is used for Wiimote data, is sent IN and OUT both over endpoint 2, addresses 0x82 and 0x02 respectively. This is important.
Here is the description of the USB peripheral features in the FT900 microcontroller user manual:
The manual states that 8 endpoints are available, which is more than needed. However, it is a bit vague about how they can be configured. Specifically, the USB hardware in the FT900 only supports a single direction for each endpoint and not both IN and OUT (probably for hardware simplicity and because for most uses this is not important). Thus, the recommended endpoint configuration for Bluetooth controllers described above is not possible with this device.
This fact alone is not necessarily a problem; I had actually considered this when I decided to use the FT900. Normally, when a USB device sends its descriptors (a step in USB device setup), it provides the addresses of available endpoints that, for example, a Bluetooth driver should use. It is possible to instead just choose different endpoint addresses that the FT900 could support (note "suggested endpoint address" in the table).
The problem is, as I had feared, the Wii's Bluetooth drivers simply ignore the provided endpoint descriptor information. The endpoint configuration is hard coded somewhere in that pesky little box, presumably to avoid the hassle of writing a proper driver since the Wii's Bluetooth module is the only device that it is designed to handle.
In USB Bluetooth devices, there is a typical, recommended endpoint configuration for USB Bluetooth adapters. Here is the relevant part of a table from the Bluetooth HCI spec:
From the table, HCI commands are sent OUT (from the Wii) on endpoint 0, HCI events are sent IN (to the Wii) on endpoint 1. The 0x80 bit flag in the endpoint address indicates the endpoint direction is IN. Notice that ACL data, which is used for Wiimote data, is sent IN and OUT both over endpoint 2, addresses 0x82 and 0x02 respectively. This is important.
Here is the description of the USB peripheral features in the FT900 microcontroller user manual:
The manual states that 8 endpoints are available, which is more than needed. However, it is a bit vague about how they can be configured. Specifically, the USB hardware in the FT900 only supports a single direction for each endpoint and not both IN and OUT (probably for hardware simplicity and because for most uses this is not important). Thus, the recommended endpoint configuration for Bluetooth controllers described above is not possible with this device.
This fact alone is not necessarily a problem; I had actually considered this when I decided to use the FT900. Normally, when a USB device sends its descriptors (a step in USB device setup), it provides the addresses of available endpoints that, for example, a Bluetooth driver should use. It is possible to instead just choose different endpoint addresses that the FT900 could support (note "suggested endpoint address" in the table).
The problem is, as I had feared, the Wii's Bluetooth drivers simply ignore the provided endpoint descriptor information. The endpoint configuration is hard coded somewhere in that pesky little box, presumably to avoid the hassle of writing a proper driver since the Wii's Bluetooth module is the only device that it is designed to handle.
tl;dr: The FT900 microcontroller I have been using will not work.
What now then? Unless I've missed something, there don't appear to be any USB+microcontroller devices out there that fit the bill (at least none that are still in production). This is annoying, but it isn't a showstopper. What is needed now is to roll a custom USB device with an FPGA. Fortunately, there already exist open source codez for USB 2.0 hardware devices that can pretty easily be adapted to this, saving time. The hardest part at this point is picking a decent FPGA part that is accessible, well-supported, cheap, and capable enough.
Also, if anything is curious about anything related to the Wiimote or Bluetooth module, I've pretty much turned them inside out at this point. Consider this a brief overview