View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
I2c hanging, need help with code |
Posted: Mon Jul 12, 2010 8:56 am |
|
|
Hello everybody,
I am connecting a pic18f4680 to a fram and other pic18f4620 and the code hangs after a few minutes.
I2c pullups are 1.8k and tracks are short.
The code used to write and read are these:
Code: | char I2C_Read (char read_ack) { // TRUE if we should ACK the byte
SSPCON1bits.SSPOV = 0;
SSPCON2bits.RCEN = 1;
while (SSPCON2bits.RCEN);
if (read_ack)
SSPCON2bits.ACKDT = 0;
else
SSPCON2bits.ACKDT = 1;
SSPCON2bits.ACKEN = 1;
while (SSPCON2bits.ACKEN); // halts here
return (SSPBUF);
}
I2C_RESULTS I2C_Write (char data) { // byte send over the I2C
SSPCON1bits.WCOL = 0;
SSPBUF = data;
while (SSPSTATbits.BF);
while ((SSPCON2 & 0x1F) || (SSPSTATbits.R_W));
if (!SSPCON2bits.ACKSTAT) // test for ACK condition received
return (BYTE_ACKED);
else
return (BYTE_NACKED);
} |
It halts reading/acking one byte from a slave (don´t know which one yet).
Am I missing somethine here?
Thank you. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 12, 2010 11:25 am |
|
|
Is there a reason why you are not using the #use i2c() library and the
built-in CCS i2c functions ?
Have you tested it with software i2c (using the #use i2c() library) ?
Does it then work ?
What's the silicon revision of your PIC ? Some revs have problems
with the hardware i2c master (for example, rev A3 is buggy):
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010305#1
The silicon revision is reported by the ICD2 when it "connects" to the PIC
in MPLAB. The CCS IDE probably reports it in a similar way. What is
the rev of your PIC ?
What's your compiler version ? |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Mon Jul 12, 2010 11:42 am |
|
|
4680 rev 0x4
CCS 4.107
The built in functions work fine up to 1MHz. What I want is to implement bus fault recovery later because I don´t want this device to hang in the field.
The CCS i2c read and write functions can easily get into infinite loops because they don´t have any timeout.
I could do it with the watchdog and sending SCK pulses to reset slave devices, but I really don´t want to reset the main controller. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Mon Jul 12, 2010 12:59 pm |
|
|
Implement a timer interrupt.
Reset the counter, and enable it before your I2C transaction.
If it triggers you have a timeout,
Recover, by disabling the I2C hardware, setting the lines to float, and re-enabling the hardware.
Have a watchdog as well. If this triggers, the hardware has become locked by a latch-up in the processor CMOS. To clear this, you will have to remove the power from the chip. The best way of preventing this, is to have an external I2C transceiver like the p82b96....
Have I2C being used like this in kit that has been running in a number of industrial applications for several years, without problems.
Best Wishes |
|
|
|