Mehmet Fide

AW32: I2C Problem

Discussion created by Mehmet Fide on Sep 12, 2007
Latest reply on Mar 5, 2011 by Maria Ines Castagnino
Hi,
 
First of all, Freescale, I hate your datasheets !
But I like the forum, anyway... :smileyhappy:
 
I'm living interesting problem with I2C and EEPROM AT24C512BN.
If I debug test routine below, it works, "count" be equal to "okunan".
If I directly run the code, it fails at EE_ReadBuffer function. The function returns 0.
 
 
Code:
Test routine:  count = 0x89654321;  // unsigned long
  Init_i2c();  if(EE_WriteBuffer(0, &count, 4, I2C_ADR_EEPROM0))        DispMsg(MSG_FILL, 0);  else DispMsg(MSG_ERROR_CODE, 1);  if(EE_ReadBuffer(0, &okunan, 4, I2C_ADR_EEPROM0))        DispMsg(MSG_FILL, 0);  else DispMsg(MSG_ERROR_CODE, 2);    if(count == okunan)    DispMsg(MSG_FILL, 0);  else DispMsg(MSG_ERROR_CODE, 3);

 
If I change the i2c_start() function such as below: It start working in debug or not.
Code:
void i2c_start(void){  IIC1S_SRW = 0; // R/W bit = 0;  IIC1C_IICEN = 0;  IIC1C = 0b10011000;    IIC1C_MST = 1; // generate START condition}

 
I don't understand the problem due to the datasheet doesn't explain I2C module well.
Regards,
BP.
 
 
Code:
void Init_i2c(void){  // Bus = 18.432MHz;  // mul=4, ICR=0x0D => SCL Div=48, i2c_ Bus Freq = 96Khz, SDA Hold Time = 600ns  IIC1F = 0b10001101;  IIC1S_SRW = 0; // R/W bit = 0;  // Enable i2c module  // not generate ACK by master after transfer;  // TX mode  // Slave mode actually;  IIC1C = 0b10011000;  }void i2c_start(void){  IIC1C_MST = 1; // generate START condition}void i2c_stop(void){  IIC1C_MST = 0; // generate STOP condition;  }void i2c_restart(void){  IIC1C_RSTA = 1; // generate RESTART condition}void i2c_sendbyte(unsigned char data){  IIC1C_TX = 1; // transmit    IIC1D = data;  while(!IIC1S_IICIF); // wait until Transfer to complete;    IIC1S_IICIF = 1;}char i2c_getack(void){  return(!IIC1S_RXAK); // ACK gelmiş ise 1 döner, gelmemişse 0}unsigned char i2c_getbyte(char send_ack){  unsigned char data;    IIC1C_TX = 0; // set up to receive;    IIC1C_TXAK = send_ack—0:1;    data = IIC1D; // dummy read;  while(!IIC1S_IICIF); // wait until Transfer to complete;    IIC1S_IICIF = 1;    data = IIC1D; // read right data;    return(data);}/////////////////////////////////////////////////////////////////////////////////// EEPROM RUTINLERI Atmel AT24C512BN-SH-B veya ST M24512-RM/////////////////////////////////////////////////////////////////////////////////unsigned char EE_WaitForACK(unsigned char external_adr){  unsigned char counter = 100;    unsigned char ack;  unsigned char ControlByte = 0b10100000; // Yazma modu, A2, A1, A0 = 0    ControlByte |= ((external_adr << 1) & 0b00001110);    do  {    i2c_start();    i2c_sendbyte(ControlByte);    ack = i2c_getack(); // i2cgetack, ack alınmış ise 1 döner!    i2c_stop();      --counter; // her deneme 175uS sürüyor, 29 deneme > 5ms yapar.  } while(!ack && (counter != 0));    return(ack);}unsigned char EE_ReadBuffer(unsigned int Adr, unsigned char* Data, unsigned int size, unsigned char external_adr){  // Control Byte = 1 0 1 0 A2 A1 A0 R/W. unsigned char ControlByte = 0b10100000; // Yazma modu, A2, A1, A0 = 0 unsigned char AddrHigh = (Adr >> 8) & 0xFF; unsigned char AddrLow = (Adr & 0xFF);  ControlByte |= ((external_adr << 1) & 0b00001110);  i2c_start();  // Control Byte = 1 0 1 0 A2 A1 A0 R/W  i2c_sendbyte(ControlByte); if(!i2c_getack()) {  i2c_stop();  return(0); } // Address High Byte i2c_sendbyte(AddrHigh); if(!i2c_getack()) {  i2c_stop();  return(0); } // Address Low Byte i2c_sendbyte(AddrLow); if(!i2c_getack()) {  i2c_stop();  return(0); } // Read i2c_restart();  // Control Byte to read ControlByte |= 0b00000001; // Okuma modu i2c_sendbyte(ControlByte); if(!i2c_getack())  {  i2c_stop();  return(0); } do {  *Data++ = i2c_getbyte(size != 1);   } while(--size);  i2c_stop();  return(1);}char EE_WriteBuffer(unsigned int Adr, unsigned char* Data, unsigned int size, unsigned char external_adr){ unsigned int _PAGE = 0xFFFF; // önceki page  do  {     unsigned int CURRENT_PAGE = Adr & 0b1111111110000000; // page size 128 byte    if(CURRENT_PAGE != _PAGE)  {      // Control Byte = 1 0 1 0 A2 A1 A0 R/W.     unsigned char ControlByte = 0b10100000; // Yazma modu, A2, A1, A0 = 0     unsigned char AddrHigh = (Adr >> 8) & 0xFF;     unsigned char AddrLow = (Adr & 0xFF);          ControlByte |= ((external_adr << 1) & 0b00001110);      if(_PAGE != 0xFFFF)   {    i2c_stop();        if(!EE_WaitForACK(external_adr))       return(0);   }      i2c_start();    // Control Byte = 1 0 1 0 A2 A1 A0 R/W.   i2c_sendbyte(ControlByte);   if(!i2c_getack())   {    i2c_stop();        return(0);   }   // Address High Byte   i2c_sendbyte(AddrHigh);   if(!i2c_getack())   {    i2c_stop();        return(0);   }   // Address Low Byte   i2c_sendbyte(AddrLow);   if(!i2c_getack())   {    i2c_stop();        return(0);   }      _PAGE = CURRENT_PAGE;     } //if(CURRENT_PAGE != _PAGE)    i2c_sendbyte(*Data++);  if(!i2c_getack())  {   i2c_stop();   return(0);  }    Adr++; } while(--size); i2c_stop();  return(EE_WaitForACK(external_adr));}

 


Message Edited by BasePointer on 2007-09-12 04:50 PM

Outcomes