xmos / lib_i2c

I²C library
Other
3 stars 25 forks source link

Use case that is not supported #20

Closed henkmuller closed 6 years ago

henkmuller commented 6 years ago

I am trying to write a piece of code, and somewhere in the middle of a long call tree, I need to use I2C. This is the only place I need I2C, I don't need it anywhere else.

Ideally, I would just call two functions 'READ' and 'WRITE' to interact with I2C. However, to do that I need to create an interface to an I2C master, but when I do that I end up with a thread that won't die.

  f() {
      ...
      par {
        i2c_single_port_master(...);
        code_that_uses_said_master;
      }
      ...
  }

How do I write that, without having to change my whole call tree to pass an i2c interface around? I am never concerned about sharing, as this is my final application. f() is a call back from other libraries, and hence I do not want to change it.

Ugly solutions include starting i2c_single_port_master at top level and somehow storing the i2c interface in a global.

Clean solutions would be to just use i2c_read and i2c_write functions; I am missing a trick as to how to use those functions encapsulated in the interface without actually creating the interface as an ever-running task.

ghost commented 6 years ago

Does 'code_that_uses_said_master' call i2c.shutdown() before finishing?

case c[int i].shutdown():
  return;
henkmuller commented 6 years ago

Aha!

That is a very interesting suggestion.

So - the requirement for a [[distributable]] task is that it ends with a while(1) { select {} }, I believe; but so you can have a return inside. I guess that with the return in a specific branch of the select this may be more tractable then allowing the while(condition) { select {} }, where the condition can be anything, whereas this was the return is in specific places?

I will try this.

henkmuller commented 6 years ago

That does the trick nicely. However, the code produced is slightly unexpected: it generates lots of indirect function calls (BLA) for the i2c read and write functions; I had expected the compiler to make them into direct calls, with a sequence of 22 instructions leading up to each call. Closing this issue, it may be worth understanding why the compiler, in this case, isn't able to make them direct calls.