I2C Platform interface suggestion.

classic Classic list List threaded Threaded
3 messages Options
Mike Panetta Mike Panetta
Reply | Threaded
Open this post in threaded view
|

I2C Platform interface suggestion.

My suggestion would be to have a simple interface as follows:

platform_i2c_init( int dev ); // Initialize an i2c interface
platform_i2c_deinit( int dev ); // de-initialize (shutdown) an i2c interface
platform_i2c_master_xfer( int dev, platform_i2c_xfer_t * xfer_info ); //
Perform an I2C master transfer

struct platform_i2c_xfer {
  u16 addr  :7;    // Slave address, 10bit addressing not supported
  u16 _RES:1;
  u16 flags  :8;   // I2C flags, such as transfer speed (400KHz or 100KHz),
or if this is just a probe transfer (no data)
  u16 wdatalen; // Length of data to write
  u8 * wdata;     // Pointer to data to write
  u16 rdatalen;
  u8 * rdata;
} platform_i2c_xfer_t;

The reason we want to have both read and write data in the transfer struct
is quite a few I2C devices require a control byte (or bytes) write before a
meaningfull read can be done, as an atomic I2C transfer if possible by doing
a Start, Write, Repeated Start, Read, to a particular address.

This particular method obviously only allows a single tranfer per call to a
particular address, a simple modification can be done to address that issue,
which would be to place the transfer data pointers and lengths in a data
struct.

It would look something like:
struct platform_i2c_data {
  u8 rdnwr :1; // 1 for read, 0 for write
  u8 flags  :7; // TBD, will contain transfer status flags such as transfer
failed, etc
  u8 len;        // xfer len for this data block, set by user to the total
length of the storage area pointed to below, set by I2C code to actual
amount read or written after transfer complete.  If a transfer error occurs
on this data block a flag will be set above and this will be set to the
amount of data sent/recieved before the error occured.
  u8 * data;   // pointer to data storage for this block
} platform_i2c_data_t;

If a data block generates a transfer error all further datablock tranfers
will be aborted and the function will return an error.

I hope all this makes sense.  Maybe I should just write the code, as code
sometimes speaks louder then words! :)

Mike
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.berlios.de/pipermail/elua-dev/attachments/20081117/c9bc055f/attachment.html 

Dado Sutter Dado Sutter
Reply | Threaded
Open this post in threaded view
|

I2C Platform interface suggestion.

Hello List,
   Mike, thank you for the detailed explanation !!!
   To allow long transfers in a simple call would indeed be welcome and the
same idea has to be propagated to the Lua level.
   It will be really nice to have I2C soon !
   To keep the style used in some modules (ex: Lumina's OLED RIT driver),
you could use platform_i2c_disable instead of platform_i2c_deinit but it
really doesn't matter, as all low level modules have their own personality
:)  (they also have a weird RIT..._enable function, that does essentially
what RIT..._init does)
   Aren't platform_i2c_data_t and platform_i2c_data exchanged in the code
below ?
   I really wish I had some more time now to learn more about I2C :( Things
are going fast here and the little time I can use for coding is for easy and
little things :( :(

   Last saturday I wrote an ls command for the shell (and Bogdan has
accepted it !! :) :). I will just polish it a little bit (adding column
alignment for the byte length printing), sync with trunk and commit asap. I
need to do the same for our RIT OLED driver bind/wrapper, that is working
fine and I've extended some demo examples to include the display.

   Also, about the PID module, fundamental for some projects and highly
awaited by the robotic guys of PUC-Rio :), I would like Pedro to help us to
detail one, together with your fine ideas.
   The idea is to include two (small but important) filters on the module,
that would be optionally activated and damp/filter some feedback behavior.
Pedro is an expert in this stuff and the initial sugestion from Marco
Meggiolaro<http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=g+marco+meggiolaro+puc>
.
   Yesterday, another Eletrical Engineering teacher, R.
Tancheit<http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=g+Tanscheit+puc>,
suggested a Fuzzy Logic controller module, based on a "simple" method he has
but this is already completely offtopic now :) :)

Best
Dado





On Mon, Nov 17, 2008 at 1:25 PM, Mike Panetta <panetta.mike at gmail.com>wrote:

> My suggestion would be to have a simple interface as follows:
>
> platform_i2c_init( int dev ); // Initialize an i2c interface
> platform_i2c_deinit( int dev ); // de-initialize (shutdown) an i2c
> interface
> platform_i2c_master_xfer( int dev, platform_i2c_xfer_t * xfer_info ); //
> Perform an I2C master transfer
>
> struct platform_i2c_xfer {
>   u16 addr  :7;    // Slave address, 10bit addressing not supported
>   u16 _RES:1;
>   u16 flags  :8;   // I2C flags, such as transfer speed (400KHz or 100KHz),
> or if this is just a probe transfer (no data)
>   u16 wdatalen; // Length of data to write
>   u8 * wdata;     // Pointer to data to write
>   u16 rdatalen;
>   u8 * rdata;
> } platform_i2c_xfer_t;
>
> The reason we want to have both read and write data in the transfer struct
> is quite a few I2C devices require a control byte (or bytes) write before a
> meaningfull read can be done, as an atomic I2C transfer if possible by doing
> a Start, Write, Repeated Start, Read, to a particular address.
>
> This particular method obviously only allows a single tranfer per call to a
> particular address, a simple modification can be done to address that issue,
> which would be to place the transfer data pointers and lengths in a data
> struct.
>
> It would look something like:
> struct platform_i2c_data {
>   u8 rdnwr :1; // 1 for read, 0 for write
>   u8 flags  :7; // TBD, will contain transfer status flags such as transfer
> failed, etc
>   u8 len;        // xfer len for this data block, set by user to the total
> length of the storage area pointed to below, set by I2C code to actual
> amount read or written after transfer complete.  If a transfer error occurs
> on this data block a flag will be set above and this will be set to the
> amount of data sent/recieved before the error occured.
>   u8 * data;   // pointer to data storage for this block
> } platform_i2c_data_t;
>
> If a data block generates a transfer error all further datablock tranfers
> will be aborted and the function will return an error.
>
> I hope all this makes sense.  Maybe I should just write the code, as code
> sometimes speaks louder then words! :)
>
> Mike
>
> _______________________________________________
> Elua-dev mailing list
> Elua-dev at lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/elua-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.berlios.de/pipermail/elua-dev/attachments/20081118/bd59e35c/attachment.html 

BogdanM BogdanM
Reply | Threaded
Open this post in threaded view
|

I2C Platform interface suggestion.

In reply to this post by Mike Panetta
Hi,

Sorry for responding so late. Do you also have a proposal for the Lua
module? I'm curious how the two (the platform interface and the Lua
module) will talk to each other.

Thanks,
Bogdan

On Mon, Nov 17, 2008 at 5:25 PM, Mike Panetta <panetta.mike at gmail.com> wrote:

> My suggestion would be to have a simple interface as follows:
>
> platform_i2c_init( int dev ); // Initialize an i2c interface
> platform_i2c_deinit( int dev ); // de-initialize (shutdown) an i2c interface
> platform_i2c_master_xfer( int dev, platform_i2c_xfer_t * xfer_info ); //
> Perform an I2C master transfer
>
> struct platform_i2c_xfer {
>   u16 addr  :7;    // Slave address, 10bit addressing not supported
>   u16 _RES:1;
>   u16 flags  :8;   // I2C flags, such as transfer speed (400KHz or 100KHz),
> or if this is just a probe transfer (no data)
>   u16 wdatalen; // Length of data to write
>   u8 * wdata;     // Pointer to data to write
>   u16 rdatalen;
>   u8 * rdata;
> } platform_i2c_xfer_t;
>
> The reason we want to have both read and write data in the transfer struct
> is quite a few I2C devices require a control byte (or bytes) write before a
> meaningfull read can be done, as an atomic I2C transfer if possible by doing
> a Start, Write, Repeated Start, Read, to a particular address.
>
> This particular method obviously only allows a single tranfer per call to a
> particular address, a simple modification can be done to address that issue,
> which would be to place the transfer data pointers and lengths in a data
> struct.
>
> It would look something like:
> struct platform_i2c_data {
>   u8 rdnwr :1; // 1 for read, 0 for write
>   u8 flags  :7; // TBD, will contain transfer status flags such as transfer
> failed, etc
>   u8 len;        // xfer len for this data block, set by user to the total
> length of the storage area pointed to below, set by I2C code to actual
> amount read or written after transfer complete.  If a transfer error occurs
> on this data block a flag will be set above and this will be set to the
> amount of data sent/recieved before the error occured.
>   u8 * data;   // pointer to data storage for this block
> } platform_i2c_data_t;
>
> If a data block generates a transfer error all further datablock tranfers
> will be aborted and the function will return an error.
>
> I hope all this makes sense.  Maybe I should just write the code, as code
> sometimes speaks louder then words! :)
>
> Mike
>
> _______________________________________________
> Elua-dev mailing list
> Elua-dev at lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/elua-dev
>
>