The Bus Pirate is a fantastic tool. It gives me an interactive prompt and immediate feedback while playing with the FM transmitter.
Unlike my previous I2C exploration with the 7-segments display, using the MMR-70 is much more complicated. First, there is no nice Arduino library for this device. Second, I do not know immediately whether what I'm doing is working or not. Finally, 23 (!) registers must be correctly initialized before starting the FM transmission.
The datasheet has some ambiguities about which register values to use during the initialisation phase; the FMBerry project uses another set of values; and another code uses yet another set of values. I tried many settings but I was never able to get the transmitter working.
So, I hooked up the Bus Pirate to the SCL and SDA lines of the MMR-70, started the I2C capture mode, plugged it into my phone, started broadcasting a song and, hooray, I captured the whole init section.
Here is what I found :
// The following is sent after plugging the MMR-70 into the phone [0xCC 0x7F 0xA0] // Reset command // Wait [0xCC 0x7F+0xA0] // Reset command again // Init for the 23 registers [0xCC 0x00 0x02] [0xCC 0x01 0x81] [0xCC 0x02 0x0A] [0xCC 0x03 0x00] [0xCC 0x04 0x00] [0xCC 0x05 0x00] [0xCC 0x06 0x00] [0xCC 0x07 0x7E] [0xCC 0x08 0x0E] [0xCC 0x09 0x08] [0xCC 0x0A 0xAF] [0xCC 0x0B 0x2F] [0xCC 0x0C 0x0C] [0xCC 0x0D 0xE6] [0xCC 0x0E 0x3F] [0xCC 0x0F 0x70] [0xCC 0x10 0xA0] [0xCC 0x11 0xE4] [0xCC 0x12 0x00] [0xCC 0x13 0x42] [0xCC 0x14 0xC0] [0xCC 0x15 0x41] [0xCC 0x16 0xF4] // The following is sent after selecting the FM Frequency // on the phone (in this case 90.0 FM) [0xCC 0x02 0x0B] // mute ON [0xCC 0x0A 0xEA 0x2A] // Select Frequency (90.0 FM in this case) [0xCC 0x07 0x7E 0x0E] // P2 [0xCC 0x70[0xCD 0x00] // Read the CEX value (0x00 in this case) [0xCC 0x15 0x39] // Deviation control [0xCC 0x02 0x0A] // mute OFF [0xCC 0x10 0xE0] // RDS stuff [0xCC 0x03 0xE0 0x00] // RDS data [0xCC 0x05 0x01 0x24] // RDS data [0xCC 0x05 0xE0 0xCD] // RDS data // The following is sent after a song is played [0xCC 0x02 0x0B] // mute ON [0xCC 0x0D 0xE6] // ALC [0xCC 0x00 0x03] // Power ON [0xCC 0x05 0x20 0x20] // RDS data [0xCC 0x02 0x0B] // mute ON [0xCC 0x0A 0xEA 0x2A] // Select Frequency (90.0 FM in this case) [0xCC 0x07 0x7E 0x0E] // P2 [0xCC 0x70[0xCD+0x05] // Read the CEX value (0x05 in this case) [0xCC 0x15 0x21] // Deviation control [0xCC 0x02 0x0A] // mute OFF [0xCC 0x10 0xE0] // RDS [0xCC 0x03 0xE0 0x00] // Continuous flow of RDS data [0xCC 0x05 0x01 0x21] [0xCC 0x05 0xE0 0xCD] [0xCC 0x05 0x52 0x2D] [...]
With this information and the datasheet, I noticed that I forgot to send the [0xCC 0x00 0x03] command to activate the power ! Duh !
It's interesting to see that some commands are redundant. For example, the frequency selection command is sent right after the frequency is chosen on the phone but is sent again when a song is being played. I wonder why.
Now I am able to correctly initialize the FM transmitter and broadcast some sound through the analog input pins (although it's really noisy) !
My setup is the following :
- Connect the GND, SDA an SCL pins of the Bus Pirate to the GND, SDA and SCL pins of the MMR-70
- Connect the 5V Bus pirate output to the VIN pin of the MMR-70
- Connect the GND and RST pins of the MMR-70 to prevent the integrated MCU to use the I²C bus. However, do NOT connect the XTAL and GND pins as I have seen in some documents. It did not work for me.
Start your Bus pirate. Select the I²C mode, activate the pull-up resistors, activate the power and start playing with the commands.
To use the I²C sniffer mode while the FM module is connected to the phone, let the phone power the module (so disconnect the Bus Pirate 5V pin from the module), do not connect GNS and RST and do not use the pull-up resistors.My next goal is to drive the module from the Trinket and broadcast a RDS FM station name.