You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/11/06 11:13:01 UTC

[GitHub] andrzej-kaczmarek opened a new pull request #1507: [RFC] Add generic serial bus driver

andrzej-kaczmarek opened a new pull request #1507: [RFC] Add generic serial bus driver
URL: https://github.com/apache/mynewt-core/pull/1507
 
 
   This PR adds initial proposed API and implementation of generic serial bus driver.
   
   The goal is to create abstraction for using serial buses like I2C and SPI in a generic way where bus state is managed automatically to allow access from multiple tasks and to multiple devices concurrently in an easy way [1]. It will be also good place to add special handling for known issues in existing devices if they are attached to bus so we can recover from errors [2].
   
   [1] currently we use global mutexes which are shared via sensor/charger/etc. interface with each driver and each driver needs to lock it manually - we should have lock defined and managed automatically on bus level
   [2] currently we already have some workaround for faulty device in `hal_i2c` implementation of `hw/mcu/nordic/nrf52xxx` - HAL is not a good place to workaround problems not related to particular I2C controller and this workaround will also not work when platform other than `nrf52xxx` is used
   
   There are two kind of objects managed by bus driver:
   - `bus_dev` = bus device which is a representation of I2C or SPI bus instance; should be created by MCU (or BSP) code and effectively replace existing init calls to HAL since this is done now internally by bus driver,
   - `bus_node` = bus node which is a representation of an actual device connected to bus; should be created by driver or even an application in case application wants to access some "loose" object on the bus without dedicated driver.
   
   It may be a bit counter-intuitive to use `bus_dev` for bus and not for an actual device, but it originated from `os_dev` which is used internally and honestly I don't have any better names for both so any other ideas are welcome. I eventually got used to these names after a week of coding ;-)
   
   The setup to use bus driver for I2C controller is as follows:
   1. MCU creates `i2c0` `bus_dev` which initializes hardware (similar to what `hal_xxx_init` call did previously)
   2. for each device attached to bus, driver or application needs to create `bus_node` which specifies:
   - `bus_dev` (by name) where node is attached
   - bus configuration used for communication with each device (clock frequency for I2C, will be also data mode for SPI)
   - optional quirks for device; this allows to define some known issues for a device and allow bus driver to automatically apply some workarounds in case such device is used
   
   Application which wants to talk to one of created `bus_node`s should do as follows:
   1. call `os_dev_open()` to open `bus_node` with specified name
   2. on 1st open, driver can configure device before 1st use
   3. `os_dev` obtained from `os_dev_open()` call can now used to talk to device using `bus_node` APIs
   
   Each operation on `bus_node` does as follows:
   1. parent `bus_dev` is locked for exclusive access
   2. bus configuration is adjusted if new device requires different configuration that device previously accessed on the same bus (for I2C this probably won't be used too much since we can run all devices with the same speed, but it's easily possible to use different devices with different speeds)
   3. operation is executed via appropriate HAL
   4. `bus_dev` is unlocked
   
   So effectively what users of `bus_node`s need to do is just call single `bus_node_xxx` API and parse the result. They don't need to care about current bus state. The goal is to be able to use a simple call to make most of bus accesses.
   
   APIs are split into two main parts:
   - `bus/bus.h` is what is enough to access `bus_node` as opened by `os_dev_open()` and this is what driver and application will mostly use
   - `bus/bus_driver.h` is what is necessary to create `bus_dev` and `bus_node` from MCU/BSP/driver so more low-level stuff that needs to be only done once to create `os_dev`s and not required to access bus from apps
   (there's also `bus/bus_debug.h` but it's just some helper for debug code, so not really useful from "outside")
   
   Current API allows to do following operations:
   1. read data from `bus_node`
   2. write data to `bus_node`
   3. write data from and then read data to the same `bus_node` (with bus lock held during entire transaction) which is probably the most commonly used transaction
   4. lock and unlock `bus_dev` to allow combine the above simple ops into compund transactions
   5. (already deprecated) obtain direct access to `bus_dev` lock
   
   1/2/3 are available as blocking operations; non-blocking versions of these APIs will be also available and they will quite similar to blocking calls except the result will be returned via supplied callback
   4 I considered to provide API to define and execute compound transactions (other than most common write->read) but abandoned this for now since it will be quite complicated and I am not sure if it will be used too much, so probably not worth the effort, but we can still add this later
   5 is to provide some compatibility with existing code so we can share mutex with other existing ways of locking, at least for now
   
   In addition to new `hw/bus` and `hw/bus/i2c` packages which implements generic bus driver and I2C bus driver, there are few other commits included which were either necessary or just useful to implement this:
   1. `hal_i2c` is extended with some calls that already exist in `hal_spi` which are separate calls to enable, disable and configure interface
   2. `hw/mcu/nordic/nrf52xxx` is extended to create `bus_dev`s for enabled I2C instances when `hw/bus` is included in build
   3. `apps/bus_test` is provided which includes two simple implementation of bus_nodes which it can then talk to (they are running at different speeds just to see if things are reconfigured properly on-the-fly)
   
   Finally, there are few things that are not finished yet which I'll try to update in upcoming days:
   - doxygen doc is a bit sparse in some places,
   - error handling is barely implemented,
   - device quirks are not implemented
   - SPI bus driver is missing

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services