CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

i2c_read() CCS Function Problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JH1987



Joined: 22 Jan 2011
Posts: 11

View user's profile Send private message

i2c_read() CCS Function Problem
PostPosted: Wed Jan 26, 2011 1:42 pm     Reply with quote

PIC- 18F4520
Compiler- PCH 4.085

I was playing around with an example I2C master and slave provided by PCM Programmer using two PICs on different PCBs. The examples work great but I discovered a problem with the CCS i2c_read() function. Whether you tell the slave to ACK (i2c_read(), i2c_read(1)) or not ack (i2c_read(0)), the slave still ACKs. I can see this on a logic analyzer- low voltage on 9th clk rising edge of slave address byte. The rest of the transaction looks normal and the master sends both bytes because it believes the slave ACKed. This is the only problem I observed. I'm using 4.7K pull-ups on SCL/SDA. This should be adequate for 100KHz and 400KHz modes, and I do see the problem in both modes.

Here is the modified version of PCM Programmer's example:

Master:

Code:
/*
   I2C Master Test Program
   For Use on the PICDem 2 Board
*/
#include <18F4520.h>
#device PASS_STRINGS = IN_RAM
#include "fuses.h"

#use delay(INTERNAL=8M, clock=16M)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#use i2c(Master, sda=PIN_C4, scl=PIN_C3, Fast)
   
#define SLAVE1_WRITE_ADDR 0x12
#define SLAVE1_READ_ADDR  0x13

//====================================
void main()
{
int8 data;

while(1)
  {
   /*i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   delay_ms(50);
   data = i2c_read(0);
   i2c_stop();

   printf("read %X \r\n", data); */

   i2c_start();
   if(i2c_write(SLAVE1_WRITE_ADDR)==0) {
      delay_ms(50);
         i2c_write(0xAA);
      delay_ms(50);
   }
   i2c_stop();

   delay_ms(100);
  }

}



Slave:

Code:
/*
   I2C Slave Test Program
   For Use on the PICDem 2 Board
*/
#include <18F4520.h>
#device PASS_STRINGS = IN_RAM
#include "fuses.h"

#use delay(INTERNAL=8M, clock=16M)

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#use i2c(Slave, SDA=Pin_C4, SCL=Pin_C3, address=0x12, Fast)

#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;

state = i2c_isr_state();
   
if(state < 0x80)     // Master is sending data
  {
   //incoming = i2c_read(); 
   printf("State= %X, Read %X\r\n",state,i2c_read(0));
  }

if(state >= 0x80)   // Master is requesting data from slave
  {
   i2c_write(0x55);
  }

}


//======================================
void main () {
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);
      
   while(1)
         delay_ms(500);
}



Anyone know what could be happening?

Thanks for your time.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jan 26, 2011 2:32 pm     Reply with quote

This diagram for a "Slave Receiver" shows that it does an ACK on
every byte that it gets from the master:
Quote:

FIGURE 15-8: I2C SLAVE MODE TIMING WITH SEN = 0 (RECEPTION, 7-BIT ADDRESS)

From the 18F452 data sheet on page 140 (pg. 142 in the Acrobat reader):
http://ww1.microchip.com/downloads/en/DeviceDoc/39564c.pdf



The i2c spec (vs. 2.1) says a receiver must ACK each byte that it gets:
Quote:

7.2 Acknowledge

Usually, a receiver which has been addressed is obliged to
generate an acknowledge after each byte has been
received, except when the message starts with a CBUS
address (see Section 10.1.3).

See page 10 in the i2c spec (in the column on the right side):
http://www.nxp.com/acrobat_download2/literature/9398/39340011.pdf
JH1987



Joined: 22 Jan 2011
Posts: 11

View user's profile Send private message

Mediocre CCS Documentation
PostPosted: Wed Jan 26, 2011 6:34 pm     Reply with quote

Thanks for the info. The NXP spec is helpful. I also just learned from skimming it that I2C reserves certain addresses.

But CCS really should have made it clear that only the master can NAK in their manual. Its obvious that the master would NAK to tell the slave not to write any more bytes out and end the slave -> master write transaction. But it also seemed reasonable that the slave could NAK the master to abort the master -> slave write process, like the way a failure in full duplex rs232 will cause a lot of chips to bail on a transaction. The only reason you can't do that is because the PIC firmware locks you into it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Thu Jan 27, 2011 5:46 am     Reply with quote

Not firmware. Hardware....
It is the slave hardware that generates this.
You can actually trigger a NACK, by setting the SSPOV bit on most of the PIC MSSP's (no warranty that this works on all.....). Or, by not reading the character from the input, and manually releasing the clock (CKP bit). You will then need to have 'recovery' code on the slave, to get the hardware out of the 'overflow' condition.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group