AW32: I2C Problem

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AW32: I2C Problem

12,250 Views
BasePointer
Contributor II
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
Labels (1)
0 Kudos
Reply
23 Replies

563 Views
Fonsi
Contributor I

One of the reasons why I do not particularly prefer forums is that is very hard to follow the trend of thought and I do not know if the person who was having the problem is now okay.

I am one of the IIC experts at the factory, my claim to fame is that I have actually been the only one that has gone inside the IIC module and traced signals through the logic module at the Failure Analysis Lab. A project that thought me a lot about what IIC is and what the strengths and weaknesses are. I also exercised the module, polled and interrupt driven to understands hung ups and LOAs and why they were happening in our development tools and for some big European Customers. I am now working for the TechnicalInformationCenter and support mainly the US market but have not problems helping anyone who is having problems with the module.

IIC is not an easy byte protocol and it is even harder to implement at packet protocol but the task is very attainable. I will encourage anybody who is implementing a true IIC bus to open up a service request at www.freescale.com and request the issue to be assigned to me.

I have since written an IIC appnote which I abandoned due to the fact that they were many others in progress so I thought that duplicating efforts would not be the best thing for me. However, you are correct, TCF is a status bit, I never had to use. I started out with the notion that this control bit would act like a completion flag on an Analog to Digital converter but I was wrong and when I ran simulations the TCF is used but it be may only a test mode feature. Since I was under the gun at the time, I never went back to get the real story on what its functionality really is. Sorry for the inconvenience that caused you.

Hi BP,

 

 Your assumption about load capacitance versus speed is incorrect but the concept is right on. The slower the speed under a heavy capacitance load the more of a slew rate affects the IIC bus performance and the more LOAs I experienced, I know why this happens but it would take me more than 3000 chars to explain it. The solution to bus hang ups is to make the rise and fall times of the clock and data as fast as possible. 

 

Regards,

 

Edgar Saenz.

TechnicalInformationCenter.

16 bit Team leader.

 
 
0 Kudos
Reply

563 Views
joemanix
Contributor I
Hi,
i'm using the AW32 I2C module, implementing a master only C code with interrupts. I drive a PCF8570 I2C RAM at 89khz with 4,7K pullups, at less than 5 cm distance on the board. For information, i use this RAM only to save data with a backup battery when the power is off. The main reason is that i couldn't get accurate information on the way to backup directly the AW32 RAM (very basic topic, yes...but the support is still working on it). But it's another story.
 
I started my I2C integration today, and of course, nothing works. At reset, the SDA, SCL lines are high, and after using my write routine for the 1st time, both still at low forever.
I used a step by step execution in the write routine. The lines are high up to arrive at the START condition. At master selection (ie START or IIC1C_MST = 1), both pins goes and still low. No data out,  and the interrupt never comes. It occurs also when i remove the PCF8570 .
 
IIC1C_TX = 1; /* Select Transmit Mode */

IIC1C_MST = 1; /* <<<< problem occurs here         Send Start) */

 //for(T=0;T<10;T++);                    /* Small delay */
 
 SCI1D = iicport_1.IICaddr;            /* write address to start transmission */
 
I tried various SW combinations using the HS08 docs (peripheral module quick reference, ...) but no change. 
I think, by reading this forum, that there is a HW bug somewhere. I'll send a service request.
 
Bye
 
0 Kudos
Reply

563 Views
BasePointer
Contributor II
Hi,
 
Did freescale release any errata for this?
If not, they should provide us a sample code that works.
I've searched the forum and saw that a lot of developers lived similar problems with I2C module.
 
Regards,
BP.
0 Kudos
Reply