Direct Register Addressing

I have been struggling with this for several months and have now thrown the towel in and have decided to ask for help. I have an old stereo-navigation unit in my car which is essentially 2 parts - a stereo unit and a nav unit. The two units speak to each other via an I2C bus. I tried connecting my Uno to listen to the bus, but it was too slow so I upgraded to a mega 256, then I had some success but wanted to intercept the traffic so again upgraded to a Due, 3.3v a nuisance but easily overcome.

My problem is that I don't want to use the wire library as it doesn't really work for me. What I really want to do is the write my own library but I don't know how to address the registers. I went poking about the various libraries and found that the variables had been defined (REG_TWCR1 etc) but they don't bear any resemblance to what's happening in the bus. So how do I address the Two Wire Control Register on TWI0 for instance? I've tried using standard C++ code for this but it doesn't work.

Any help or ideas greatly received. Thanks in advance.

Derek Smalls

My problem is that I don't want to use the wire library as it doesn't really work for me.

If I were you, I'd be attacking this from two directions. One would be to use the Wire library as a starting point, posting here describing why it doesn't work for me, and what I wanted to do, instead.

The other would be to spend many a fine evening reading the datasheet for the chip that the DUE uses, where the answers to all of your questions can be found. Not all in one place, and not all in normal English, but they are there.

I2C is a slow bus. There is no way that UNO is not fast enough to read the fastest bus speed, which is 1MHz.

Thanks for your advice so far, you have suggested a more detailed account of the problem so here goes:

As I explained, I have a becker 2580 PCM system in my car, it has a crappy 240x320 5" non-widescreen display and can do all the usual stereo functions but also phone, sat nav and air con etc. I looked into upgrading to a more modern PCM but this one matches the rest of the dash and I fancied a project anyway. So I decided to use a Raspberry Pi as the bas for this. When I took apart the unit I discovered that it was two separate units built in into one double DIN unit. The top is a self-contained stereo unit based on two chips a micronas 3001 - which is a digital audio chip for car stereos and an 8-bit micro controller an infineon AM29F800BB-70 with an EPROM chip connected to it which I have interrogated. The bottom unit is the satnav computer etc which I plan to remove and replace with the Pi. It seems like a good idea to keep the top unit as it does all of the stereo stuff, talks to CD MD deals with RDS and does eq and balance-fade, and has a not bad power amp onboard. The top and bottom units talk via an I2C so I started by connecting an Arduino Mega 256 to the bus and ran it off a Mac iBook G4. It gave me some useful stuff but there were two problems, firstly the real time serial display was not quick enough to do more than a few runs without crashing and speeding up the serial display caused it to crash. The second problem was that as I started to work out what the data meant I found that there were several things missing (seen on scope but missing on serial data) which I tracked down to the buffer length being too short at 32, when I made it longer I got this

A0 1 C2 0 F F2 0 0 0 0 0 0 0 C 6 0 20 20 20 20 20 20 20 20 0 0 17 22 1 0 0 0 A0 1 C2 0 F F2 0 0 0 0 0 0 0 C 6 0 20 20 20 20 20 20 20 20 0 0 17 22 1 0 0 0

and by varying the settings on the radio I know what much of it means

01 A0 ?ADDRESS 02 01 RADIO 1 CASSETTE 2 REGIONAL=BIT6 SIDE=BIT3 FFWD=BIT0 03 C2 FM A/B X6 FM AS X4 MW X2 TP=BIT4 CX MUTE=BIT3 DOLBY=BIT6 04 00 LOUDNESS X0 X1 / SDV 0X 4X 8X CX 05 0F 06 F2 07 00 08 00 09 00 10 00 11 00 12 00 13 00 14 AC LSB FREQ FM 88B8 - A8C0 (28') 15 05 MSB FREQ AM 02B5 - 0642 (01') 16 00 PRESET A 1-6 B 7-C 17 20 RDS CHAR 1 18 20 RDS CHAR 2 19 20 RDS CHAR 3 20 20 RDS CHAR 4 21 20 RDS CHAR 5 22 20 RDS CHAR 6 23 20 RDS CHAR 7 24 20 RDS CHAR 8 25 00 ?PTY 26 00 ?TA 27 00 ?CLK 28 16 ?CLK 29 01 ?CLK 30 00 BALANCE F9 - 00 - 07 31 00 FADER F9 - 00 - 07 32 00 TREBLE F7 - 00 - 09

The problem was that, particularly at start up, the streams of data were smaller and when you make a change there is a brief run of shorter messages and so I decided that the best way forward was to put something in between the two units and watch the flow of data, also I needed a faster Mac so I got a DUE as it has two I2C ports and a MacBookPro 15" retina. The problem was that the data stops and starts when on the scope it's flowing, so I decided to take a step back and bought an I2C 4x20 LCD display so that I could get the I2C thing working properly with something that I had the data sheet for and it could display data. This took some fiddling as there are various iterations of the wire library and I got it working with a Liquid_Crystal_I2C library eventually. I then got rid of the lcd bit by just using the Wire commands but what I really want to do is essentially create my own Wire library so that I can be sure that I am not missing any data. The difficulty is that I was brought up on assembly and my C++ is not so hot (but I'm learning), so when I look at the Wire.h and Wire.cpp for example

class TwoWire : public Stream { public: TwoWire(Twi *twi, void(*begin_cb)(void)); void begin(); void begin(uint8_t); void begin(int);

I understand that we are creating a class and borrowing the Stream functions and variables. but I presume that in the line after public:, the TwoWire(…. is a constructor but what does Twi *twi mean? as *twi refers to it's memory address.

Second problem, I can't seem to find the registers that Wire is using as the hardware datasheet calls them TWI_CR for example to refer to the control register but if I experiment with different names I eventually find the REG_TWI0_CR is defined but contains 0.

Anyone able to give me a point or push in the right direction would be greatly appreciated, and sorry for the long post.

Regards Derek Smalls

I understand that we are creating a class and borrowing the Stream functions and variables. but I presume that in the line after public:, the TwoWire(…. is a constructor but what does Twi *twi mean? as *twi refers to it's memory address.

Twi is another class. The twi argument is a pointer to an instance of that class.

*** Subject bump ***

I just came across these posts talking about replacing the CD navigation unit with a Raspberry Pi. I've been thinking along similar lines, ie how to use an Arduino or Raspberry Pi in order to improve this otherwise obsolete unit.

I currently have a spare 16 bit Porsche PCM1 Becker 2580 /Siemens unit with the phone handset to play around with (I don't have the codes as yet, but I'm planning to buy a EEPROM reader to try and dump the relevant bytes in order to get these).

The unit currently in my Porsche 996 is the 8 bit one which only has maps going up to 2000, and so as a first step I wanted to swap the navigation units in order to have access to the 2011 Opel/Vauxhall maps (however I need the code first). It then struck me that it seems ridiculous to be still relying on the CD when all the data could be put on a device like a Pi acting as an emulator (this should also work much faster). Unfortunately I lack the technical knowledge to go forward with this, but nonetheless I'd be very interested to know if Derek or anyone else has made any progress on this.

I'm also frustrated by the phone module which will no longer pick up a network since it is apparently limited to the 900Mhz band. From looking through the software on the GPS disc with a hex editor I noticed that it apparently uses the Siemens A20 cellular engine. It seems that a Siemens TC35i unit can be obtained very cheaply, and I'm sure it must be fairly easy to interface this in place of the current one in order to have dual 900/1800 frequencies and use any SIM card.

I'm planning to open up my unit to see if I can identify a serial interface which could be easily diverted to a TC35i. I haven't yet compared all of the Siemens specific AT commands of the A20 and the TC35i, but if there are differences then I'd thought of putting a Pi or Arduino ahead of the TC35i in order to do any necessary translation. I also wondered if an Arduino could be used to improve the phone book (eg injecting the phone book entries via Bluetooth, or increasing the number of entries).

Another thought was to install a Pi or Arduino in the car in parallel with the current unit, and somehow switch over to it (eg by pressing the dark button which I never use) including using the display, for example to show information from the OBD2 diagnostic socket, or weather info pulled from the web, or to play MP3 and showing the MP3 data / album art on screen.

As you can see, I have a lot of ideas to have some fun with this unit. Just wondered if anyone might have an idea how to do any of these.

I don't know anything about those radios. You may be lucky and find someone else who does, but I wouldn't hold your breath while waiting.

If you want to take on the job of exploring the interfaces yourself and trying out code people here will probably be able to help with specific programming questions.

It would help greatly (i.e. almost essential) if you can post links to the datasheets for the devices you want to connect to.


PS it may be a good idea to start your own Thread with a title that mentions the sort of radio you want to work with - and repeat your question. If you do, make sure to include a link to this Thread to avoid duplication.