I2C on two different Tiles

If you have a simple question and just want an answer.
shaw
Active Member
Posts: 43
Joined: Fri Mar 25, 2011 12:36 am

I2C on two different Tiles

Post by shaw »

I'm using the XU316 1024 for a new project. The project has some constraints which require I2C on both tiles. What is the suggested approach to running I2C on each of the two tiles. Both I2C will be unique masters and both tiles will be using their own 1 pin ports for SDA and SCL.

Is it advisable to use the same lib_i2c on both tiles and just rename one of the libs?

Thanks


User avatar
fabriceo
XCore Addict
Posts: 186
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi
you don't need to duplicate files just include the library in each of your source code

in the current version, I2C master is a distributable task and you will have to launch 1 instance on each tile and use the interfaces to read and write registers. These interfaces could be called from any other task on the same tile;

if you want a basic version without using task and interfaces, you can look a previous version like the one in the sw audio usb 6.15.2.
shaw
Active Member
Posts: 43
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

Hi Fabriceo,

"you don't need to duplicate files just include the library in each of your source code". How do you include the library so that it is accessible from the source code in each of the two different tiles?

Thanks,
User avatar
fabriceo
XCore Addict
Posts: 186
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hello
the linker is doing the magic : it generates 2 binaries , 1 for each tile, including the code and data which are used within the tile.
the 2 binaries are included in the .xe file and loaded one by one for each tile during boot.

just do a test : create a file.c and file.h with a simple routine like add(int x, int y).
then create a main.xc with main() and 2 tasks in a par statement. just print something using add(). it works.
you can use a single library in 2 tiles. there is 2 instances of the add() routines.

regarding accessing the i2c master routines, you will declare client interfaces for each task requiring I2C access.
the compiler will automatically instantiate as much elementary code as needed for each client interface callers.

I sujest you create a simple application just with this 2 master program to put your hands on this mechanism, before you integrate them in the large application...

Also I was suggesting a simple older library, as this interface mechanisms requires some study and practice :)
shaw
Active Member
Posts: 43
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

I will try this out and let you know how it goes. Thank-you for the help.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

It's very simple. That's the power of client-server model.

Here is the code I use:

customdefines.h

Code: Select all

#define USER_MAIN_DEFINES on tile[ports_tile]: port p_i2c_sda = PORT_I2C_SDA; \
on tile[ports_tile]: port p_i2c_scl = PORT_I2C_SCL;

// Declare a i2c server. 

#define USER_MAIN_DECLARATIONS i2c_master_if i_i2c[num_of_clients];

// Then use calls in you code: i_i2c[0] ... i_i2c[num_of_clients-1].

#define USER_MAIN_CORES i2c_master(i_i2c, num_of_clients, p_i2c_scl, p_i2c_sda, 100); \
on tile[AUDIO_IO_TILE]: usb_audio_io(c_mix_out, c_adc, c_aud_cfg, c_spdif_rx, c_adat_rx, dfuInterface, i_i2c[0]);
...
I am using macro to share main.xc in multiple USB Audio projects.
shaw
Active Member
Posts: 43
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

Okay, thanks for all the feedback. I believe that I have two options:

Option A: Use one I2C server (Master Synchronous server with 2 clients): Server will be loaded on Tile 0, and will use i2c_sda and i2c_sda pins also on on Tile 0.
There will be one client on Tile 0 and one client on Tile 1. Both clients will access the server on Tile 0.

Option B: Use two I2C servers (Both would be Master Synchronous servers each with 1 client): One server will be loaded on Tile 0 and will use the i2c_sda and i2C_sda pins on Tile 0.
The second server will be on Tile 1 and will use the i2c_sda and i2C_sda pins on Tile 1.
One client will be on Tile 0 and access the server on Tile 0. One client will be on Tile 1 and access the server on Tile 1.

Two questions:
1: Am I correct in saying that these two optios are both viable as described?

2: With option B, the blocking mechanism is clear. When a client access of a server is underway, that client task will block, until the xmission is complete. No problem, no shared resource.
With Option A, the blocking mechanism is not so clear to me; What happens when if a client 1 transmit is under way, client 1 blocks AND then if client 2 tries to access the same server. Will that create a problem that must be prevented from happening, with some type of locking/semaphore resource sharing mechanism?

Thanks
User avatar
fabriceo
XCore Addict
Posts: 186
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi Shaw,
options A and B seems OK, but as you describe option A, it uses only one I2C master on 2 one-bits ports, while option B has 2 Master with 4 one bits ports.
if your hardware design can accommodate a single I2C bus then go with option A.

The blocking mechanism of option A is same as B : when an I2C transaction will be in progress, the client will wait for it to complete (synchronous behaviour) and if another client calls for a transaction it will be blocked until the current transaction is finished. You can see in the source code of i2c lib some guarding cases and locking mechanisms depending on client number.
Also note that the I2C task is distributable meaning it doesn't need its own core and you can use a single core to run multiple distributable/combinable tasks. (e.g. you could combine I2C with rotary encoder or GPIO access across tiles). in fact in this library the concept of tasks is only used to share a process across multiple client across tiles (which is quite powerful by the way).
shaw
Active Member
Posts: 43
Joined: Fri Mar 25, 2011 12:36 am

Post by shaw »

Hi Fabriceo,

Thank-you. That really cleared it up.
MaximLiadov
XCore Addict
Posts: 130
Joined: Mon Apr 16, 2018 9:14 am

Post by MaximLiadov »

BTW. The latest lib_i2c versions on GitHub provide an additional asynchronos mode, function i2c_master_async. So a client is not blocking as I presume. I like this idea, but I keep using old i2c 4.0 due to some timing issue with my hardware ICs. I did not tested the latest 6.0 though.