Last year I bought an old 1988 BMW 3-series, registered to the original owner 3 days before I was born. The only thing I don't like about the car is the look of the glossy, flashing aftermarket radio right in the middle of the great-looking dash.
So I had an idea about a month ago: It would be awesome if I had the original radio back in the car, but with some modern improvements like Bluetooth support and a more stout amplifier. The catch: I want the radio to look and behave as if it were designed with all that from the factory.
That's my goal for the project, and I figured I should document my progress, so here goes. So here's the factory radio, the Alpine CM5908:
Pretty standard 80s cassette deck except the super cool infrared-sensing 'slider' in the bottom right which is used to adjust bass/treble/balance/fade, and the pretty cool 4-way pad on the left for transport control. In the BMW community, I guess people call this the 'slider radio'.
After thinking about it for awhile, here's a diagram showing roughly how I'm thinking the signal flow will work and what new HW I need:
I've been calling the project "Raspberry Cassette" after I started singing it to the Prince tune. It'll be a joint effort between a Raspberry Pi (for the audio stack, Bluetooth stack, and a CPU capable of real-time audio DSP) and an Arduino (for SPI slave capabilities, ADC for volume pot sampling, and general off-loading of any other digital IO possible since the pi doesn't have enough). These two will be talking over UART to coordinate events. They basically sit in between the factory UI and the factory MCU so that I intercept all the button presses and have control over the display.
The tricky part is I want to keep the AM/FM/WB (weather band, who knew?) capabilities, so in certain modes, I essentially want to be invisible and simply forward on button events or LCD frame buffers through my layer. My idea is that the 'Band" button on the front, which cycles between AM/FM/WB, will be handled such that at the end of the cycle, there is one new option, BT, at which point I sort of take over the buttons and display, not forwarding on that "Mode" button press to the original MCU. Hit "Band" again and you're back to AM and "passthrough" mode.
As far as audio routing, my plan is to find the stereo (pre front/back fader) preamp output in the radio, tap off there, and feed that into the line-in on my USB sound card. The other input will be via Bluetooth A2DP. I will write a C++ program on the pi that will need to handle the following:
- Communicate with Arduino via USB serial
- Manage GPIO using WiringPi library. Includes getting interrupts from buttons, controlling outputs to factory MCU
- Use libPulse with PulseAudio on the pi to get access to the incoming audio streams, as well as a hook to write to the 4-channel output stream). Implement software mixer to control source selection/etc
- Some basic audio processing controlled via slider input. I may deviate from my goal of "works just like factory" here and add a 5-band parametric EQ.
After audio is routed to the USB sound card, the DACs convert to analog, 4 channels are sent to an off-the-shelf 4-channel car audio amp, which feeds the speakers. Ta-da! Now to make it happen...
So that's the idea. Progress:
- Bought a working CM5908 radio on eBay about a month ago. Started tearing in:
Started hacking the LCD display first. They even labeled the pinout, how nice:
The controller chip is a Sanyo LC7582, seen here on the back of the LCD board. Connector that fastens into the main board is on the end.
Desoldered one side of the connector, pulled up the leads, ready to insert myself between the PCB (feeding the LCD) and the connector leads (coming from MCU):
Done. Not totally pretty. Ribbon cable connects into the PCB, the small wires I soldered onto the smaller connector leads to give myself something more to work with:
Got the data sheet for the LC7582 online, pretty simple SPI communication to control it. Started working on a sketch to control it. Once I had it working and the segments mapped, I had my first real success:
Problem is, somewhere I goofed, probably shorted something, and the LCD segments only stay lit for a very short time on their own before slowly kinda dissolving away. That's why you see the flash light above, to provide my own 'back light' which at least lets me test what I'm doing.
First question: Anyone familiar with these old segment displays know what I burnt out on my board based on that description? They will light up when first powered, but within 5 seconds, it's like the light starts to dissolve away. Remove power, wait a minute, and you can repeat with the same results.
On to the next piece to hack: the front panel. Here's an overhead with the whole cassette deck removed and the front panels flex removed:
So I found that it's a 1.25mm pitch, 27 position flat-flex cable, and I made up some breakout boards so that I can probe around to reverse engineer what every lead controls. This is where I've run into my next big issue where I need someone smarter than me:
When I started trying to find what pins did what on this connector, I started by trying to map out the push buttons. I figured, I should easily find a pin at this connector go between ground and 3.3/5V when any given push button on the front is pressed. That's not turning out to be the case. I find pins that seem to be tied with a button, but the voltage jump is nowhere near 0 and 3.3V - it's between like 0.2 and 0.3 volts, but definitely not just noise, it's a reliable jump.
So my second question: What other ways would the MCU be registering a button press if the voltage swing is only like 0.1 V? Is there some other measure going on here? I'm and audio SW guy, so I'm a little out of my wheelhouse on this one. Any advice would be much appreciated.
That's my progress as of now, been working on my pi app lately since I've been stumped on this hardware issue. More updates to come!