zephyrproject-rtos / zephyr

Primary Git Repository for the Zephyr Project. Zephyr is a new generation, scalable, optimized, secure RTOS for multiple hardware architectures.
https://docs.zephyrproject.org
Apache License 2.0
11.01k stars 6.7k forks source link

Add API to retrieve the I2S State from Zephyr I2S Driver #60754

Open DerekSnell opened 1 year ago

DerekSnell commented 1 year ago

Discussed in https://github.com/zephyrproject-rtos/zephyr/discussions/60743

Originally posted by joekane101 July 24, 2023 I am converting this to an Issue for @joekane101 to gain more visibility in the project.

Introduction

The Zephyr I2S Driver API has many calls that are dependent upon the i2s_state (the current operating state of the I2S bus); some calls can only be made during IS2_STATE_RUNNING, or I2S_STATE_ERROR, but the state itself is not directly exposed by the Zephyr API.

SOC vendors that port to the I2S driver keep the i2s_state in their internal port structures in order to comply with the Zephyr driver operational requirements. Its possible to retrieve the data from the internal structure, but this is not portable.

Having public access to the current I2S state will help with error conditions and recovery.

Problem description Without access to the current i2s_state, calls to an I2S API may fail (as they are disallowed). In a specific example, multiple errors may occur) and be detected on I2S input (read call) and the output I2S write, but the asynchronous timing of the recovery calls can result in errors.

Assume a simple I2S pass-through case, when I2S data is read from I2S input, and then written to I2S output.

Assume the following sequence: An input I2s error occurs (read timeout or buffer error) and the i2s_state moves to I2S_STATE_ERROR.
An error is returned on the i2s_read call, and the (input) recovery code issues an I2s_trigger (I2S_TRIGGER_PREPARE) to recover the bus.

Short thereafter an I2S write error occurs (buffer underrun, because the I2S read is late). Similarly, an I2S_trigger(I2S_TRIGGER_PREPARE) is issued to recover the bus after the write failure.

Given the timing of events, the first I2S_TRIGGER_PREPARE (input error) resets the I2S bus sometime shortly after the write error. The i2s_state moves to I2S_STATE_READY, and the second I2S trigger prepare fails with a generic EIO (because this trigger is only allowed during I2S_STATE_ERROR), which is ambiguous.

In more complicated scenarios, the I2S read and I2s write calls are managed by separate threads and queues, so the input error recovery and output error recovery are unaware of each other.

In addition, other processes may want to know the current state of the I2S bus; is it currently active and running, ready, in error?

Proposed change

Add a Zephyr I2S API to expose the i2s_state. This would allow testing for state conditions, better error handling, and smarter api calls (don't send calls that are disallowed by the bus state).

Soc Vendors would also need to update their ports to supply the I2S STATE via the Zephyr API.

Detailed RFC

Proposed change (Detailed)

I defer to the zephyr team for the API definition that returns the i2s_state.

Dependencies

Concerns and Unresolved Questions

Alternatives Soc Vendor specific calls to return the state could be made, but this is not portable.

zephyrbot commented 10 months ago

Hi @anangl,

This issue, marked as an RFC, was opened a while ago and did not get any traction. It was just assigned to you based on the labels. If you don't consider yourself the right person to address this issue, please re-assing it to the right person.

Please take a moment to review if the issue is still relevant to the project. If it is, please provide feedback and direction on how to move forward. If it is not, has already been addressed, is a duplicate, or is no longer relevant, please close it with a short comment explaining the reason.

@DerekSnell you are also encouraged to help moving this issue forward by providing additional information and confirming this request/issue is still relevant to you.

Thanks!