View previous topic :: View next topic |
Author |
Message |
Markus
Joined: 30 Oct 2003 Posts: 13
|
Is it impossible to poll for ACK with CCSC? |
Posted: Tue Jun 22, 2004 4:37 am |
|
|
Hi all,
I'm going nuts!
Why does this code result in an infinite loop?
Code: |
static void AckPollingI2C(int i2cAddress) {
int1 nack;
i2c_start();
i2c_write(i2cAddress & 0xFE);
nack = 1;
while (nack) {
// repeated start condition
i2c_start();
nack = i2c_write(i2cAddress & 0xFE);
delay_us(500);
}
i2c_stop();
}
|
I do have a repeated start condition
I do have an i2c bus delay
Compiler: 3.180
EEPROMs: Microchip 24LC256, ST M24512W
Any comments appreciated.
Markus |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Jun 22, 2004 4:49 am |
|
|
Maybe because i2c_write(); does not return anything, and nack is always TRUE. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Tue Jun 22, 2004 5:22 am |
|
|
i2c_write does return the ACK condition:
(From the manual)
Quote: |
Syntax: i2c_write (data)
Parameters: data is an 8 bit int
Returns: This function returns the ACK Bit.0 means ACK, 1 means NO ACK.
|
Have you tried the code with only one i2c_start()? |
|
|
Ttelmah Guest
|
Re: Is it impossible to poll for ACK with CCSC? |
Posted: Tue Jun 22, 2004 5:30 am |
|
|
Markus wrote: | Hi all,
I'm going nuts!
Why does this code result in an infinite loop?
Code: |
static void AckPollingI2C(int i2cAddress) {
int1 nack;
i2c_start();
i2c_write(i2cAddress & 0xFE);
nack = 1;
while (nack) {
// repeated start condition
i2c_start();
nack = i2c_write(i2cAddress & 0xFE);
delay_us(500);
}
i2c_stop();
}
|
I do have a repeated start condition
I do have an i2c bus delay
Compiler: 3.180
EEPROMs: Microchip 24LC256, ST M24512W
Any comments appreciated.
Markus |
Try sending an address, before the repeated start. The data sheet, does not show a repeated start being used, except after the address has been sent, or when doing a write operation, and using the ack to poll for the operation completing.
Best Wishes |
|
|
Guest
|
|
Posted: Tue Jun 22, 2004 7:23 am |
|
|
Thank you both for your input!
CCS Help says that i2c_write() returns the ACK bit.
CCS Help wrote: |
This function returns the ACK Bit.
0 means ACK, 1 means NO ACK.
|
I tried sending an adress, but it didn't work.
According to this thread in Microchip's forum it should work without sending an address: http://forum.microchip.com/tm.asp?m=32229&mpage=1
But it doesn't work for me (using CCS C). Seems to be a problem of CCS's built-in i2c functions.
Markus |
|
|
DaFox Guest
|
|
Posted: Tue Jun 22, 2004 7:26 am |
|
|
Oops, Haplo. I missed your message, sorry!
Yep, I also tried one single start. But it doesn't work. See the messages from the link above (Microchip forum).
Markus |
|
|
Ttelmah Guest
|
|
Posted: Tue Jun 22, 2004 7:51 am |
|
|
DaFox wrote: | Oops, Haplo. I missed your message, sorry!
Yep, I also tried one single start. But it doesn't work. See the messages from the link above (Microchip forum).
Markus |
Have you actually tried coding exactly as in the Forum you quote?.
In the forum, you will see that the original poster there, was having exactly the same problem, till he followed the chips data sheet _to the letter_. He had to perform the write operation, send the stop, then sit in a loop, sending the repeated 'start', till the ACK was seen (waiting for the chip to finish writing). In the code you give, you are trying to read the ACK, without having sent the write, and it does appear from the comments in the forum, that the chip does have some 'oddities' in it's handling of the ACK/NACK response. ence you would need to leav the 'loop' as it is, but send the command to write a byte first, followed by the I2C_STOP. Though 'on paper', the chip should acknowledge any transaction, it does not appear to work qite like this....
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Jun 22, 2004 8:41 am |
|
|
This is what I think I would do:
Code: |
int1 AckPollingI2C(int i2cAddress) {
unsigned int8 jnk = 0;
i2c_start();
while (i2c_write(i2cAddress & 0xFE && ++jnk < 100) { // returns a '1' if NOACK
delay_us(500);
}
i2c_stop();
if(jnk < 99)
{
return(1);
}
else
{
return(0);
}
}
|
The Master sends a Start telling all of the devices that it wants control of the I2C bus. It then sends a Write to a device while evaluating the /ACK bit. If the /ACK bit is a NOACK it will then delay 500us and try to send the Write again. This will continue until jnk reaches over 100 which will, basically, time out the function and send it on it's way. The Stop simply releases the I2C bus for other potential Master's to take control. The return statement will tell the rest of your program if a successful /ACK was achieved or not.
Ronald |
|
|
Markus
Joined: 30 Oct 2003 Posts: 13
|
|
Posted: Tue Jun 29, 2004 2:39 am |
|
|
My code above works like a charm. The error was elsewhere in the program.
Sorry for the inconvenience, guys.
Markus |
|
|
|