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 support@ccsinfo.com

I2C read problem with PIC18LF14K22

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



Joined: 25 Mar 2010
Posts: 4
Location: USA

View user's profile Send private message AIM Address

I2C read problem with PIC18LF14K22
PostPosted: Thu Mar 25, 2010 2:40 pm     Reply with quote

I am having trouble doing an I2C read with the PIC18LF14K22.
My I2C sniffer says the transaction is correct (reads 0x01) but the i2c_read() function returns 0x00.
See the code below.
My compiler version is 4.103.

Code:

#include <18LF14K22.h>

#fuses   INTRC_IO, NOWDT, NOPUT, NOMCLR, NOPROTECT, NOCPD, BROWNOUT
#use delay (internal=4M) // 4 MHz clock
#use i2c(MASTER, SDA=PIN_B4, SCL=PIN_B6, fast=10000, force_sw)

#byte ADCON0   = 0xFC2
#byte WPUB      = 0xF78
// Pin definitions.............................................................
#define pTP15      pin_a0   // TP15
#define pTP16      pin_a1   // TP16
#define lcd_sleep   pin_a2
#define i2c_bad      pin_a4   // TP17
#define dis_33      pin_a5   // disables 3.3V when high

#define dec_pdn      pin_b5   // high = TW8816 in power down
#define asic_pdn   pin_b7   // high = power down for GBE ASIC

#define en_vss      pin_c0   // high = VSS power supply enabled
#define en_bl      pin_c1   // high = backlight enabled
#define en_power   pin_c2   // high = power supplies enabled
#define asic_rst   pin_c3   // low = resets GBE ASIC

#define dec_rst      pin_c6   // low = resets TW8816
#define fpga_rst   pin_c7   // low = resets FPGA

#define dec_slave    0x8A   // dec slave address
#define dec_reg1   0xff
#define dec_reg2   0x02
#define   dec_data1   0x00
#define   dec_data2   0x01

// Global variables............................................................
int mode = 0;            // 0/1: 3d/2d Mode Control

// Functions...................................................................
int1 my_i2c_write(int8, int8, int8);

// Start of Main...............................................................
void main()
{
   //PROCESSOR INITIALIZATIONS
   setup_timer_1( T1_INTERNAL | T1_DIV_BY_2 );
   setup_adc_ports (NO_ANALOGS);
   ADCON0 = 0x00;
   WPUB = 0x00;               // weak pull-ups disabled

   //PIN INITIALIZATIONS
   output_low(en_bl);            // disable BL for now
   output_low(lcd_sleep);         // display in sleep mode for now
   delay_ms(20);
   output_high(en_power);      // enables power supplies
   output_low(dis_33);         // enable 3.3V
   output_high(en_vss);      // enables the LVDVSS power supply
   delay_ms(200);
   output_low(dec_pdn);      // decoder not in power-down
   output_low(asic_pdn);      // ASIC not in power-down
   output_low(asic_rst);      // do ASIC reset
   delay_ms(10);
   output_high(asic_rst);      // ASIC not in reset
   output_high(fpga_rst);      // FPGA not in reset
   output_high(dec_rst);      // decoder not in reset
   delay_ms(10);
   output_low(dec_rst);      // decoder in reset
   delay_ms(10);
   output_high(dec_rst);      // decoder not in reset
                        // All other pins default to inputs
   output_low(i2c_bad);      // default is low
   delay_ms(2000);            // GBE needs this delay to load registers

   
   //WRITE I2C TO ASIC (THIS WORKS!)
   while (my_i2c_write(dec_slave, dec_reg1, dec_data1));
   while (my_i2c_write(dec_slave, dec_reg2, dec_data2));

   //MORE PIN ENABLES
   delay_ms(10);
   output_high(lcd_sleep);      // display in normal mode
   delay_ms(10);
   output_high(en_bl);         // enables backlight power
   delay_ms(1000);            // to make probing easier


   //THIS IS THE SECTION THAT DOES NOT WORK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   i2c_start();
   i2c_write(dec_slave);            //write device slave address for write
   i2c_write(dec_reg2);               //bit0 of reg 0x00 is 2D/3D, 0=2D, 1=3D
   i2c_stop();
   delay_us(25);

   i2c_start();
   i2c_write(dec_slave+1);   //write device slave address for read
   delay_us(100);
   mode = i2c_read(0);          //store in 8 bit variable, the (0) means the
                        // nack after read, use (1) for multiple reads
   i2c_stop();

   if(mode == dec_data2) {
      output_high(pTP16);
   } else {
      output_low(pTP16);
   }
   //END SECTION THAT DOES NOT WORK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

   for (;;);            //loop here forever
}
//*****************************************************************************
// my_i2c_write
// Variables:    slave = device slave address
//            index = index location of the register data
//            data = register settings to be written
// Returns: 0/1 = ACK/NACK
// sends a stop condition if the ASIC NACKs (no ACK)
// This routine sends a stop condition if the ASIC NACKs
//*****************************************************************************
int1 my_i2c_write(int8 slave, int8 index, int8 data)
{
  int1 nack = 0;               //bit for testing if nack received

  i2c_start();                  //send start bit
  nack = i2c_write(slave);         //write device slave address return nack
  if (nack == 1) {               //nack?
    i2c_stop(); return 1; }         // yes, send stop and return w/ 1
  nack = i2c_write(index);         //write register address and return nack
  if (nack == 1) {               //nack?
    i2c_stop(); return 1; }         // yes, send stop and return w/ 1
  nack = i2c_write(data);         //write register data and return nack bit
  if (nack == 1) {               //nack?
    i2c_stop(); return 1; }         // yes, send stop and return w/ 1
  i2c_stop();                  //send stop bit

  return 0;                     //no nacks along the way, return 0
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 25, 2010 11:04 pm     Reply with quote

Instead of starting with the ASIC as the slave, try using a more
conventional i2c slave, such as a 24LC256 eeprom. Prove that
you can make the 18LF14K22 talk to the eeprom. Then try your ASIC.

Also, if the ASIC is a commercially available part, you could post
the manufacturer and part number.
dcosta



Joined: 25 Mar 2010
Posts: 4
Location: USA

View user's profile Send private message AIM Address

PostPosted: Fri Mar 26, 2010 7:16 am     Reply with quote

My I2C sniffer says the ASIC is replying properly.
Also, there are 2 other devices on the board that I can write to but not read from. Clearly the problem is with the PIC.
kopin



Joined: 18 Dec 2008
Posts: 3

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 9:04 am     Reply with quote

I work with dcosta.

To clarify: one of the other devices on the board that we cannot read from is another PIC running a hardware slave. As with the ASIC, the actual I2C bits look okay on the scope and with the sniffer, the i2c_read() function just always returns 0x00.
dcosta



Joined: 25 Mar 2010
Posts: 4
Location: USA

View user's profile Send private message AIM Address

PostPosted: Mon Mar 29, 2010 9:41 am     Reply with quote

Has anyone done I2C reads with this PIC?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Mar 29, 2010 2:18 pm     Reply with quote

Quote:

My I2C sniffer says the ASIC is replying properly. Also, there are
2 other devices on the board that I can write to but not read from.
Clearly the problem is with the PIC.

One of the 3 devices could be responding incorrectly, and it could be
affecting the i2c bus when you attempt to access the other two devices.

Create a hardware test setup, wherein your PIC is only connected to
one "known good" device, such as a 24LC256 eeprom. Test if you
can write and read from this device. If it fails, it will be far easier to
troubleshoot the PIC problem with one known-good slave, instead
of 3 slaves of unknown worthiness.
dcosta



Joined: 25 Mar 2010
Posts: 4
Location: USA

View user's profile Send private message AIM Address

PostPosted: Wed Mar 31, 2010 11:13 am     Reply with quote

I got it to work by only changing from software to hardware I2C.
Luckily I had used the SDA and SCL pins.
Is there any reason the software (bit bang) I2C would not work?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Mar 31, 2010 1:06 pm     Reply with quote

It's possible there is a bug in the CCS software i2c code for that PIC and
that compiler version. Or, there may be a silicon bug with the SDA and
SCL pins, so they are not completely available as ordinary i/o pins on
that PIC. Or, it may be a CCS configuration code bug.

To find the answer, I would have to spend 30 to 60 minutes analyzying
the .LST file, the errata sheets, and the data sheet. Since you have
something that works, it's not worth it for me to spend the time on it.
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