pasko-zh / brzo_i2c

Brzo I2C is a fast I2C Implementation written in Assembly for the esp8266
GNU General Public License v3.0
244 stars 47 forks source link

Add `Wire` like interface api #1

Closed FWeinb closed 7 years ago

FWeinb commented 8 years ago

It would be great if this library would be supported as a drop in replacement for the Wire library. There could be a thin wrapper around this lib to make integration into existing code simpler.

supersjimmie commented 8 years ago

I think(...) that it's not very hard to replace these 'Wire' like functions:

begin
beginTransmission
endTransmission
write / send
read / receive

With those respectively:

brzo_i2c_setup
brzo_i2c_start_transaction
brzo_i2c_end_transaction
brzo_i2c_write
brzo_i2c_read

More a problem will be Wire like functions as:

requestFrom

And I think these Wire functions will need a lot of extra coding:

available
onReceive
onRequest

I would personally be happy if the first part and a requestFrom equivalent can be added somehow.

pasko-zh commented 8 years ago

Yes, it's true, it would be nice to have a wrapper for a drop in replacement of the wire library and its methods.

When I started to develop brzo i2c I had this case in mind, of course. However on the other hand, there are some "concepts" in the wire library which I don't like (or either never fully understood). For instance, this asymmetry between sending and receiving bytes, i.e. .beginTransmission, and then only .write commands, no reads, and finally end this transmission with .endTransmission, where all the date is trasmitted over the i2c bus. Versus .requestFrom and then the read commands, where the bytes are read from the i2c slave; and no bracket for beginning and ending a transmission. Or, how errors are treated and reported back to the caller...

But, jumping over this "I don't like" stuff and thinking on ;-)

There are many overloads of the methods in the wire library. So, I think I/we would have to find a compromise which one should be made ported. For instance, you can write a single byte or as I did in brzo i2c, write from a buffer.

Then, overall, I need to think a bit more on how these two concepts could be married :-) But nothing is impossible!

supersjimmie commented 8 years ago

Just to do something, I started to make a small library that melts your brzo library and the old Wire together. It creates a new class called Wire2 (because it cannot be named Wire). So in an Arduino code, you need to include this translating library and rename any Wire to Wire2. I will call this library Wire2brzo. So instead of #include <Wire.h> it's going to be #include <Wire2brzo.h>. Then everything works with the object Wire2 and functions like Wire2.begin().

That was the easy (but not for me) step.

Next, more difficult, step is to let my library do the same as the original Wire library by using your code. I'll start my attempt with the base functions like begin, write, read, beginTransmission, endTransmission. Next must be requestFrom. If I manage to get those working, all is enough as a replacement to test it with my problematic PN532...

(Fingers crossed, I am not a programmer)

FWeinb commented 8 years ago

@supersjimmie Thanks for your effort. That sound really great. @pasko-zh Just a usage question. I could not get it to work. I want to send some data from an existing uint8_t array like this:

  [... setup and begin ...]
    uint8_t  buffer[10] = [0,0,1,1,1,2,3,3,4,5];
    brzo_i2c_write(&buffer[4], 5, true);
  [... end ...]

That should send 1,2,3,3,4 right?

pasko-zh commented 8 years ago

Not quite :-) In brzo_i2c_write it expects a pointer to a buffer, it then sends the n elements starting from the beginning of the buffer. (Inside the function I pass the pointer to the first element to the inline assembly, [r_adr_array_element] "+r" (&data[0]) ...
Maybe my use cases were a bit too narrow, but I thought one would always send n bytes from the beginning of the buffer. But I could change that... EDIT: I will change this in the next version. Since I don't have a compiler/esp in front of me for the next days it will take ~ 1 week.

EDIT 2: I have moved this to a new issue, #2 .

FWeinb commented 8 years ago

I would really like that. Maybe just expect a raw pointer (like memcpy) and dont do the (&data[0]) query in this library. Than one could just pass in a pointer that points to the start of the array you would like.

pasko-zh commented 7 years ago

I have included a section in the wiki on "How to migrate from Wire Library", see here