Sunday, 23 March 2025

MEGAphone Bluetooth module

The next module on the list is something that can do BlueTooth to talk to a headset. For security reasons, I'd prefer something that is BlueTooth only, if I can find it. The problem is that the ESP32 is probably otherwise the obvious choice, but I'm not totally sure that it can be trusted. But then, there is lots of alternative firmware available for it, and at the end of the day, if you are using wireless to talk to a headset, then you have already compromised your own security.

But let's look at the options...

1. Requirements Analysis

The requirements relating to this module are:

Requirement 2.1.1, Bluetooth host module that can connect to headsets and other audio devices. Must support UART or I2C control, and audio interfaces that we can easily implement from the FPGA, such as I2S audio.

Desirable 2.1.2, Bluetooth host module support for keyboards and other HID peripherals. 

Note that 2.1.2 was previously listed as a requirement, but it is not required in the milestones, and so I have allowed it to be relaxed to a desirable. I'll document this in the repository.

2. Key Component Selection

 I do have a BM63 eval kit laying around, which I had originally intended for this use-case, but I believe it is only able to act as a sink (headset/speaker), not a source (phone).  But chatgpt is trying to tell me that it can do both -- and I fear it is hallucinating this, as much as I'd like to believe that it could do it.

So the IS2083 IC can be both source or sink. But I think that's in the BM83, not the BM63. 

Confirmed -- I need the BM83, not BM63.

This all feels vaguely familiar, like I explored this in the past. I'm staring at the BM63 eval kit I have here, and wondering if I didn't get a BM83 kit as well at some point. It would be nice if I did, as they are A$500+ each. 

Ah, it _is_ a BM83 kit -- its just my aging eyes in the dim light here in the middle of the night! Hurrah!

So I can immediately start setting that up, and trying to make it pair with a BT headset, and see how it goes.

I'm starting to read through the documentation, so that I can do some basic testing of this module to make sure it works -- I want it to pair with a headset and pretend to start sending audio to it, and also be able to pretend to start a voice call. I should be able to hear the difference in noise in the ear piece of the old Bose QC35s I have here to tell the difference.

The BM83 supports an "AT command set". Now, this is _not_ a modem-style Hayes-AT command set, but rather an Audio Transceiver Command Set, which is binary in format.

But looking at the commands, it looks like everything I should need is there.  Time for sleep now, but I'll start setting up the board in the morning.

Okay, so now I'm reading my way through the BM83 Evaluation Board User's Guide, with the intention of powering it up and talking to it via UART. That board has a PIC32 microcontroller on it, which I don't want to use, so I may need to figure out which of the many switches need to be set correctly to run the BM83 in stand-alone UART controlled mode.

Following the instructions in section 4, I can put it into pairing mode and make it pair with my phone -- thus confirming that the module is superficially working, which is great.  Except that after pairing, the phone refuses to actually connect with it. But it's a cheap android phone, so it could be that. Also it shows up on my phone under "Other devices" which might mean that it doesn't recognise the set of profiles its offering. After some more pressing the MFB button in semi-random ways, I have gotten it to pair, and it is showing support for HD-Audio AAC, Telephone calls and audio media, which is great. The buttons to control the volume etc, however, are still not causing anything to happen.  But I don't care too much about that right now, as I intend for it to be used primarily in the reverse direction: as the phone, rather than the headset.

Switching SW300 on lets me seemingly switch the BM83 eval board into "test mode" where I can talk directly to it via the USB UART.

Then I can use the isupdate.exe tool from Microchip to talk to it.

I had a frustrating half hour where I could make it connect, and it would even identify it as BT5511_002 in a little box, but then fail to connect.  After some googling around, I found this post, with this sage piece of advice:

Put the TTY into raw mode:

stty -F /dev/ttyACM0 raw
 

With that, I was able to flash the main firmware, the DSP firmware and the application firmware (you have to do them all -- there is a way to "rehex" them to make a single file for convenience, but I didn't do that) with SW300 set to on, and then turn it off again after flashing everything.

This also confirms that SW300 should be off for normal operation.  I did find that if I press RESET_N and then long-press (~1 sec) the MFB button, that the BM83 does output something that looks like the kind of AA + checksum packet format we expect:

AA 00 03 30 00 00 CD
AA 00 03 2D 05 01 CA

So let's try to understand how those should be decoded.

Except I can't even get it to do that reliably now.  I suspect the PIC32 MCU on the eval board might still be doing things and getting in the way.

Let's try to get to the bottom of this.

We want "host mode", where the BM83 expects an MCU to be connected via UART. That's good, because we have the host firmware loaded.

But the eval board will be expecting to have the PIC32 act as the MCU in this case. We need to disable that. I'm finding the documenation for this evaluation board quite frustrating, to be honest. For example, there is a big fat JP303 connector with 40 signals brought out onto it -- but it isn't even mentioned in the user's guide. And it's not like its a different PCB revision that lacks it -- you can see the big 2x20 0.1" header at the top of the PCB in this screenshot, and how there is carefully nothing pointing at it. JP303, which is silkscreened next to it isn't event mentioned once in the manual.

Fortunately despite this seemingly intentional ignorance of it, it has various signals identified on it in silkscreen. Those of interest to us are:

HCI_RXD

HCI_TXD

Indeed HCI_TXD follows the UART TX line from the USB UART adaptor. So my bits are getting that far at least.  And HCI_RXD really seems to be connected to the BM83, because I see those responses that I've been seeing when pressing the MFB ("Multi-Function Button", by the way).  The MFB pin is also routed out onto this JP303.

A bit more digging indicates that S400 selects bewteen onboard PIC32 and an external microcontroller. It was already set to external, which is what I want. So most probably the PIC32 isn't actually being a problem.

So why doesn't the firmware talk to me in any more sensible way?

The first assumption is that the "application" firmware that I loaded on isn't the right one, or doesn't support the UART packetised commands.

So I have perhaps found a clue on this page. It talks about running the config utility to enable the BM83's UART. Maybe RX on the UART has to be enabled? But I find it a bit odd that the UART can send, but not receive.

The datasheet does seem to indicate that this GUI config tool is required to configure host mode. The problem is that that is windows-only software, and I haven't figured how to get it running under Wine yet. Or rather, I can run it, but it so far makes no sense at all. It doesn't seem to communicate with the module but rather allows loading and saving of configurations, without a great deal of clarity as to how to actually drive it.

To add to the fun, there is corrupted copy of the documentation for this config tool in the SDK:

./Tools/Config Tool
./Tools/Config Tool/~$208x_Config_GUI_Tool Release Note.docx
./Tools/Config Tool/is208x_config_gui_tool v1.3.23.exe
./Tools/Config Tool/~$BT5511_Config_Parameter_Table_R0.xlsx
./Tools/Config Tool/is208x_config_default_table.ini
./Tools/Config Tool/IS208x_Config_Parameter_Table_R0.ihlp 

So I know there is some sort of documentation for it, but it's not included.

There is some instructions on use in:

https://ww1.microchip.com/downloads/en/DeviceDoc/BM83-Bluetooth-Audio-Development-Board-User-Guide-DS50002902B.pdf

So let's see what it explains.

Ok, so the tool is quite a bit newer than in the documentation. And the order of the options has changed.

But broadly speaking, it can be followed, and when you save it, it writes a .HEX file that can then be flashed onto the device using the isupdate.exe program.

After a lot of poking around, it looks like the MSPKv2_1.03.0406_SPP firmware is missing many of the UART commands that we'd need. But potentially they are in the v1.3 era. But finding that old firmware is proving non-trivial.  It's not helping that the Microchip website is under maintenance for a few hours right now.

Actually, it looks like the firmware I downloaded fresh is not the latest according to this post. There should be a 2v1.3.5 instad of the 2v1.2.4 that I have. Now to try to find a link where I can download it...

I've since posted a question on the Microchip forum and emailed my local FAE for their distributor to see if I can get some help with this, as I'm just spinning my wheels, when I have much more that I need to get on with. 

I'm going to work on the assumption that there will be some solution to this problem at some point, and since the module does pair with things, that it fundamentally works.  In short, I can get on with designing a module to carry the BM83.

3. Schematic Layout

So for this one, we really just need to host the BM83, and work out which of its 50 pins we actually care about. So let's take a look:

Okay, so that's our pin out. Let's now work out which ones we definitely need, which we definitely don't need, and if there are any we aren't sure about.
 
BM83 Module Pin Description
Pin Number Pin Name Required? Description
1DR1YES (I)I2S interface: digital left/right data
2RFS1YES (I/O)I2S interface: digital left/right clock
3SCLK1YES (I/O)I2S interface: bit clock
4DT1YES (O)I2S interface: digital left/right data
5MCLK1YES (O)I2S interface: master clock
6AOHPRNOR-channel analog headphone output
7AOHPMNOHeadphone common mode output/sense input
8AOHPLNOL-channel analog headphone output
9MICN2NOMIC 2 mono differential analog negative input
10MICP2NOMIC 2 mono differential analog positive input
11AIRNOR-channel single-ended analog input
12AILNOL-channel single-ended analog input
13MICN1NOMIC 1 mono differential analog negative input
14MICP1NOMIC 1 mono differential analog positive input
15MICBIASNOElectric microphone biasing voltage
16GNDYES (P)Ground reference
17DMIC_CLKNODigital MIC clock output
18DMIC1_RNODigital MIC right input
19DMIC1_LNODigital MIC left input
20P3_2MAYBE (I/O)GPIO (default: AUX_IN DETECT)
21P2_6MAYBE (I/O)General purpose I/O port
22ADAP_INNO (P)5V adapter input / USB DFU / battery charge
23BAT_INYES (P)Power supply input (3.2V–4.2V)
24SYS_PWRNOSystem power output (internal use only)
25VDD_IOYES (P)I/O power supply (internal use)
26PWR (MFB)YES (I)Multi-function push button
27SK1_AMB_DETMAYBE (I)Temperature sense channel 1
28SK2_KEY_ADMAYBE (I)Temperature sense channel 2
29P8_6 / UART_RXDYES (I/O)GPIO / UART RX data
30P8_5 / UART_TXDYES (I/O)GPIO / UART TX data
31P3_4 / UART_RTSYES (I/O)GPIO / UART RTS / Mode select
32LED1MAYBE (I)LED driver 1
33P0_2MAYBE (I/O)GPIO (default: play/pause)
34LED2MAYBE (I)LED driver 2
35P0_6MAYBE (I/O)GPIO
36DMNO (I/O)USB D-
37DPNO (I/O)USB D+
38P0_3MAYBE (I/O)GPIO (default: reverse)
39P2_7MAYBE (I/O)GPIO (default: volume up)
40P0_5MAYBE (I/O)GPIO (default: volume down)
41P1_6 / PWM1MAYBE (I/O)GPIO / PWM1 output
42P2_3MAYBE (I/O)GPIO
43RST_NYES (I)System reset (active-low)
44P0_1MAYBE (I/O)GPIO (default: forward)
45P0_7MAYBE (I/O)GPIO
46P1_2 / TDI_CPU / SCLMAYBE (I/O)GPIO / Debug / I2C SCL
47P1_3 / TCK_CPU / SDAMAYBE (I/O)GPIO / Debug / I2C SDA
48P3_7 / UART_CTSMAYBE (I/O)GPIO / UART CTS
49P0_0 / UART_TX_INDYES (I/O)GPIO / Codec reset (Embedded) / TX_IND (Host)
50GNDYES (P)Ground reference

So that's 15 yeses and 18 maybes. That would make 33 total, if we include everything that we could feasibly want (given we are only using this to send and receive I2S audio. I am a bit concerned about whether the BM83 can convey bidirectional audio from a call via it's digital I2S interface, but we can live without that for this initial version, as the microphone array on the MEGAphone unit itself will be fine to use for many use-cases. For true hands-free operation, e.g., a headset in a bike helmet, like I use from time to time, we'd need it though. But as said, we will defer that for now.
 
Back to our 33 pins, that means that we need at least a 2x17 module, which would be 1.7 inches long.  The BM33 is 22mm from the bottom to where the PCB antenna starts, i.e., ~0.9 inches. So if we want all those extra pins, we will end up using more board realestate than we'd like.  So let's prune out the bluetooth fuction buttons, e.g., reverse, volume up, down, forward, play (5 pins), the temperature sensor (2 pins), the stray GPIOs (5 pins), and that leaves us with 21 pins, which would fit just about perfectly -- and still leave us with the most likely pins we'd need. The updated table would look like this: 
 
BM83 Module Pin Description
Pin Number Pin Name Required? Description
1DR1YES (I)I2S interface: digital left/right data
2RFS1YES (I/O)I2S interface: digital left/right clock
3SCLK1YES (I/O)I2S interface: bit clock
4DT1YES (O)I2S interface: digital left/right data
5MCLK1YES (O)I2S interface: master clock
6AOHPRNOR-channel analog headphone output
7AOHPMNOHeadphone common mode output/sense input
8AOHPLNOL-channel analog headphone output
9MICN2NOMIC 2 mono differential analog negative input
10MICP2NOMIC 2 mono differential analog positive input
11AIRNOR-channel single-ended analog input
12AILNOL-channel single-ended analog input
13MICN1NOMIC 1 mono differential analog negative input
14MICP1NOMIC 1 mono differential analog positive input
15MICBIASNOElectric microphone biasing voltage
16GNDYES (P)Ground reference
17DMIC_CLKNODigital MIC clock output
18DMIC1_RNODigital MIC right input
19DMIC1_LNODigital MIC left input
20P3_2NOGPIO (default: AUX_IN DETECT)
21P2_6NOGeneral purpose I/O port
22ADAP_INNO (P)5V adapter input / USB DFU / battery charge
23BAT_INYES (P)Power supply input (3.2V–4.2V)
24SYS_PWRNOSystem power output (internal use only)
25VDD_IOYES (P)I/O power supply (internal use)
26PWR (MFB)YES (I)Multi-function push button
27SK1_AMB_DETNOTemperature sense channel 1
28SK2_KEY_ADNOTemperature sense channel 2
29P8_6 / UART_RXDYES (I/O)GPIO / UART RX data
30P8_5 / UART_TXDYES (I/O)GPIO / UART TX data
31P3_4 / UART_RTSYES (I/O)GPIO / UART RTS / Mode select
32LED1MAYBE (I)LED driver 1
33P0_2NOGPIO (default: play/pause)
34LED2MAYBE (I)LED driver 2
35P0_6NOGPIO
36DMNO (I/O)USB D-
37DPNO (I/O)USB D+
38P0_3NOGPIO (default: reverse)
39P2_7NOGPIO (default: volume up)
40P0_5NOGPIO (default: volume down)
41P1_6 / PWM1NOGPIO / PWM1 output
42P2_3NOGPIO
43RST_NYES (I)System reset (active-low)
44P0_1NOGPIO (default: forward)
45P0_7NOGPIO
46P1_2 / TDI_CPU / SCLMAYBE (I/O)GPIO / Debug / I2C SCL
47P1_3 / TCK_CPU / SDAMAYBE (I/O)GPIO / Debug / I2C SDA
48P3_7 / UART_CTSMAYBE (I/O)GPIO / UART CTS
49P0_0 / UART_TX_INDYES (I/O)GPIO / Codec reset (Embedded) / TX_IND (Host)
50GNDYES (P)Ground reference

So let's filter out all the NOs and see how it looks:
BM83 Module Pin Description
Pin Number Pin Name Required? Description
1DR1YES (I)I2S interface: digital left/right data
2RFS1YES (I/O)I2S interface: digital left/right clock
3SCLK1YES (I/O)I2S interface: bit clock
4DT1YES (O)I2S interface: digital left/right data
5MCLK1YES (O)I2S interface: master clock
16GNDYES (P)Ground reference
23BAT_INYES (P)Power supply input (3.2V–4.2V)
25VDD_IOYES (P)I/O power supply (internal use)
26PWR (MFB)YES (I)Multi-function push button
27SK1_AMB_DETMAYBE (I)Temperature sense channel 1
28SK2_KEY_ADMAYBE (I)Temperature sense channel 2
29P8_6 / UART_RXDYES (I/O)GPIO / UART RX data
30P8_5 / UART_TXDYES (I/O)GPIO / UART TX data
31P3_4 / UART_RTSYES (I/O)GPIO / UART RTS / Mode select
32LED1MAYBE (I)LED driver 1
34LED2MAYBE (I)LED driver 2
43RST_NYES (I)System reset (active-low)
46P1_2 / TDI_CPU / SCLMAYBE (I/O)GPIO / Debug / I2C SCL
47P1_3 / TCK_CPU / SDAMAYBE (I/O)GPIO / Debug / I2C SDA
48P3_7 / UART_CTSMAYBE (I/O)GPIO / UART CTS
49P0_0 / UART_TX_INDYES (I/O)GPIO / Codec reset (Embedded) / TX_IND (Host)
50GNDYES (P)Ground reference

Okay, so I relented, and added the temperature sensor back in, because I think it might be good to know the internal temperature of the unit, and I'd miscounted pins, so this still leaves us at just 22 pins, which feels acceptable. 

Ah, there are also two GND pads, so that saves us a pin. Also, the VCC_IO pin isn't needed either, apparently, according to the footprint that I'm using. The footprint is annoying in that it has a keep-out zone for copper surrounding the GND pads on the rear of the PCB! I've just modified that so that it allows vias, so that I can still connect those pads to GND.

The end result is a very simple schematic:

Note that we feed 3.3V to the modules VBAT input. This is so that we can still switch power on and off to this module, rather than running it directly from the battery.

4. PCB Layout

The PCB layout is also trivial, with the pin assignments on the module being mapped so that all routing happens on the front, except for the power and ground which are routed on the rear.
 

5. Requirements Cross-Check

Requirement 2.1.1, Bluetooth host module that can connect to headsets and other audio devices. Must support UART or I2C control, and audio interfaces that we can easily implement from the FPGA, such as I2S audio.

Met -- in that we have the Bluetooth module, and the necessary interfaces for I2C and I2S and UART.

Desirable 2.1.2, Bluetooth host module support for keyboards and other HID peripherals. 

Met if and only if the BM83 can be configured to talk to HID devices. This remains unknown, but as this is only a desirable rather than a requirement, we are fine.

In short, we have this module finished!

 


 
 
 
 

No comments:

Post a Comment