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
Log in with Google account
No account? Register here.