![]() |
flux sdk
v01.02.02-3-g292b3a7
Embedded C++ SDK
|
A framework device class wraps an underlying device driver, providing the needed functionally to bring the device withing the framework.
The key capabilities provided by the implemented framework device class are:
The device class should following the naming pattern flxDev[Name]
, where Name is a unique name of the class.
The implementation requires separate header and implementation files, since several class variables and a global object are defined that required the use of an implementation file.
The new device class should subclass from the frameworks flxDevice
class, using the flxDeviceI2CType<DeviceName>
template. Additionally, the device class subclasses from the underlying Arduino driver class in most cases. This allows the descriptor class to support the existing driver's interface.
Note - In some cases, because of the underlying Arduino Library design, an alternative implementation pattern is required - such as object containment.
Implementing a driver for the BME280
Device.
The framework supports runtime discovery of connected devices. This is performed using information from the framework device class, and not creating a device instance until the device is actually detected.
To accomplish this task, class level (static) methods and data are implemented by the device object. Each device class implements the following:
Item | Description |
---|---|
bool isConnected(flxBusI2C, address) | Returns true if the device is connected |
char* getDeviceName() | Returns the Device Name |
uint8_t *getDefaultAddresses() | Return a list of addresses for the device. This list terminates with the value of kSparkDeviceAddressNull |
flxDeviceConfidence_t connectedConfidence() | Returns the confidence level of the drivers isConnected() algorithm. Values supported range from Exact to Ping |
>* Often the device implements the address list as a class level variable >* It is common to define a constant or macro for the device name and return it from getDeviceName()
The first step for a given driver is the retrieval of default addresses for the device. In this step, the system calls the getDefaultAddresses()
method of the driver. The driver should return an array of type uint8_t, with the last value of the array being the sentinel value of kSparkDeviceAddressNull
.
The system uses the array of addresses to determine what addresses are currently available, and call the isConnected()
with the possible and available addresses until a connection is found, or it hits the end of the possible addresses for the device.
For each of the addresses returned, the system calls the drivers isConnected()
method. The driver should returns true
if the device is connected at the given address, otherwise false
.
How the driver determines if a device is connected is determined by the implementation
The static interface for the device also includes a method to return the name of the device.
This method returns a constant C string.
This method returns the confidence level for the algorithm in the devices isConnected()
method in exactly determining if a device is connected at the specific address.
This confidence level is used to resolve detection conflicts between devices that support the same address on the I2C bus. Drivers that have a higher confidence level are evaluated first.
The return value should be one of the following:
flxDevConfidenceExact | The algorithm can perform an exact match |
flxDevConfidenceFuzzy | The algorithm has high-confidence in a match, but it's not exact |
flxDevConfidencePing | An address "ping" is used - just detecting a device at a location, but not verifying the device type. |
Only one device with a PING confidence is allowed at an address.
This example is taken from the device driver for the BME280 device.
The class definition - flxDevBME280.h
kBME280DeviceName
defaultDeviceAddress[];
onInitialize()
is called after the object is instantiated.BME280
To complete the auto-discovery capabilities of the system, besides the implementation of the above methods, the classes implementation file must include a call to register the device with the system.
This is call is placed before the class implementation and has the following signature:
Where DeviceClassName
is the class name of the device being registered.
Once a device is registered, it is available for auto-detection and loading by the framework during the startup process of system.
Building off the above BME280 example, the implementation looks like:
* This example includes the implementation of
defaultDeviceAddress[]
, the class variable holding the addresses for the device.
- The device is registered before the class constructor
- In the constructor, the device identity is set, which is based of runtime conditions.
The isConnected() method for this example is:
* This is a static (has no
this
instance) and as such uses the methods on the passed in I2C bus driver to determine in a BME280 is connected to the system
The last part of implementing a device descriptor/driver class is the addition of an initialization method, named onInitialize()
.
The only argument to this methods is the Arduino I2C TwoWire
class, which the class can use to initialize the device. The method returns true
on success, false
on failure.
The BME280 example implementation:
The
address()
method returns the device address for this instance of the driver.
To determine if a device is initialized, the Device Driver implementation should call the method isInitialized()
, which returns the value that was returned by onInitialize()
. It also returns false before the call to isInitialized()
See the detailed description of Properties
See the detailed description of Parameters