You will need to know how the arduino I2C function works in order to understand where the problem is coming from.
As someone who has written the I2C implementation using registers (via Atmel studio) I can tell you than most probably, the issue is that the arduino sends a signal on the I2C line and awaits response inside a while() function. It never received the response so it is stuck there waiting forever. You will have to find a way to reach the registers using Arduino IDE, I dont know how easy of feasable that is, you might need to change your I2C library as well.
For example a simple function to read data from TWI (which probably arduino uses) is:
//Read from the TWI, Read result is in TWDR.
uint8_t TWI_Read(uint8_t CheckReadStatus)
{
//Enable TWINT(make it 0) to execute command, Data byte will be received and ACK will be returned
TWCR = (1 << TWINT) | (1 << TWEA)| (1 << TWEN);
//waiting for all data to be read
//while TWINT =0 do nothing. the TWINT will be 1 when start is done.
while((TWCR&(0B10000000))==0); //Arduino's code probably stucks here
}
My solution to this, is to utilize one of arduino's timers. For example I set the timer (timer2 for example here) and then on timer's interrupt routine I just count to a number, say 100 here, and it will reset itself as well (basically use a variable to count time):
/*
For TWI timer check
*/
ISR (TIMER2_OVF_vect)
{
//static uint8_t t2ovf = 0;
if(twiTimerStart)//if we want to start its timer
{
twiTimerStart++;//increase it
if(twiTimerStart >= 100)//if it reaches 100
{
twiTimerStart = 0;//make it zero again
}
}
}
And then I modified the read function to also check on that variable and do ot wait forever:
//Read from the TWI, Read result is in TWDR.
uint8_t TWI_Read(uint8_t CheckReadStatus)
{
//Enable TWINT(make it 0) to execute command, Data byte will be received and ACK will be returned
TWCR = (1 << TWINT) | (1 << TWEA)| (1 << TWEN);
//waiting for all data to be read
twiTimerStart = 1;
//while TWINT =0 AND while timer has not ended, do nothing. the TWINT will be 1 when start is done.
while((TWCR&(0B10000000))==0 && (twiTimerStart != 0) );
if(twiTimerStart)//timer to apply command is >0
{
twiTimerStart = 0;//reset the timer
}
else//TWI ended with time exceeded error.
{
return 1;//timer to apply command exceeded
}
}
It will be hard(er) to do this modifications via Arduino IDE, as it does not give you so direct access to the registers.
regarding the I2C registers, they are described in ATMEGA328p's datasheet page 199