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

Strange I2C vs. 24LC256 problem!

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



Joined: 15 Jun 2010
Posts: 4
Location: Denmark

View user's profile Send private message MSN Messenger

Strange I2C vs. 24LC256 problem!
PostPosted: Fri Sep 17, 2010 5:58 am     Reply with quote

Hi all

I am currently working on a x,y-plotter based on four 18F2680, a µALFAT USB host controller and a 24LC256 eeprom. Until now i've been writing working i2c functions and respective slave-interrupts. I've now added the eeprom, and i'm using the ccs driver.

My problem: I can write and read as much data to/from the eeprom as i want without any problems. But after 24 writes, my slave i2c functions aren't working anymore?!

I've verified that the master is generating the pulses on SCL and SDA, but the slaves aren't somehow acknowledging this after the 24 eeprom writes. I can send as much data i want using these i2c functions, without writing to the eeprom...

All pics are running 8Mhz (internal osc) with i2c in standard-mode (HW). Pull-ups are 1.8kOhm. Im using MPLAB IDE v8.43, PicKit2 and CCS compiler.

i2c master:
Code:

void i2c_x_send_mode(int mode)           
{                                             
i2c_start();
i2c_write(x_adr);
i2c_write(mode);
i2c_stop();
}

void i2c_x_send_speed(int mode, int speed_msb, int speed_lsb)           
{                                             
i2c_start();
i2c_write(x_adr);
i2c_write(mode);
i2c_write(speed_msb);
i2c_write(speed_lsb);
i2c_stop();
}


void i2c_x_send_data(int mode1, int dir, int angle_factor, int x_drive_msb, int x_drive_lsb, int mode2)           
{                                             
i2c_start();
i2c_write(x_adr);
i2c_write(mode1);
i2c_write(dir);
i2c_write(angle_factor);
i2c_write(x_drive_msb);
i2c_write(x_drive_lsb);
i2c_write(mode2);
i2c_stop();
}

void i2c_y_send_mode(int mode)           
{                                             
i2c_start();
i2c_write(y_adr);
i2c_write(mode);
i2c_stop();
}

void i2c_y_send_speed(int mode, int speed_msb, int speed_lsb)           
{                                             
i2c_start();
i2c_write(y_adr);
i2c_write(mode);
i2c_write(speed_msb);
i2c_write(speed_lsb);
i2c_stop();
}


void i2c_y_send_data(int mode1, int dir, int angle_factor, int y_drive_msb, int y_drive_lsb, int mode2)           
{                                             
i2c_start();
i2c_write(y_adr);
i2c_write(mode1);
i2c_write(dir);
i2c_write(angle_factor);
i2c_write(y_drive_msb);
i2c_write(y_drive_lsb);
i2c_write(mode2);
i2c_stop();
}


void i2c_io_send_mode(int mode)           
{                                             
i2c_start();
i2c_write(io_adr);
i2c_write(mode);
i2c_stop();
}

void write_ext_eeprom(long address, int data)
{
   short int status;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_write(data);
   i2c_stop();
   i2c_start();
   status=i2c_write(0xa0);
   while(status==1)
   {
   i2c_start();
   status=i2c_write(0xa0);
   }
   i2c_stop();
   delay_us(10);
}


int read_ext_eeprom(long address) {
   int data;
   i2c_start();
   i2c_write(0xa0);
   i2c_write(address>>8);
   i2c_write(address);
   i2c_start();
   i2c_write(0xa1);
   data=i2c_read(0);
   i2c_stop();
   return(data);
}


i2c slaves:
Code:

void i2c_data_handler()
{
int recieve_buffer = 0;
state = i2c_isr_state();
recieve_buffer = i2c_read();
if(state == 1) {mode = recieve_buffer;}
if(state == 2 && mode == 3) {buffer1 = i2c_read();}
if(state == 3 && mode == 3) {buffer2 = i2c_read();}
if(state == 2 && mode == 12){dir = recieve_buffer;}
if(state == 3 && mode == 12){buffer1 = recieve_buffer;}
if(state == 4 && mode == 12){buffer2 = recieve_buffer;}
if(state == 5 && mode == 12){buffer3 = recieve_buffer;}
if(state == 6 && mode == 12){mode = recieve_buffer;}
}

#INT_SSP
void I2C_interrupt()
{
i2c_data_handler();
}


Thanks on behalf!

Greetings
Steven
_________________
Steven Follmann
steven@follmann.dk
Bachelor Student Electronics
Technical University Of Denmark
@ Unigreen International ApS
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 17, 2010 10:52 am     Reply with quote

If the 18F2680 is talking to a 24LC256, this means the PIC is the i2c
Master, which means it does not need the #int_ssp interrupt routine.

Also, you're writing your own 24LC256 driver and that will probably
create bugs in the code. You should use an existing, working driver.
Here's the CCS driver location:
Quote:
c:\program files\picc\drivers\24256.c
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Sep 18, 2010 2:46 am     Reply with quote

I think he is talking about having four slave devices on the one I2C bus. A EEPROM, and three separate slave PICs.

Presumably the int_ssp, if for the slave PICs.

What are the addresses involved?. You use presumably 'defined' values, as 'x_addr', 'y_addr', and 'io_addr'. If these are 'defines', then switch to the 'C' standard, and use capitals for these. If they are not defines, but variables, are you sure the values are remaining correct...

Why, oh why, have the recieve code as a separate routine?. Does this imply you are calling this from somewhere else as well?. If so, then this could be the problem.
Post the I2C setup lines for each slave, the addresses used etc..

Best Wishes
StevenO



Joined: 15 Jun 2010
Posts: 4
Location: Denmark

View user's profile Send private message MSN Messenger

PostPosted: Sun Sep 19, 2010 1:54 pm     Reply with quote

Thanks for answering Ttelmah! First of all you've read my thread correct, and corrected PCM programmer in the right direction as well!

I am using a PIC18F2680 as i2c master for three PIC18F2680 slaves, the eeprom and a USB host controller. The adresses are defined as:

Code:

int y_adr = 0x12;         //I2C adress for Y-motor PIC
int x_adr = 0x16;         //I2C address for X-motor and lane PIC
int io_adr = 0x14;         //I2C adrress for IO PIC


So i am not using 'defines' for these addresses (bad or good?!). The i2c setups are:

Code:

#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#use i2c(slave, address=0x14, sda=PIN_C4, scl=PIN_C3)
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=0x12)
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=0x16)


All config pins on the eeprom are grounded (A0,A1,A2), so the i2c address is: 0xA0. The i2c address for the USB host controller is 0xA4 (un-changeable).

I only made my recieve-routine seperate because I thought was 'doing too much' staying in the interrupt (i guess i'm not?). The routine posted, is the same for all the PIC slaves. I'm not calling i2c_data_handler elsewhere than the interrupt!

The eeprom routines are the exact same as from the CCS written driver.

I simply can't understand why i'm able to write (use the write routine) exactly 24 times before my i2c bus/functions/behaviour is acting wierd?! As mentioned i've scop'ed the i2c lines and they are both high (4,x volt) after the 24 writes, indicating the bus is acting normally regarding hardware (i guess?).

Do I have to use a delay between the writes? I'm supposing the while-loop in the write routine is taking care of this?

I could REALLY use the eeprom in the setup, due to a lot of things. I'm handing in my thesis/report on this project in 3 weeks Shocked

Best wishes to all, and again thanks Ttelmah!!!
_________________
Steven Follmann
steven@follmann.dk
Bachelor Student Electronics
Technical University Of Denmark
@ Unigreen International ApS
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