View previous topic :: View next topic |
Author |
Message |
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
Snooping I2C lines |
Posted: Tue Mar 02, 2004 6:28 am |
|
|
Hi everybody
In application I need to snoop on the I2C communication between two devices. I'm using PIC16F876 and PCM3.186. I set up a hardware I2C in slave mode and used the i2c_read(0); to read the bytes. I can read the bytes properly...but...The problem is that after reading a random number of bytes the hardware I2C module of the PIC sets both RC3 and RC4 as outputs and just sits there forever. It looks like it is trying to send something back (but I'm using the '0' parameter in the i2c_read() to stop it from ACKing back). When I try to chang TRISC it doesn't work. At this stage I2C doesn't work anymore and I have to power-cycle the circuit. Does anyone know what is causing this and how I can solve it?
Thanks. |
|
|
mpfj
Joined: 09 Sep 2003 Posts: 95 Location: UK
|
|
Posted: Tue Mar 02, 2004 7:12 am |
|
|
If you're using MPLAB, you can set a breakpoint on a read / write to a file register.
So you could breakpoint on a write to the PORTC tri-state register, which should (in theory !!) stop at / near the offending code ?? |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Tue Mar 02, 2004 8:23 am |
|
|
Are you trying to set the TRISC register yourself directly? If I recall correctly, it is recommended that you not do that because there is a read-modify-write problem with peripherals interacting with the TRISC register. Use the set_tris_c() function. The compiler then creates a mirror register of the TRISC register, then rmws on the register, and copies the mirror to the TRISC register as a byte.
This may not have anything to do with your problem, but I thought I'd just lob it out there as a thought. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Tue Mar 02, 2004 5:55 pm |
|
|
I'm using PCW and I'm afraid there is no offending code, it's just something the hardware I2C is doing. And no I'm not trying to write to TRISC directly. However even if I stop the code and set SCL and SDA pins as inputs in the RAM window, as soon as I do a single step, they go back to outputs. This is basically my whole code:
Code: |
#use I2C(slave,sda=PIN_C4,scl=PIN_C3,address=0x70,RESTART_WDT,FORCE_HW,Fast)
byte DT[60];
while(1)
{
for(I=0;I<56;I++)
{
while(!i2c_poll())
restart_wdt();
}
DT[I] = i2c_read(0);
}
|
Does anyone know what the problem is?! I appreciate any help. |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Tue Mar 02, 2004 7:02 pm |
|
|
I have compiled your code in a test program and it doesn't look like the tris registers are being changed anywhere in the while loop.
Are you absolutely certain that the pins are actually being set to outputs? Are you determining this by reading the tris register, or via a watch window? The read-modify-write problem may cause the tris register to look wrong if read directly. That is the basic problem, it reads WRONG in some cases. Have you disconnected the I2C pins from the bus and applied a "soft" pull up or pull down to see if the pins are actually floating? Or are they being driven?
I'll stick with you on this for a while, I'm just trying to help with some other ideas. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Wed Mar 03, 2004 12:33 am |
|
|
Thanks for your post. Yes I am sure the pins are becoming outputs. The TRISC in the watch window are showing them to be outputs (but as you said it may be wrong), but I'm sure they are being driven because everytime this happens the other two I2C devices (the ones I'm trying to snoop) go berserk and the communication stops between them (one of the them is a display device and it stops showing the data). As soon as I disconnect my circuit from their I2C line they resume operation again. So my PIC is driving those two lines.
As you said, "read-modify-write problem may cause the tris register to look wrong", but is there a chance that it can actually change the value of tris? And is having trisc in watch window a read-modify-write?(It probably is).
When you tested my code, did you actually try to snoop on I2C lines?
Thanks for your help, I really appreciate it. |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Wed Mar 03, 2004 7:03 pm |
|
|
I've been looking at the data sheets and the mid range processor manual, and I not sure that what you are trying to do is possible. It appears that the ACK condition is generated automatically in hardware when the MSSP is in slave mode.
Regarding you other questions, I just created a small project and compiled it. I don't have an I2C network set up right now to test it. I reviewed the lst file for tris register activity.
I'll keep pondering this for a while, but I fear it may be a lost cause, at least in PICs. It may be time for an FPGA.
Charlie |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Thu Mar 04, 2004 6:51 pm |
|
|
Well I guess I'm gonna have to write my own I2C routines. Anybody knows if there are any available on the net? This will save me some time. Thanks. |
|
|
Charlie U
Joined: 09 Sep 2003 Posts: 183 Location: Somewhere under water in the Great Lakes
|
|
Posted: Fri Mar 05, 2004 8:17 am |
|
|
You could start possibly with the link below. Peter Anderson has a fairly large library of routines for various functions. This one is for I2C in assembly, but you could translate it to C. Then work on the slave version of it. Just a thought.
http://www.phanderson.com/PIC/16C84/8574_1.html
Let us know if you are successful with this!
Thanks
Charlie |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Sat Mar 06, 2004 6:57 pm |
|
|
Thanks! I'll try it and keep you posted. |
|
|
|