Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re^2: i2c bus contention

by jcb (Parson)
on Mar 30, 2020 at 01:48 UTC ( [id://11114790]=note: print w/replies, xml ) Need Help??


in reply to Re: i2c bus contention
in thread i2c bus contention

If I remember I2C correctly, that is actually over-complicated. The master selects a device by emitting an address onto the bus, possibly writes some number of bytes to that device (a device-internal register number and/or data to write), and possibly reads some number of bytes from that device. The bus then returns to idle state.

So the manager only needs a slave-address/write-buffer/read-count 3-tuple to define a transaction that can be performed atomically. If read-count is zero, only a completion can be returned; otherwise, the data read from the device is returned. In pseudo-C with the uint8_t[] type as a Perl-like scalar that carries its own length, an I2C transaction has this prototype:

uint8_t[] i2c_xact(i2c_address slave, uint8_t[] write, size_t read_count);

Replies are listed 'Best First'.
Re^3: i2c bus contention
by GrandFather (Saint) on Mar 30, 2020 at 06:24 UTC

    In principle yes. In practice it ain't quite as simple as you suggest. The complication isn't the function prototype (or even the implementation) anyway, but even there your suggested API is a little simplistic for practical use. The devil is in the error handling. Not only may either the write or the read fail, but either may partially succeed. So, sticking with pseudo-C/C++ where Buffer is a suitable C++ class equivalent to a Perl string, the function prototype changes a little to:

    Status TransactI2C(uint8_t address, Buffer wData, uint8_t &written, Bu +ffer &rBuffer, uint8_t expected);

    and the calling code needs to be able to handle statuses like: I2C busy, Write failed, Partial Write, Read Failed, Partial Read, Complete OK.

    But the real issue is exactly what the OP is struggling with: simultaneous access. And that isn't solved by just defining a nice API. That has to be solved using some common "process" that serialises access to the I2C port as provided by the OS. That can be non-trivial indeed depending on what the system provides and what your actual use case is. As it happens I've been working to solve exactly those sorts of problems with an embedded system that uses 6 I2C buses, a couple of SPI buses and the odd ADC, USB controller and Ethernet controller thrown in. With all of that stuff running interrupt driven and half of it driving DMA things get pretty interesting!

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond

      That API is for submitting a transaction to a shared daemon that will queue the transaction and process it later, so the "I2C busy" status cannot occur. You are probably correct about the possibilities of partial success, but the application I previously worked with did not handle that and did not have problems from lacking that handling. It also drove only very simple peripherals.

      Defining a nice API is the first step towards solving simultaneous access. The API must be an interface to an implementation that can queue and serialize transactions from multiple clients. What I suggested is similar to the I2C module I once wrote for an embedded application that handled some I/O in interrupt handlers or with DMA but did nearly all processing in a cooperative multitasking loop. The "I2C daemon" was another function called as part of that loop and an interrupt handler for advancing an "in-progress" transaction.

Re^3: i2c bus contention
by anita2R (Scribe) on Mar 30, 2020 at 13:16 UTC

    @jcb As GrandFather notes, I still need to get a common function that handles calls to the i2c bus from two or more scripts.

    My access to the i2c bus from the two existing scripts works well and is stable when contention is managed on a time slot basis.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11114790]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2024-04-26 05:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found