EmbDev.net

Forum: ARM programming with GCC/GNU tools SIC bit in IIC (I2C) module on LPC2129 doesn't clear


von Javier R. (fjrg76)


Rate this post
useful
not useful
Hi everyone!!

I've trying for a while to make the I2C module to work in polling mode, 
but I found that interrupt bit (SI) bit doesn't clear whenever I write a 
1 in the I2CONCLR register. Every other bits seem to change accordingly 
in the way one expects, but this one refuses to do so. The user manual 
says that writing a 1 in I2CONCLR clears that bit, and I need to see 
changes in this bit for polling correctly, otherwise I'll need to check 
all over the 26 status codes!!

The general idea is to read and program the flash memory 24LC32 (as well 
as other devices like RTC's), but before I needed to write the I2C 
driver. When writing a byte I had no problems (I guess), but I don't 
know whether it works or not 'cause I'm not able to read it 'til now. 
Here is an excerpt from my code (sorry, comments are in spanish, my 
mother tongue). There is no enough nor clear information over the net 
for using the I2C module, so as soon as I make it work as it should I'll 
share it with the community. Please take a look at the iicSndStart() and 
iicRdBy() functions

Thanks in advanced =)


/* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */
void iicInit(void)
{
  IO0SET|=(3<<2);

  // config PINES
  PINSEL0|=(1<<4)|(1<<6);

  // baud rate para 100 KHz: i2scl=60x10_6/100x10_3=600=300+300
  I2SCLH=300;
  I2SCLL=300;

  // igual que después del reset
  I2CONCLR=0x6c;    // NOTA: no se debe escribir 0xFF !!
  I2CONSET=IIC_I2EN_BIT;  // habilita el módulo IIC
}

/* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */
bool_t iicSndStart(ubyte_t addr, bool_t t)
{

  I2CONSET=IIC_STA_BIT;    // envía el start

  while(!(I2STAT&0x08))
    ;

  I2CONCLR=IIC_STAC_BIT;    // evita start's consecutivos

  I2CONCLR=IIC_SIC_BIT;    // <-- DOESN'T CHANGE THE SI BIT !!

  if(t==IIC_WRITE){
    addr&=~(IIC_READ);
  }
  else{
    addr|=(IIC_READ);
  }

  I2DAT=addr;      // envía la dirección

  I2CONCLR=IIC_SIC_BIT;    // <-- DOESN'T CHANGE THE SI BIT !!

  while(!(I2CONCLR&IIC_SI_BIT)) // espera a que se transmita el byte
    ;

  if(I2STAT==0x18){  // se recibió el ack del esclavo (wr mode)
    return true;
  }

  if(I2STAT==0x40){  // se recibió el ack del esclavo (rd mode)
    return true;
  }

  return false;

}

/* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */
void iicSndStop(void)
{
  I2CONSET=IIC_STO_BIT; //envía el stop. Automáticamente se pone en 0
}

/* ---- THIS NEXT ALREADY WORKS AS EXPECTED --- */
bool_t iicWrBy(ubyte_t data)
{
  I2DAT=data;      // transmite el dato

  I2CONCLR=IIC_SIC_BIT;    // resetea la bandera SI

  while(!(I2CONCLR&IIC_SI_BIT)) // espera a que se transmita el byte
    ;

  if(I2STAT==0x28){  // se recibió el ack del esclavo (wr mode)
    return true;
  }

  return false;

}

/* I'M STILL WORKING IN THIS ONE 'CAUSE SI BIT DOESN'T CHANGE
ubyte_t iicRdBy(void)
{
  I2CONCLR=IIC_SIC_BIT;    // <-- DOESN'T CHANGE THE SI BIT !!

  while(!(I2CONSET&IIC_SI_BIT))  // espera a recibir el dato
    ;

  if(I2STAT==0x58){    // se contestó al slave
    return I2DAT;
  }
}

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.