View previous topic :: View next topic |
Author |
Message |
Matro Guest
|
Issue with "i2c_write()" return value |
Posted: Thu Feb 14, 2008 9:51 am |
|
|
Hi everybody,
I've got some problems with the return value of the i2c_write() function.
According to the help file of CCS the return value is the ACK state coming after the write with following meanings :
0x00 : byte has been acknowledged by master
0x01 : byte has not been acknowledged
My problem is that the function returns 0x01 although the byte has been acknowledged by the master (I checked with a scope).
I saw that in the generated asm the code was checking the CKP bit to know if the transfer has been ACK or not.
Do somebody know how to solve this problem?
Is it possible that the code is too "fast" and check the CKP bit before the i2c driver update it?
Thanks in advance for your answers.
Matro. |
|
|
Matro Guest
|
|
Posted: Thu Feb 14, 2008 10:07 am |
|
|
Some more information :
The target is a PIC16F88 and I use CCS 4.057.
Matro. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 14, 2008 11:55 am |
|
|
Quote: | The target is a PIC16F88 and I use CCS 4.057. |
The CCS manual and help file for vs. 4.xxx says this:
Quote: |
i2c_write
Returns:
This function returns the ACK Bit. 0 means ACK, 1 means NO ACK,
2 means there was a collision if in Multi_Master Mode.
|
Here's the current manual:
http://www.ccsinfo.com/downloads/CReferenceManual.pdf
1. Post a very short (but complete) program that shows the problem.
2. Post the part number of the slave device, and a description of it.
(Make sure that you "Disable HTML" when you post your code. There is a
tickbox to do this just below the post editing window). |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Thu Feb 14, 2008 12:01 pm |
|
|
Just an FYI, during an i2c_write() the ACK is generated by the slave. During an i2c_read() the ACK(default), is generated by the master. An i2c_read(0) tells the master to generate a NOACK, which tells the slave that it is finished reading data.
Ronald |
|
|
Matro Guest
|
|
Posted: Fri Feb 15, 2008 2:46 am |
|
|
Thanks for your answers. Appreciate it!
@PCM PROGRAMMER
- I have the same help file. But in my case it is a single master bus so the return value 0x02 will never be used. ;-)
- The slave device is the PIC16F88 itself (this part has only a slave driver)
- I will post a few lines of code that will allow to generate the problem. But you will need a scope to see the signals. :-)
@rnielsen
- Given that the slave device is the PIC16F88 I really think that when it does a i2c_write() the ACK is generated by the master.
@everybody ;-)
All my I2C bus is working very fine (at the physical level) and the transfers too. Even in the cases of multi-byte write / multi-byte read / repeated start / ...
The only problem is that I need to have a different behavior according to an ACK or NACK from the master when my PIC16F88 answer to a read request. And currently the return value of the i2c_write() function is always 0x01 even if the master well acknowledged the byte. ;-)
Thanks for the help you gave and you will give (I hope)
Matro
PS : because of the time difference between us I can be some hours without answering to you. Don't think I'm no more interested in. I'm just sleeping! |
|
|
Matro Guest
|
Sample code |
Posted: Fri Feb 15, 2008 3:07 am |
|
|
Below is a sample code that will create the problem (as any code answering to a master read) :
Code: |
#include <16F88.h>
#FUSES NOWDT //Watch Dog Timer (The WDT is not activated because it could be soft dis/en-abled. If it is activated it can't be soft controlled and is always enabled)
#FUSES INTRC_IO //Internal RC Osc
#FUSES NOPUT //No Power Up Timer
#FUSES MCLR //Master Clear pin enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES CCPB3 //CCP pin = B3
#use delay(clock=8000000)
#use i2c(Slave,Slow,sda=PIN_B1,scl=PIN_B4,restart_wdt,force_hw,address=0x4C)
#define LED PIN_A4
#int_SSP
void SSP_isr(void)
{
BYTE I2C_status; //internal I2C HW status
I2C_status = i2c_isr_state(); //get status of internal I2C HW
if(I2C_status >= 0x80) //if host is reading
{
if(i2c_write(0xAA) == 0x00) //send the register value
{
output_high(LED); //master ACK
}
else
{
output_low(LED); //master NACK
}
}
else
{
i2c_read(); //update register
}
}
void main(void)
{
setup_oscillator(OSC_8MHZ|OSC_INTRC);
output_low(LED);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(1);
}
|
Matro |
|
|
|