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

Use of multiple i2c

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



Joined: 13 Aug 2004
Posts: 58
Location: Turkey

View user's profile Send private message Visit poster's website

Use of multiple i2c
PostPosted: Mon Mar 10, 2014 3:54 am     Reply with quote

Hello,

My question is about multiple use of i2c bus.
is it possible to define more than one i2c bus on a pic with CCS.
I am planning to use a 10 pcs of BH1750 light sensor at once. But the BH1750 has only 2 address meaning that I can use only 2 sensor on only one i2c bus.
How to use multiple i2c on CCS.

best regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Mon Mar 10, 2014 4:40 am     Reply with quote

Yes.
#USE I2C, just like #USE RS232, supports streams.
You can define as many I2C busses as you have pin pairs!.
CCS can develop master software I2C on any pins (provided they are not already doing something else).
Key is that once you use streams, you have to remember to use them everywhere. So i2c_start(), becomes i2c_start(your_first_stream) etc..
Each write, read, start, stop, needs the stream name added.
If you look at the manual entries for #USE I2C, and for each of the I2C functions, you will see the optional stream name entries.

Best Wishes
scanan



Joined: 13 Aug 2004
Posts: 58
Location: Turkey

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 10, 2014 8:14 am     Reply with quote

Ttelmah wrote:
Yes.
#USE I2C, just like #USE RS232, supports streams.
You can define as many I2C busses as you have pin pairs!.
CCS can develop master software I2C on any pins (provided they are not already doing something else).
Key is that once you use streams, you have to remember to use them everywhere. So i2c_start(), becomes i2c_start(your_first_stream) etc..
Each write, read, start, stop, needs the stream name added.
If you look at the manual entries for #USE I2C, and for each of the I2C functions, you will see the optional stream name entries.

Best Wishes


Thanks for your information
as I understand
#use i2c(stream=number1, sda=PIN_B0, scl=PIN_B1)
#use i2c(stream=number2, sda=PIN_B2, scl=PIN_B3)
#use i2c(stream=number3, sda=PIN_B4, scl=PIN_B5)

is it like that?
_________________
Dr Suleyman CANAN
R&D Electronic Engineer
https://suleymancanan.wordpress.com

Do whatever you do with amateur spirit -
But always feel professional.
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Mon Mar 10, 2014 9:23 am     Reply with quote

Yes, but you really need MASTER, and the clock rate required for each stream.
So:
Code:

#use i2c(stream=number1, sda=PIN_B0, scl=PIN_B1, MASTER, FAST=400000)
#use i2c(stream=number2, sda=PIN_B2, scl=PIN_B3, MASTER, FAST=400000)
#use i2c(stream=number3, sda=PIN_B4, scl=PIN_B5, MASTER, FAST=400000)


Best Wishes
scanan



Joined: 13 Aug 2004
Posts: 58
Location: Turkey

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 10, 2014 10:16 am     Reply with quote

Ttelmah wrote:
Yes, but you really need MASTER, and the clock rate required for each stream.
So:
Code:

#use i2c(stream=number1, sda=PIN_B0, scl=PIN_B1, MASTER, FAST=400000)
#use i2c(stream=number2, sda=PIN_B2, scl=PIN_B3, MASTER, FAST=400000)
#use i2c(stream=number3, sda=PIN_B4, scl=PIN_B5, MASTER, FAST=400000)


Best Wishes


OK Let's give a try Smile
thank you
_________________
Dr Suleyman CANAN
R&D Electronic Engineer
https://suleymancanan.wordpress.com

Do whatever you do with amateur spirit -
But always feel professional.
scanan



Joined: 13 Aug 2004
Posts: 58
Location: Turkey

View user's profile Send private message Visit poster's website

PostPosted: Thu Mar 13, 2014 7:51 am     Reply with quote

Hi,
Have problem passing stream to let say i2c_read(?)
how to pass stream to i2c library, thinkin I am goin to use 10 i2c

I tried something like that:
unsigned int16 e2promtimer=0;
const char s[2][10]={"bus1\0","bus2\0"};
unsigned int8 a,b,c,i,j;

#define EEPROM_SDA1 PIN_C7
#define EEPROM_SCL1 PIN_C6
#define EEPROM_SDA2 PIN_E2
#define EEPROM_SCL2 PIN_E5

#use i2c(master, sda=EEPROM_SDA1, scl=EEPROM_SCL1,stream=bus1,FAST=100000)
#use i2c(master, sda=EEPROM_SDA1, scl=EEPROM_SCL1,stream=bus2,FAST=100000)

the s array will be used to select i2c buses. but unable to pass the array let say to i2c_read(s[0]);

problem with this expression Get "stream must be a constant in the valid range " error

Any suggextions?
_________________
Dr Suleyman CANAN
R&D Electronic Engineer
https://suleymancanan.wordpress.com

Do whatever you do with amateur spirit -
But always feel professional.


Last edited by scanan on Thu Mar 13, 2014 8:28 am; edited 1 time in total
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Mar 13, 2014 8:21 am     Reply with quote

#use_i2c and the related i2c routines are not implemented at runtime. They are done at compile time. You cannot use a variable to select the stream. You must use a constant.

What happens is that the compiler substitutes code, some in-line, for the "calls", rather than the calls calling actual runtime routines. There is no runtime library; the code to be run/called has to be decided by the compiler.

So, the stream isn't a normal parameter. Instead of passing a variable for the stream, you have to do something else like using a switch statement:

Code:

switch (Stream_Select)
{
    case 1:
        i2c_write(First_Stream, Data_Byte);
        break;
    case 2:
        i2c_write(Second_Stream, Data_Byte);
        break;

    ...

    case 10:
        i2c_write(Tenth_Stream, Data_Byte);
        break;
}


Yes, it's not ideal, but it should work.
Ttelmah



Joined: 11 Mar 2010
Posts: 19535

View user's profile Send private message

PostPosted: Thu Mar 13, 2014 9:42 am     Reply with quote

Yes.

You can thought take advantage of macro substitutions to make the actual routines simpler.

As a comment though, since the devices offer two addresses, five streams is all that should be needed.

So (showing just for I2C write):
Code:

typedef enum {I2C1=1,I2C2,I2C3,I2C4,I2C5} streamname;
#define M_I2C_write(n,x) i2c_write(bus##n,x)
//Then these needed for all five busses
#use i2c(master, sda=EEPROM_SDA1, scl=EEPROM_SCL1,stream=bus1,FAST=100000)
#use i2c(master, sda=EEPROM_SDA1, scl=EEPROM_SCL1,stream=bus2,FAST=100000)

int1 I2C_write_multi(streamname st, int8 val)
{
   switch (st)
   {
   case I2C1:
      return M_I2c_write(1,val);
   case I2C2:
      return M_I2c_write(2,val);   
   case I2C3:
      return M_I2c_write(3,val);
   case I2C4:
      return M_I2c_write(4,val);
   case I2C5:
      return M_I2c_write(5,val);
   }
}

//Then to perform and I2C_write to a numbered stream:

   streamname val;
   for (val=I2C1;val<=I2C5;val++)
      i2c_write_multi(val,23); //just a demo of writing '23' to stream 'val'

This minimises the actual typing needed to generate the expansion, and allows you to 'count' streams.

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