Multiple Software I2C

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
animo3d
Posts: 24
Joined: Sun Sep 18, 2011 6:02 am
Location: Monterrey Mexico

Multiple Software I2C

Post by animo3d » Sun Sep 18, 2011 6:13 am

Hi, I'm wondering what's the best way to handle multiple I2C buses, with the microcontroller (trying to save a few bucks on a multiplexer ;) ) just because I have too many idle pins.

I need 4 independent I2C buses (SCK and SDA), an I visualize 3 options:

1.- Get a multiplexer, simple solution, but I don have it, and will take some time for me to get it...

2.- Modifiy SI2C.bas to be able to change the pins every time I need to use a diferent bus...

3.- Duplicate SI2C.bas creating SI2C1.bas, SI2C2.bas etc. an configure each one individually...

please, If any of you have done this before, I will love to hear your ideas...

Thanks in advance...
Sergio

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sun Sep 18, 2011 9:57 am

If you don't want to use the hardware solution then option 3 would be my choice. All it takes is about 30 seconds of editing to change the module name and the '#option I2C_SCL/I2C_SCA' statements and you're done.

There'd be a lot more work involved getting option 2 to work, and you'd probably end up with more code in the end as well.

animo3d
Posts: 24
Joined: Sun Sep 18, 2011 6:02 am
Location: Monterrey Mexico

Post by animo3d » Mon Sep 19, 2011 10:44 pm

I dont need the hardware solution, and I was also leaning for option 3, I know is not the most optimized code but who cares, I have a lot of Flash memory, and looks really simple to me, I just wanted to be sure that is valid to do so..

Thanks Jerry, I will post my results

Regards
Sergio

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Tue Sep 20, 2011 9:48 am

I was also leaning for option 3, I know is not the most optimized code but who cares
Actually, you may be surprised. It will result in a lot of source code but the amount of compiled flash space might well be smaller than the alternative.

Definitely let us know how it goes, Sergio.

animo3d
Posts: 24
Joined: Sun Sep 18, 2011 6:02 am
Location: Monterrey Mexico

Post by animo3d » Tue Sep 20, 2011 11:12 pm

Worked like a charm!!!

I created 3 copies of the library, named the modules SI2C1, SI2C2, and SI2C3.


on every one changed the code for the options:

Example for SI2C2:

Code: Select all

// SCL option...
#if IsOption(I2C_SCL2) And Not IsValidPortPin(I2C_SCL2) 
   #error I2C_SCL2, "Invalid option. I2C clock must be a valid port pin."
#endif
#option I2C_SCL2 = PORTC.3

// SDA option...
#if IsOption(I2C_SDA2) And Not IsValidPortPin(I2C_SDA2) 
   #error I2C_SDA2, "Invalid option. I2C data line must be a valid port pin."
#endif
#option I2C_SDA2 = PORTC.4

// configure SCL and SDA...
Dim
   SCL As I2C_SCL2.I2C_SCL2@,
   SDA As I2C_SDA2.I2C_SDA2@

and configured the options on my main program:

Code: Select all

#option I2C_SCL = PORTC.3
#option I2C_SDA = PORTC.4

#option I2C_SCL1 = PORTB.0
#option I2C_SDA1 = PORTB.1

#option I2C_SCL2 = PORTB.3
#option I2C_SDA2 = PORTB.2

#option I2C_SCL3 = PORTB.5
#option I2C_SDA3 = PORTB.4

Include "usart.bas"
Include "SI2C.bas"
Include "SI2C1.bas"
Include "SI2C2.bas"
Include "SI2C3.bas"

then I just called the bus I need to address: like

SI2C.WriteByte($12) ---> for bus 0
SI2C1.WriteByte($12) ---> for bus 1
SI2C2.WriteByte($12) ---> for bus 2
SI2C3.WriteByte($12) ---> for bus 3

not a problem, working ok...

Jerry, thanks for the insight

Regards
Sergio

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Multiple Software I2C

Post by Jerry Messina » Sun Jun 22, 2014 1:03 pm

I'm working on an application that needs 7 individual I2C ports, so I thought I'd revisit this.

Like Sergio, I have a lot of pins and don't want to add a hardware mux, so instead of making 7 copies of the SI2C module, I decided to try Sergio's option #2 and make the pins programmable.

Using the Shift.bas and SI2C.bas modules as a model, this is what I came up with...

EDIT: code moved to User Modules wiki page http://www.sfcompiler.co.uk/wiki/pmwiki ... User.PSI2C

This lets you define as many I2C ports as you like using '#option PSI2C_NUM_PORTS = x'
(which defaults to one port). Check out the comments at the beginning of the source as to how you would use this.

For a single port, the code ends up about twice the size of the SI2C module, and quite a bit slower.
You don't start to see any advantage in code size until you hit the 3-4 port range, where things
start to even out. Each instance of SI2C takes about 275 bytes, while with PSI2C once you're
using multiple ports the only real difference in code size is the addtional code to define and init
the pins, which is about 60 bytes/port. Did I mention it's slower?

Note that unlike the original SI2C module, you'll need to use a pullup resistor on the SDA line(s) for this one.
If you're using a pin w/programmable internal pullups they should work fine.

User avatar
RangerBob
Posts: 152
Joined: Thu May 31, 2007 8:52 am
Location: Beds, UK

Re: Multiple Software I2C

Post by RangerBob » Mon Jun 23, 2014 10:36 am

Blimey Jerry, that's a very useful and absolutely brilliant library! Many thanks for sharing, should come in useful sometime.

Rangerbob

Post Reply