On Mon, Oct 30, 2017 at 12:03 PM, Et Dev <[email protected]> wrote:
> Hello Ytai,
>
> Sorry for the delay as I was trying to get hold of another reliable logic
> analyzer to confirm my findings. The logic analyzer capture indicates that
> address is written by the master followed by an ACK from the slave. Do you
> need a trace with any other specific scenario?
>
Can you send a capture? Specifically, I'm curious about whether the
transaction ends (i.e. has a stop symbol).
>
> I understand that managing the project is quite intensive and time
> consuming - I didn't mean to impose additional burden on you. I believe
> timeout change is pretty innocent and could help esp. when dealing with
> unpredictable I2C slaves - and hence my suggestion.
>
Actually, I don't think this is as simple as you're describing it. Since
the master is the one driving the clock, all transactions are predictable
under normal conditions. Under abnormal conditions, a slave may hold SCL
low ("clock stretching") or SDA low indefinitely. Under these
circumstances, the bus is hung and even if the Java side gives up waiting,
the firmware is still stuck and the bus is physically unusable. This is a
serious limitation of the I2C specification, regardless of implementation.
For that reason, some chip manufacturers offer I2C "buffers", which have
some logic to "unstuck" slaves that have timed out and detach them from the
bus.
However, this doesn't explain or justify why the 0-length transactions
don't work. We can try to at least figure this out, so you could at least
enumerate what's on the bus.
> A complex I2C interaction with a timer at each step was quite difficult to
> program and hence I came up with my workaround.
>
In what way was it difficult? And in either case, once it is done, you
never need to do it again, right? Simply a matter of wrapping the standard
writeRead() with your own writeReadWithTimeout() that you can call instead.
This can be done externally, i.e. without changing the internals of IOIOLib.
> If you find it worthwhile please try to incorporate it in a future release
> - if you do come up with one in the future.
>
> Once again, thank you for your help and making a fantastic board available
> to the community.
>
> With regards,
> -VB
>
> On Wednesday, October 4, 2017 at 7:12:37 PM UTC-5, Ytai wrote:
>>
>> There are a few issues here, I hope I didn't forget anything.
>>
>> - Timeout: the approach I took with all blocking operations is that
>> they all handle Thread.interrupt() correctly. This way, you can implement
>> your timeout externally without having to change the IOIO library
>> internals. Simply set a timer that will interrupt the current thread on
>> your deadline and remember to cancel this timer if the operation succeeds.
>> - Async API: can be implemented on top of the sync API by creating a
>> thread per call or using a pool, etc. The risk you mentioned with a native
>> async API (blocking the internal threads of the IOIO) is one of the
>> reasons
>> why I chose this route. The other is that synchronous code is generally a
>> lot more straightforward. There's obviously a trade-off.
>> - I don't know why writeRead with empty in/out buffers doesn't work.
>> I agree that this is the preferred way to just check whether a device is
>> on
>> the bus or not. Do you happen to have a logic analyzer capture of what
>> happens on the bus in this case?
>> - As a side-note, I haven't been actively maintaining the code-base
>> in a couple of years now and have no strong desire to do so. I'm happy to
>> answer questions or engage in discussions, but just wanted to set your
>> expectations as far as making changes per your request.
>>
>> Cheers.
>>
>> On Tue, Oct 3, 2017 at 12:57 PM, Et Dev <[email protected]> wrote:
>>
>>> Hello Ytai,
>>>
>>> Great product - just love it!
>>>
>>> I am not sure if this is the right group to send this request, if not
>>> please guide. I am hoping to make a positive contribution to this community.
>>>
>>> I have used IOIO in past and have started using it for a pretty big
>>> project using some intricate hardware. I ran into problems for effectively
>>> using I2C devices and most of these were attributed to the fact that
>>> ioio.lib.api.TwiMaster.Result has a waitReady that blocks forever. This is
>>> problematic esp. when the I2C slave's behavior is not always completely
>>> determistic - as is the case with many complex hardwares. The thread blocks
>>> forever and recovery logic becomes more complex than original operation
>>> esp. when monitoring multiple such devices. For now I had to resort to some
>>> pretty ugly work-arounds. However, a waitReady in Result that times out -
>>> would make an application developer's task a lot easier. So I have the
>>> following suggestion, which I would appreciate if you can please consider
>>> to make something similar to this available in your next API release.
>>>
>>> In ioio.lib.impl.ResourceLifeCycle, add the following method:
>>>
>>> protected synchronized void safeWait*(long millis)* throws
>>> ConnectionLostException, InterruptedException {
>>>
>>> if (state_ == State.CLOSED) {
>>> throw new InterruptedException("Resource closed");
>>> } else if (state_ == State.DISCONNECTED) {
>>> throw new ConnectionLostException();
>>> }
>>> wait(*millis*);
>>> }
>>>
>>>
>>> In ioio.lib.api.TwiMaster.Result interface, add the following method:
>>>
>>> public boolean waitReady*(long millis)* throws ConnectionLostException,
>>>
>>> InterruptedException;
>>>
>>>
>>> In ioio.lib.impl.TwiMasterImpl.TwiResult class, add the following
>>> method:
>>>
>>> @Override
>>> public synchronized boolean waitReady*(long millis)* throws
>>> ConnectionLostException,
>>> InterruptedException {
>>> checkState();
>>> while (!ready_) {
>>> safeWait(*millis*);
>>> }
>>> return success_;
>>> }
>>>
>>>
>>> Another issue for working with I2C devices, I was not able to come up
>>> with a reliable solution to "ping" a I2C slave with IOIO master to
>>> determine if slave is indeed present. For example, connecting my I2C device
>>> to a bus-pirate, master can write an address of the slave on the bus and
>>> obtain an ACK and this would be an indication that a slave is indeed
>>> present at that address. My logic analyzer shows the same with this
>>> bus-pirate setup. However, I did not have any such luck making it work with
>>> IOIO's TwiMaster.writeRead. I tried writing a 0-byte buffer (with read
>>> null buffer) and reading 0-byte buffer (with write null buffer) but seems I
>>> dont get any results - calls simply block. I would appreciate any help in
>>> this regards.
>>>
>>> It would also help to obtain information on what was NACKed when
>>> writing+reading using TwiMaster.writeRead or TwiMaster.writeReadAsync
>>> returns false as currently, we have to split write and read into two
>>> separate invocations to know what failed esp. when error recovery depends
>>> on what failed.
>>>
>>> I was able to handle most trivial apps fairly easily with the current
>>> APIs and I like the synchronous API in its elegance and simplicity. I
>>> recognize this is a subjective viewpoint - however, when time-critical
>>> processing, reliability and performance are critical, it becomes harder to
>>> overcome the absence of asynchronous event handling paradigm in API esp for
>>> devices such as I2C, UART. User ends up dedicating a thread per item to
>>> operate and for complex apps, thread synchronization across many threads is
>>> typically harder, error-prone and sometime lags quite a bit - when recovery
>>> depends on state of device(s) across many such threads. At IOIOProtocol
>>> level,
>>> we are getting the notifications from the board (asynchronous processing).
>>> I wonder if it is worthwhile to explore allowing users to use an
>>> asynchronous event handling paradigm - where user can register listeners
>>> for handling ingress traffic notifications rather than blocking for it in
>>> individual threads. Problem of a potential event-handler hogging the
>>> IOIOProtocol handling thread can be mitigated by user handling events
>>> using a thread-pool/queue. Please share your thoughts.
>>>
>>>
>>> With regards,
>>> -VB
>>>
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "ioio-users" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at https://groups.google.com/group/ioio-users.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
> You received this message because you are subscribed to the Google Groups
> "ioio-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/ioio-users.
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.