I2C troubles

I’m trying to implement an I2C slave functionality using your Register level interface(polled). I first tried this with I2C0 and got everything setup just fine. But when I try to send a byte to it the whole thing hangs. I watched it on an oscilloscope and the bus seems to operate just fine, all signals are proper and the SDA gets pulled down by the micro on the last clock high and everything. Since the bus appeared to work but the processor seems to just go away I was wondering if this was because there was an interrupt handler configured for this that is hanging. I tried to set the interrupt handler register but cannot instantiate a Register object to do this as I get an argument exception.
Am I right to assume you block access to this from the Register interface?
After that I tried to use I2C1, and when I try to make a Register object for the I2C1 address register I get an argument exception again. Putting in the literal directly and getting this for example:

Register I2C1AddrReg = new Register(0xE005C00C); 

doesn’t work.
I then tried it with I2C2 and I can make all the Register objects I need, but setting it up just like when I did with I2C0 it just doesn’t seem to respond to anything on the bus. I’m doing everything per the datasheet and have verified the following:
PCONP is set correctly (default values are correct anyway)
Clock is set but not necessary for slave mode
PINSEL is set to proper I2C device
PINMODE is set to no pull-up or down
Address reg is set correctly
AA and I2EN are set in the control reg
Status register is always 0xF8 (no status).
I’m trying to make a Mini the slave and sending it data with a Domino. The mini is plugged into the USB, the domino is powered from the +5v/Gnd from the mini. I have external pull-ups and the edge risetime (90%) is about 85ns so everything electrically looks good to me.
At this point I’m stuck anything I should know?


What you are doing as not supported as you know and it will not be easy. The question is, why do you need to setup a slave functionality on FEZ?

I have an existing application that I need to replace the microcontrollers I’m using in. It has a primary microcontroller that enumerates and controls an arbitrary number of secondary microcontrollers over the I2C bus. The secondary controllers are on user configurable plug in cards which have a small amount of hardware that needs to be controlled. I’ve already written proof of concept code for the primary micro to run on the LPC2387 and plan to use it for that. But while I’m moving the primary to another chip I would like to get the secondary going on the same chip for supply-chain and tool-chain continuity, and also since the platform is so nice to code on. I know I2C slave is not supported, but with your register access api (fantastic feature) I’m expecting it shouldn’t be too bad, or at least not worse than implementing it directly in assembly or C.

I think I2C interrupts are enabled internally so once you do anything with I2C, you will fire an interrupt, which in turn fire our internal I2C ISR which would crash the system!

The first thing to do is go through the VIC and disable the I2C interrupt and after that it should be easy! I2C hardware has only about 4 registers!

Now, I am not sure if the VIC registers are open for register access. You need to check the documentation

The two VIC registers I could use are:
0xFFFFF010 -VIC Interrupt Enable register
0xFFFFF014 - VIC Interrupt Clear
and this is the set of ranges I found in the library documentation:
[0x3FFFC000 to 0x3FFFC0A0),
[0xE0000000 to 0xE0000014),
[0xE0004000 to 0xE004C000),
[0xE0068000 to 0xE0090000),
[0xE01FC000 to 0xE0200000),
[0xFFE00000 to 0xFFE00FF8],
[0xFFE0C000 to 0xFFE10000],
[0xFFE10000 to 0xFFE10030],
[0xFFE10200 to 0xFFE103FC],
[0xFFE10800 to 0xFFE10BFC],
[0xFFE10C00 to 0xFFE10C2C].

They are not in any of those ranges, and since I get an error in trying to instantiate the register object for them it would seem that they are blocked. Is there any chance that I could get access to the VIC range in the future?

Hi KyleG,
Have you had any luck with the i2c slave problem?
I too need the domino to act as a slave but haven’t found any info!

I haven’t worked on that since my last post. The final problem was the VIC was not accessible from the Register interface. I don’t know if that was with the latest firmware though, so I don’t know if they changed it. Just try to access the registers listed in the previous post and if that doesn’t work it’s still a no-go. Of course I’m assuming that the interrupt service routine still hangs when the I2C subsystem is setup as a slave. My intention now is to take a look at the Panda (got one on order) and see if building up some custom firmware is feasible. That’s on the 100pin USBizi chip though, if you don’t need the 144pin chip that’s probably the way to go because the only other way I can think of doing it is to hack in some machine code to set the interrupt mask by hand…

Even if you have other systems on the bus, why not let FEZ be the master and others slave?

As I also dabble in PicAxe’s there are a couple of the higher range PicAxes’ that woek well as I2C Slaves. So one could always offload that area.

Take Care

Chimpanzee (Gus): I am not sure who you were asking, but for me it’s because I’m replacing a micro in an existing design (see earlier in the thread.) I’ve been having trouble getting the micro, so I’m forced to design it out.
But I am actually doing what you suggest, I am using the USBizi for the master but I also want to replace the slave micros with your chips.

Marcwolf: Your suggestion is a good one, I think most of the time it’s the right answer. I’m just trying not to go down that road and I suspect the Panda should make it unnecessary, it’d be awfully nice to keep my whole system in .NET uFramework.
Thanks for your post.

If you ever need something for serious commercial project then you only have to give GHI a call and tell them what you need :wink:

A bit late in here!!

May I ask why you are using I2C for board to board comunication? Thats not really what it was designed for! I can’t remember offhand but I2C has a distance problem! you really could do with current drivers like CAN…


Chimpanzee (Gus): It was my intention to call you up when I got to implementing the slave hardware. When I saw you released the Panda I figured I’d like to give that a look first. But I won’t hesitate to call you up.

IanR: The boards I am talking between support it electrically, the channel isn’t being used anywhere close to it’s limits and the electrical distance isn’t that long. It’s not much different to SMBus on PCI cards. But CAN would work great too!

Chimpanzee (Gus): we sometimes have existing systems that need smart co-processors, on the i2c bus, to take care of details…there’s no reason for an end-device, for instance, to have fft, or poly-regression, on-board, unless one absolutely needs it (think battery life): ergo you need to have smarts on your bus!
Most often, the ‘Master’ is the device talking to the network.
Under this architecture, the network communicator talks, cheap and efficient, i2c to it’s co-processor to get the averages, statistics, or whatever, to relay to it’s, say, wireless coordinator, or gateway.

KyleG: I have tried , with no success (the Domino simply hangs), to use your aforementioned code.

What, i think, we need here is a simple NetMF ‘Full’ I2C library port that works on, say, the Domino…the Arduino ‘Wire’ library works well for masters and slaves…

newguy: Two things I thought about but never tried were to instantiate and keep around a I2CDevice object before going at the registers on the off chance that it does anything. Secondly is to switch the debug port to COM1 and see if it puts anything into the debug stream that’s useful.

I completely agree with you on the ‘Full’ I2C library. I’ve always seen the I2C implementation as a weak point in the .NET uFramework. It doesn’t implement slave functionality. There’s no way to use more than one device without having the GC kick in at some point. And its use of member classes is not keeping with the style of the rest of the framework. I think that an update would be worthwhile and hope that happens some day even if it’s vendor specific.
But that said if you have register access and use a polled approach to both sending and receiving on the bus you can get around all of these issues. Being that most I2C activity from the controlling application’s perspective is blocking and controller initiated an interrupt driven approach is often not necessary. It would be nice as a slave to use an ISR especially so you could enter a low power state. But again if you don’t mind 100% CPU activity, it isn’t necessary.
My intention was to develop an open-source library that did both master and slave functions in that fashion; but being that the interrupt mask register is blocked I was foiled. I’m also betting that GHI isn’t going to open up that register in a future general consumption firmware release just because changing interrupt handling is such a great way to mess things up.
I’m definitely planning to re-visit this when my Panda kit ships out to me. And if I do end up getting a library together I’d definitely post it. If you get anything together before me I’d appreciate you letting me know.
Also if the Panda doesn’t pan out for me I’ll definitely be calling up GHI before I do something extreme like spend $$$$ on the ARM tool-chain which is my plan C. I’m betting that they would make doing so unnecessary.

See my answer above. You can always contact GHI directly and discuss your commercial needs