SUPER COPTER
New Member
Hi, i'm working with pic32 and I2C, specifically DS2482 I2C to OneWire chip. I'm reading some DS18B20 Onewire temperature sensors, everything works fine, except under certain contitions (randomly), sometimes it seems onewire bus stops responding.
Now I'm checking the code to see if everything is fine and i started with my I2C libraries.
I'm reading the I2C bus with a logic analyzer, and i noticed that it takes a long time to send an NACK. i checked subroutines and there's any kind of delay or anything. There is a while loop, wich waits for the ACK sequence to complete (after sending the ACK/NACK), but i noticed it really makes no effect if i comment ir or even if i put it somewhere else in the code.
I took a screenshot of what's happening in the bus:
I'm also uploading part of the code i'm using for I2C:
//INIT I2C
BOOL Init_I2C(int I2C_BUS, UINT32 FREQ)
{
//BUS I2C Como entrada
TRISDbits.TRISD9 = 1; //SDA
TRISDbits.TRISD10 = 1; //SCL
int actualClock;
I2C_STATUS status;
I2CConfigure(I2C_BUS, I2C_STOP_IN_IDLE);
actualClock = I2CSetFrequency(I2C_BUS, GetPeripheralClock(), FREQ);
I2CEnable(I2C_BUS, TRUE);
status = I2CGetStatus(I2C1);
if(status & I2C_ARBITRATION_LOSS)
{
print_error("ARBITRATION LOSS");
DelayMs(5000);
//clear_lcd();
//I2CClearStatus (I2C_BUS, I2C_ARBITRATION_LOSS);
return FALSE;
}
//sprintf(lcd, "Clock: %dkHz", actualClock/1000);
//print_error(lcd, 1);
//DelayMs(1000);
//clear_lcd();
return TRUE;
}
//START TRANSFER
BOOL StartTransfer( BOOL restart )
{
I2C_STATUS status;
if(restart) // Start = 0; Restart = 1
{
I2CRepeatStart(I2C_BUS);
}
else
{
while( !I2CBusIsIdle(I2C_BUS) );
if(I2CStart(I2C_BUS) != I2C_SUCCESS)
{
print_error("Start Error");
DelayMs(1000);
//clear_lcd();
return FALSE;
}
}
do
{
status = I2CGetStatus(I2C_BUS);
}
while (!(status & I2C_START));
return TRUE;
}
//STOP TRANSFER
void StopTransfer( void )
{
//DelayMs(1);
I2C_STATUS status;
I2CStop(I2C_BUS);
do
{
status = I2CGetStatus(I2C_BUS);
}
while ( !(status & I2C_STOP) );
}
//TRANSMIT ONE BYTE
BOOL TransmitOneByte( UINT8 data )
{
while(!I2CTransmitterIsReady(I2C_BUS));
if(I2CSendByte(I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
{
//print_error("Transmit Error!",0);
print_error("Bus Collision");
DelayMs(1000);
//clear_lcd();
return FALSE;
}
while(!I2CTransmissionHasCompleted(I2C_BUS));
if(!I2CByteWasAcknowledged(I2C_BUS))
{
return FALSE;
}
else
{
return TRUE;
}
}
// RECIEVE ONE BYTE
UINT8 RecieveOneByte( BOOL SendAck )
{
UINT8 i2cbyte;
I2CReceiverEnable(I2C_BUS, TRUE);
delay(40); //40: 400k; 100 para 100Khz!
if (I2CReceivedDataIsAvailable(I2C_BUS))
{
i2cbyte = I2CGetByte(I2C_BUS);
I2CAcknowledgeByte(I2C_BUS, SendAck);
while ( !I2CAcknowledgeHasCompleted(I2C_BUS) );
return i2cbyte;
}
else
{
print_error("NO DATA!");
DelayMs(1000);
//clear_lcd();
return 0x00;
}
}
Now I'm checking the code to see if everything is fine and i started with my I2C libraries.
I'm reading the I2C bus with a logic analyzer, and i noticed that it takes a long time to send an NACK. i checked subroutines and there's any kind of delay or anything. There is a while loop, wich waits for the ACK sequence to complete (after sending the ACK/NACK), but i noticed it really makes no effect if i comment ir or even if i put it somewhere else in the code.
I took a screenshot of what's happening in the bus:
I'm also uploading part of the code i'm using for I2C:
//INIT I2C
BOOL Init_I2C(int I2C_BUS, UINT32 FREQ)
{
//BUS I2C Como entrada
TRISDbits.TRISD9 = 1; //SDA
TRISDbits.TRISD10 = 1; //SCL
int actualClock;
I2C_STATUS status;
I2CConfigure(I2C_BUS, I2C_STOP_IN_IDLE);
actualClock = I2CSetFrequency(I2C_BUS, GetPeripheralClock(), FREQ);
I2CEnable(I2C_BUS, TRUE);
status = I2CGetStatus(I2C1);
if(status & I2C_ARBITRATION_LOSS)
{
print_error("ARBITRATION LOSS");
DelayMs(5000);
//clear_lcd();
//I2CClearStatus (I2C_BUS, I2C_ARBITRATION_LOSS);
return FALSE;
}
//sprintf(lcd, "Clock: %dkHz", actualClock/1000);
//print_error(lcd, 1);
//DelayMs(1000);
//clear_lcd();
return TRUE;
}
//START TRANSFER
BOOL StartTransfer( BOOL restart )
{
I2C_STATUS status;
if(restart) // Start = 0; Restart = 1
{
I2CRepeatStart(I2C_BUS);
}
else
{
while( !I2CBusIsIdle(I2C_BUS) );
if(I2CStart(I2C_BUS) != I2C_SUCCESS)
{
print_error("Start Error");
DelayMs(1000);
//clear_lcd();
return FALSE;
}
}
do
{
status = I2CGetStatus(I2C_BUS);
}
while (!(status & I2C_START));
return TRUE;
}
//STOP TRANSFER
void StopTransfer( void )
{
//DelayMs(1);
I2C_STATUS status;
I2CStop(I2C_BUS);
do
{
status = I2CGetStatus(I2C_BUS);
}
while ( !(status & I2C_STOP) );
}
//TRANSMIT ONE BYTE
BOOL TransmitOneByte( UINT8 data )
{
while(!I2CTransmitterIsReady(I2C_BUS));
if(I2CSendByte(I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
{
//print_error("Transmit Error!",0);
print_error("Bus Collision");
DelayMs(1000);
//clear_lcd();
return FALSE;
}
while(!I2CTransmissionHasCompleted(I2C_BUS));
if(!I2CByteWasAcknowledged(I2C_BUS))
{
return FALSE;
}
else
{
return TRUE;
}
}
// RECIEVE ONE BYTE
UINT8 RecieveOneByte( BOOL SendAck )
{
UINT8 i2cbyte;
I2CReceiverEnable(I2C_BUS, TRUE);
delay(40); //40: 400k; 100 para 100Khz!
if (I2CReceivedDataIsAvailable(I2C_BUS))
{
i2cbyte = I2CGetByte(I2C_BUS);
I2CAcknowledgeByte(I2C_BUS, SendAck);
while ( !I2CAcknowledgeHasCompleted(I2C_BUS) );
return i2cbyte;
}
else
{
print_error("NO DATA!");
DelayMs(1000);
//clear_lcd();
return 0x00;
}
}