Heya, i have been using the next 2 funtions for months, they are included in the basic examples. My application has been working fine while i have been in debugging, debug that i have done usually compiling to flash.
The problem came when i compiled to flash, where i have found that it gets in a loop forever, until the watchdog restarts the program (with watchdog disabled it hangs there forever).
You probably know the next code and maybe you are using it:
Code:
//*=========================================================
//* WRITE
//*=========================================================
//*----------------------------------------------------------------------------
//* \fn AT91F_TWI_WriteByte
//* \brief Send a byte to a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_WriteByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data2send, int nb)
{
unsigned int status,counter=0,error=0;
// Set TWI Internal Address Register
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// Set the TWI Master Mode Register
pTwi->TWI_MMR = mode & ~AT91C_TWI_MREAD;
if(nb <2){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN | AT91C_TWI_STOP;
pTwi->TWI_THR = *data2send;
}
else
{
// Set the TWI Master Mode Register
for(counter=0;counter<nb;counter++){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXRDY)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
pTwi->TWI_THR = *(data2send+counter);
}
}
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
return error;
}
//*=========================================================
//* READ
//*=========================================================
//*----------------------------------------------------------------------------
//* \fn AT91F_TWI_ReadByte
//* \brief Read a byte from a slave device
//*----------------------------------------------------------------------------
int AT91F_TWI_ReadByte(const AT91PS_TWI pTwi ,int mode, int int_address, char *data, int nb)
{
unsigned int status,counter=0,error=0;
// Set TWI Internal Address Register
if ((mode & AT91C_TWI_IADRSZ) != 0) pTwi->TWI_IADR = int_address;
// Set the TWI Master Mode Register
pTwi->TWI_MMR = mode | AT91C_TWI_MREAD;
// Start transfer
if (nb == 1){
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_STOP;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
*(data) = pTwi->TWI_RHR;
}
else{
pTwi->TWI_CR = AT91C_TWI_START | AT91C_TWI_MSEN;
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
// Wait transfer is finished
while (!(status & AT91C_TWI_TXCOMP)){
status = pTwi->TWI_SR;
if ((status & ERROR )== ERROR) error++;
if(status & AT91C_TWI_RXRDY){
*(data+counter++) = pTwi->TWI_RHR;
if (counter == (nb - 1)) pTwi->TWI_CR = AT91C_TWI_STOP;
}
}
}
return 0;
}
I disable interrupts before i call any of those 2 functions and i enable them after. As i said both work fine while i run the code in ram but not when i run it in flash. It doesnt fail always, it happens just some random times, so i though that it was something with interrupts but it is not since i have them disabled.
For example in write funtion it hangs forever here:
Code:
while (!(status & AT91C_TWI_TXRDY)){
status = pTwi->TWI_SR;
if ((status & ERROR) == ERROR) error++;
}
In that case status has always status = 0x00000008 (that bit is always 1 it seems, even when it works fine).
I have tried everything and i have been not able to fix it, i'm thinking to implement it with soft, instead of using the Peripheral.
Some help would be welcome. Thanks in advance.