|
|
View previous topic :: View next topic |
Author |
Message |
dcosta
Joined: 25 Mar 2010 Posts: 4 Location: USA
|
I2C read problem with PIC18LF14K22 |
Posted: Thu Mar 25, 2010 2:40 pm |
|
|
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
|
|
Posted: Thu Mar 25, 2010 11:04 pm |
|
|
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
|
|
Posted: Fri Mar 26, 2010 7:16 am |
|
|
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
|
|
Posted: Fri Mar 26, 2010 9:04 am |
|
|
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
|
|
Posted: Mon Mar 29, 2010 9:41 am |
|
|
Has anyone done I2C reads with this PIC? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 29, 2010 2:18 pm |
|
|
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
|
|
Posted: Wed Mar 31, 2010 11:13 am |
|
|
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
|
|
Posted: Wed Mar 31, 2010 1:06 pm |
|
|
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. |
|
|
|
|
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
|