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

dual HW I2C on 18F23K22

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



Joined: 26 Nov 2008
Posts: 8

View user's profile Send private message

dual HW I2C on 18F23K22
PostPosted: Thu Jan 09, 2014 2:48 pm     Reply with quote

I've got a 18F23k22 that i want to use the HW i2c ports. One used for an eeprom ( master ) the other for communications ( slave ). I can't seem to get it to work properly. The master never gets enabled ( SSPEN ). I contacted CCS and they said to use the I2C_INIT functions but I'm not sure how that is done. Has anyone else used the dual I2C ports? Has anyone got them to work. Any help would be appreciated.
Code:

#include <18F23K22.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES BROWNOUT               //brownout reset
#FUSES BORV29                   
//#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                 
#Fuses PLLEN
#fuses intrc_IO
#device ICD=TRUE
#use delay(int=64MHz,restart_wdt)
#use fast_IO(B)
#use fast_IO(A)
#use fast_IO(C)
#use i2c(Slave,Fast,I2C1,restart_wdt,force_hw,address=0x20,stream=com)
#use i2c(Master,Fast,I2C2,restart_wdt,force_hw,stream=eemem)

#define EEPROM_SCL pin_B1
#define EEPROM_SDA pin_B2
#define i2c_eemem_address 0xa0


#ZERO_RAM
#opt 11

#int_ssp
void int_ssp()
{
//!   int8 i;
//!   i2c_write(com,0);
   clear_interrupt(int_ssp);
}

void main()
{
   int8 data;
   set_tris_a (0x00); // a0, a1, a2, a3, a4 as outputs
   set_tris_b (0x07); // b0 through b2 as inputs
   set_tris_c (0x98); // c3 and c4 as inputs
   output_c (00);
   output_B (00); //set the pwm outputs all low
   output_A (00);
   i2c_init(eemem,1);
   i2c_init(com,1);
   init_ext_eeprom();
   data=read_ext_eeprom(0xA0,0);
   enable_interrupts(int_ssp);
   enable_interrupts(global);
}

// And the modified 24256 code

///////////////////////////////////////////////////////////////////////////
////   Library for a 24LC256 serial EEPROM                             ////
////                                                                   ////
////   init_ext_eeprom();    Call before the other functions are used  ////
////                                                                   ////
////   write_ext_eeprom(a, d);  Write the byte d to the address a      ////
////                                                                   ////
////   d = read_ext_eeprom(a);   Read the byte d from the address a    ////
////                                                                   ////
////   The main program may define eeprom_sda                          ////
////   and eeprom_scl to override the defaults below.                  ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////
//// This source code may only be used by licensed users of the CCS C  ////
//// compiler.  This source code may only be distributed to other      ////
//// licensed users of the CCS C compiler.  No other use, reproduction ////
//// or distribution is permitted without written permission.          ////
//// Derivative programs created using this software in object code    ////
//// form are not restricted in any way.                               ////
///////////////////////////////////////////////////////////////////////////


//#ifndef EEPROM_SDA

//#define EEPROM_SDA  PIN_B1
//#define EEPROM_SCL  PIN_B0

//#endif

//#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE   65536

void init_ext_eeprom()
{
   output_float(EEPROM_SCL);
   output_float(EEPROM_SDA);

}
   
void write_ext_eeprom(int8 wa, long int address, BYTE data,int8 check)
{
   
   short int status;
   i2c_start(eemem);
   wa=wa & 0xfe; // make sure r/w bit is low
   i2c_write(eemem,wa);
   i2c_write(eemem,address>>8);
   i2c_write(eemem,address);
   i2c_write(eemem,data);
   i2c_stop(eemem);
   if (check==1)
   {
      i2c_start(eemem);
      status=i2c_write(eemem,wa);
      while(status==1)
      {
         i2c_start(eemem);
         status=i2c_write(eemem,wa);
      }
      i2c_stop(eemem);
   }
}
void write_ext_eeprom_page(int8 wa,long int address, int8 *data,int8 length)
{
   short int status;
   int8 i;
   int8 value;
   i2c_start(eemem);
   wa=wa & 0xfe; // make sure r/w bit is low
   i2c_write(eemem,wa);
   i2c_write(eemem,address>>8);
   i2c_write(eemem,address);
   for( i=0;i<length;i++)
   {
      value=*data;
      i2c_write(eemem,value);
      data++;
   }
   i2c_stop(eemem);
   i2c_start(eemem);
   status=i2c_write(eemem,wa);
   while(status==1)
   {
      i2c_start(eemem);
      status=i2c_write(eemem,wa);
   }
   i2c_stop(eemem);
}


BYTE read_ext_eeprom(int8 wa,long int address)
{
   BYTE data;
   i2c_start(eemem);
   wa=wa & 0xfe; // make sure r/w bit is low
   i2c_write(eemem,wa);
   i2c_write(eemem,address>>8);
   i2c_write(eemem,address);
   i2c_start(eemem);
   i2c_write(eemem,wa+1);
   data=i2c_read(eemem,0);
   i2c_stop(eemem);
   return(data);
}

void read_ext_eeprom_page(int8 wa,long int address, int8 *data,int8 length)
{
   int8 i;
   i2c_start(eemem);
   wa=wa & 0xfe; // make sure r/w bit is low
   i2c_write(eemem,wa);
   i2c_write(eemem,address>>8);
   i2c_write(eemem,address);
   i2c_start(eemem);
   i2c_write(eemem,wa+1);
   for( i=0;i<length-1;i++)
   {
      *data=i2c_read(eemem,1);
      data++;
   }
   *data=i2c_read(eemem,0);
   i2c_stop(eemem);
   return;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 09, 2014 3:30 pm     Reply with quote

I don't think you need to use streams. The CCS #use i2c() parameters
stay in effect for all i2c code called after that line, until a new #use i2c()
line is encountered by the compiler. This is stated in the CCS manual.

So, you can place the #include for the 24LC256 driver first. It contains
its own #use i2c() line, which you can edit. You should probably make
a local copy of the 24256.c driver file and put it in your CCS project folder.
Then edit that file and #include it. Rename it as shown below.

After that point, you can put in the #use i2c() line for your i2c slave, and
follow it with the slave interrupt routine.

Here is an outline of how to do this:
Code:

#include <18F23K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M)

// Edit the following file and change only the #use i2c() line to:
// #use i2c(Master,Fast,I2C2,Force_hw)
#include "my24256.c"

//----------------------------
// i2c slave code:

#use i2c(Slave,I2C1,address=0x20)

unsigned int8 address, buffer[16];

#int_ssp
void ssp_interrupt()
{
unsigned int8 incoming, state;

state = i2c_isr_state();

.
.
.
// Put in code from CCS Ex_slave.c example file here
.
.
}

//=======================================
void main()
{
write_ext_eeprom(0, 0x55);

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while(1);
}


Your posted code has a large number of newbie mistakes, such as
overriding the TRIS on hardware i2c pins (setting them to low-level
outputs when the compiler has already set them to be inputs).
Also you let your code fall off the end of main(). Also you put return
statements at the end of functions that don't return a value. All functions
automatically return anyway. Also, you have set it to #opt 11. I wouldn't
do that. Changing the #opt will cause more bugs than you need.
#zero_ram is probably not needed.

The most important advice is to first get each i2c bus working separately.
Make the master program. Prove that it works. Make the slave program
(without any master code). Prove that the slave works. Then combine
them as shown above.
tems



Joined: 26 Nov 2008
Posts: 8

View user's profile Send private message

PostPosted: Fri Jan 10, 2014 2:47 pm     Reply with quote

This code was chopped from a fairly large single I2C master program 4000+ lines. Its been used for many years and adapted to the newer pics. When do you need to use streams. I'm an example person so if there is an example dual HW i2c it would help a bunch.
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