xCORE 200 MC: r_i2c violates parallel usage rules Topic is solved

Technical discussions related to any XMOS development kit or reference design. Eg XK-1A, sliceKIT, etc.
User avatar
ccrome
Active Member
Posts: 62
Joined: Wed Sep 23, 2015 1:15 am

xCORE 200 MC: r_i2c violates parallel usage rules

Post by ccrome »

Hi there,
I'm using the xCORE 200 MC audio design as the basis of a new audio board. The new audio board shares the I2C bus with the analog codecs (different codecs from the ones on the MC board).

My question is: how do I get the volume command (which comes in from endpoint0), to change registers in the codec?

The current problem is:

endpoint0 is on tile[XUD_TILE] but the i2c bus is on AUDIO_IO_TILE. So, the problem would appear to be solved by creating an interface where endpoint0 calls an interface method over to the AUIO_IO_TILE.

However, the thread that holds the reigns to r_i2c (the i2c ports), is the 'audio' thread because it's what calls AudioHWInit, etc.

But the audio thread doesn't seem to have a select {} that I can hook into to write the I2C bus.

I tried using another core to receive the new interface commands, but I get the r_i2c 'violates the parallel usage rules' error message because the audio thread still 'holds' onto r_i2c.

How can share the r_i2c object so that 2 threads can write to it (the audio thread when changing sample rate, and my i2c_message thread when messages come in from endpoint 0 ? ).


If I can't share, how about transferring ownership so that it's used for AudioHWInit at init time, but from then on, it's owned by the i2c_message thread?

Thanks,
-Caleb
View Solution
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

If you are using lib_i2c then the intention is that the i2c interface can be shared between multiple clients and the master takes an array of those clients.

Code: Select all

int main(void) {
  i2c_master_if i2c[2];
  par {
    i2c_master(i2c, 2, p_scl, p_sda, 10);
    init(i2c[0]);
    volume_control(i2c[1]);
  }
  return 0;
}
Both of the i2c clients (init() and volume_control() in the example above) can use the i2c bus whenever they want. In addition, the clients can be placed on any tile and the compiler will take care of the communication protocol required between the two tasks.
User avatar
ccrome
Active Member
Posts: 62
Joined: Wed Sep 23, 2015 1:15 am

Post by ccrome »

peter wrote:If you are using lib_i2c then the intention is that the i2c interface can be shared between multiple clients and the master takes an array of those clients.

Code: Select all

int main(void) {
  i2c_master_if i2c[2];
  par {
    i2c_master(i2c, 2, p_scl, p_sda, 10);
    init(i2c[0]);
    volume_control(i2c[1]);
  }
  return 0;
}
Both of the i2c clients (init() and volume_control() in the example above) can use the i2c bus whenever they want. In addition, the clients can be placed on any tile and the compiler will take care of the communication protocol required between the two tasks.
I forgot to mention that I'm using the USB Audio reference software sw_usb_audio-6.15.2rc1, which uses module_i2c, instead of lib_i2c, so it doesn't have that capability.

However, this looks like the correct solution. It's probably not too difficult to switch from module_i2c to lib_i2c.

Thanks for the help.

-Caleb