I do not think a driver requires an os device personally. You could write a driver that does not have os dev functionality in it. I do agree that it seems most people implement drivers with os dev functionality but I do not think it is a requirement.
> On Aug 31, 2018, at 9:51 AM, Christopher Collins <ch...@runtime.io> wrote: > > I do think that approach makes more sense than implementing retries in > the HAL. By the way, I did submit a PR for performing I2C retries in > the HAL: > https://github.com/apache/mynewt-core/pull/1373#issue-212250961 > > I am happy to redo this at a higher layer, though. If nothing else, it > gives us two implementations to compare. > > I am a bit confused by the term "driver," though. I could be wrong, but > my impression is that a Mynewt driver necessarily involves the use of > `os_dev` objects. That is not how I would envision such an I2C layer to > look. Specifically, I am thinking of a thin library that offers two > functions (names simplified): > > int i2c_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata, > uint32_t timeout, uint8_t last_op, int retries); > > int i2c_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata, > uint32_t timeout, uint8_t last_op, int retries); > > These functions would just repeatedly call the HAL I2C functions until > they succeed, or until all retries are exhausted. Is anything else > needed? > > Chris > > On Fri, Aug 31, 2018 at 05:58:39PM +0200, Sterling Hughes wrote: >> I agree with this as well. For awhile now, I think there has been a >> need for an I2C driver layer, which also can manage bus arbitration. >> Retries is another good one to add to that. >> >> Sterling >> >> On 31 Aug 2018, at 17:32, Andrzej Kaczmarek wrote: >> >>> Hi all, >>> >>> Seems like the majority already voted to go for retries in HAL, but >>> I'll add my opinion anyway: I do not think HAL is proper place to >>> include such logic. >>> I think HAL should only provide interfaces to hide differences between >>> underlying MCU hardware while read/write retry logic is something >>> driver should do (or any caller in general) since it can decide when >>> and if it makes sense to retry. This is what common error codes (so >>> #1) would allow to do. This does not however mean we can't have common >>> retry code. What we likely need is some bus-level driver/layer that >>> drivers will use instead of HAL directly so it can take care of >>> handling multiple devices on the same bus seamlessly (in general) and >>> also it would be the place where we can put extra common logic if >>> needed (like retries). >>> >>> Best, >>> Andrzej >>> >>> >>> >>> On Thu, Aug 30, 2018 at 3:59 AM Christopher Collins <ch...@runtime.io> >>> wrote: >>>> >>>> Hello all, >>>> >>>> I noticed the HAL master I2C API does not include any retry logic. >>>> As >>>> you probably know, in I2C, the default state of the SCL line is NACK. >>>> This means an unresponsive peripheral is indistinguishable from one >>>> that >>>> is actively nacking the master's writes. If the master's writes are >>>> being NACKed because the slave is simply not ready to receive data, >>>> then >>>> retrying seems like the appropriate solution. >>>> >>>> I can think of two ways to add I2C retries. Each of them requires >>>> changes: >>>> >>>> (1) Delegate the retry logic to the code calling into the HAL >>>> (e.g., >>>> drivers). >>>> (2) Implement retry logic directly in the HAL. >>>> >>>> The problem with (1) is that HAL implementations currently return >>>> MCU-specific error codes. A generic driver cannot determine if a >>>> retry >>>> is in order just from inspecting the error code. If there were a >>>> common >>>> set of error codes that all HAL I2C implementations returned, drivers >>>> would have the information they need. Actually, even ignoring the >>>> subject of retries, I think common error codes here makes sense. >>>> >>>> Re: (2) - I was thinking this could be implemented by adding two new >>>> members to the `hal_i2c_master_data` struct that gets passed to every >>>> master I2C function: >>>> >>>> /** >>>> * Total number of times to attempt the I2C operation. Certain >>>> * failures get retried: >>>> * o NACK received after sending address. >>>> * o (if configured) NACK received after sending data byte. >>>> */ >>>> uint8_t tries; >>>> >>>> /** Whether to retry when a data byte gets NACKed. */ >>>> uint8_t retry_on_dnack:1; >>>> >>>> (I hate to complicate things with the `retry_on_dnack` member, but >>>> some >>>> peripherals seem to become unresponsive in the middle of a >>>> transaction.) >>>> >>>> Since these additions are members of a struct, rather than new >>>> function >>>> parameters, this change would be mostly backwards-compatible. There >>>> is >>>> still a problem here, though: code that doesn't zero-out the >>>> `hal_i2c_master_data` struct will likely get retries when it isn't >>>> expecting them, which could conceivably be a problem. >>>> >>>> I am leaning towards (1). Thoughts? >>>> >>>> Thanks, >>>> Chris