Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
|
According to a study conducted at Harvard Medical School, "Hot flashes can go on for years and take a toll on a woman’s health and well-being"
According to another study, hot flashes are sudden feelings of heat that spread mainly through the face, neck, and chest. Night sweats happen when hot flashes occur at night. According to some estimates, the occurrence of hot flashes may run for an average of 5.2 years. And the earlier in life they occur, the longer time period they may last. Hot flashes and night sweats occur before and during menopause because of changing hormone levels, including estrogen and progesterone, affecting the body’s temperature control. Changes in these hormone levels affect the action of other hormones that are responsible for regulating the body’s temperature. This causes the characteristic feelings of sudden warmth, flushing, and excessive sweating. The frequency of hot flashes and night sweats differ between people. Some only experience occasional hot flashes while, for others, the symptoms can get in the way of daily life.
Although some women learn to deal with menopause-related hot flashes and night sweats and can live a normal life with them, for other women they can be quite disturbing.
Some of the measures for controlling and easing hot flashes are:
- Deep-breathing exercises
- Dressing in layers
- Lowering the temperature
- Staying away from caffeine, alcohol, hot beverages, and spicy foods
- Stress reduction techniques like meditation and mindfulness
- Doing your best to stay cool in general
In this, we are going to focus on lowering the ambient temperature for easing the conditions by reducing body temperature and night sweats. There are quite a few devices that are already available to ease the effects of hot flashes. But in our project, we are trying to develop a simple and cost-effective solution. This can also be viewed as an easy DIY solution to anyone suffering from the effects of hot flashes.Introduction
The aim of this project is to design and develop a Smart Band that can provide possibilities for usage in personal health monitoring for easing the effects of hot flashes. The Smart modules will be developed with RSL10-SENSE-GEVK as the core component connected to a custom-made mobile application via BLE for external access, monitoring, and control.
This deals with the monitoring and reporting of healthcare-related data to a central server (eg: Atmosphere IoT) so as to generate daily or periodic health care reports. In our case, we are focusing on skin temperature data and reports.
In the future, as an upgrade, the data can include those collected from the IMU (based on various activities carried out) and the environmental sensors (for checking various conditions of exposure).
The RSL10-SENSE-GEVK is available for less than 50$ and the RSL10 QFN module (not the development module) is available for less than 5$ and thus can be easily developed in bulk to make it available at an even cheaper rate in the market. Overall, the final module cost will be cheaper which makes it one of the Best Retail Directed and One-Symptom Solution.
Work planThe RSL10-SENSE-GEVK is a comprehensive, compact, node-to-cloud IoT sensor platform that allows the development of various Bluetooth Low Energy-based use cases. The board boasts a compact size and an ultra-low-power Bluetooth Low Energy SoC and features a wide range of onboard sensors, including sensors for ambient light, temperature, pressure, humidity, gas, inertia, and magnetism. Along with the hardware and software, the RSL10-SENSE-GEVK includes a mobile app to interact with sensors and actuators.
Make sure we have the following pre-requisite software before proceeding:
1. SEGGER JLink Software - This is used as an interface to talk with the JLink debugger module.
2. Atmosphere IoT Agent - This allows the atmosphere web interface to talk with associated hardware for programming and debugging.
3. Atmosphere IoT app - From the respective stores, iPhone & android
Now once these are downloaded, install the SEGGER JLink Software. The Atmosphere IoT Agent is an app image, we just have to run this using Sudo privileges.
chmod u+x <app image>
Now add the current user to dialout group
sudo adduser $USER dialout
I would recommend logging in again for the changes to take the effect.
Now after re-logged in, start the atmosphere agent app. An atmosphere agent icon would appear at the top taskbar.
Now if we click on that icon and select status, we would get a webpage stating this:
This means that everything is up and running.
Now we move on to the next step. The programming.
Head to https://platform.atmosphereiot.com/
If you don't have an account already, now it's the time to make one.
Start a new project using RSL10-SENSE-GEVK as the device.
Give a cool name and let's start.
Now we are presented with a nice canvas and an element toolbox to the right.
Now as I told I am a bit lazy, I am gonna take the help from the atmosphere tutorial webpage to explain the upcoming steps.
The first aspect of building this sample project is adding elements to the Embedded tab to create the project’s embedded firmware. This involves setting an interval to read embedded data, and when to run to read the board’s BME680 element.
Add the following elements to the canvas by clicking them in the Element Toolbox:
- Interval element: The interval element sets the project to run at the time set in the element’s properties, which by default is set to once per second (1000 ms).
- BME680 element: The BM3680 element reads the temperature, humidity, and pressure data. This is an environmental sensor that is onboard the RSL10-SENSE-GEVK, and its element is imported in the Element Toolbox for RSL-SENSE-GEVK projects by default.
- BLE characteristic element: This element creates a GATT characteristic to use in your project and is a coupled element that bridges the project between the Embedded tab and Application tab, meaning it’s included on both tabs.
The interval and BME680 element will work as intended by default, so none of their properties need to be changed. Connect the interval element to the BME680 element. This creates an event between them, which can be seen in either the interval element’s properties or by clicking the connector’s button. The event added is within the Interval
trigger, with the BME680 ability Read Temperature (°C)
. This means that when the interval element is triggered (which is every second), it will read the sensor’s temperature data. Add a BLE characteristic element to the canvas. In the BLE characteristic element’s properties, change the Read Data Type and Write Data Type fields to Floating Point (32-bit)
. This allows the elements to read and write floating-point values that will eventually be sent through them. You’re encouraged to give the elements custom names that represent what they do or what data they are passing through, such as naming it “Temperature". Connect the BME680 element to the BLE characteristic element, which ties the value of the sensor to the Application tab. This creates an event between the two elements in the Temperature Read
trigger, with the ability as Set Value
. This sets a value for the project’s interface after it reads the temperature sensor data. That’s all for work in the Embedded tab. To this point, an interval has been set that will run once per second after the project opens, and when run will read the temperature value from the onboard BME680 sensor.
Let's proceed to the Applications tab to create the project’s visual component. Here we’ll create a basic interface, pairing the sensor values sent from the Embedded tab with label elements to display their values on labels inside the mobile app. Click the Application tab to move to the application area of the project. Notice how the Element Toolbox has changed, and that the coupled BLE characteristic elements are displayed on the canvas. Click the top right button in the Application tab’s toolbar to display the app builder. This area creates a visual interface for your project. By default, this uses the smallest display size supported for an interface (320x560), but you can add an interface size by clicking the phone button. Use the display size that fits best with your mobile device.
Now, sad the following elements:
- Interval element: The interval element sets the project to run at the time set in the element’s properties, which by default is set to once per second (1000 ms).
- Label element: The label element displays text on a project’s interface. Notice when the label is added to the canvas, a corresponding interface component is added to the app builder. The label component can be moved around on the interface wherever you like.
- Analog meter element: The analog meter element adds a meter to measure value to a project’s interface.
- Cloud element: The element enables a project’s data to be sent to the Atmosphere cloud.
Connect the interval element to the BLE characteristic elements. Within the interval element’s trigger properties, set each BLE characteristic’s event ability to Trigger
under the Interval
trigger, which will trigger the BLE characteristic elements every time the interval triggers. Connect the BLE characteristic element carrying the temperature data to the first label element. This creates an event between the two elements of Set Text
under the Read
trigger, which sets the text to the value of the label when the BLE characteristic is read. This correlates the set value from the BLE characteristic element in the Embedded tab to the label on the interface. Within the Set Text event, modify the Text field to "Temperature:" + readData.toFixed(2)
. This argument reads the temperature data and truncates the value to two decimal places. This is all that needs to be done for the project’s interface, simply using three labels to display text values. To this point, an interval has been set that will trigger the BLE characteristic elements once per second, which will display the read temperature values on the interface label. The cloud event element is a coupled element between the Application and Cloud tabs. Connect the BLE characteristic element carrying the temperature data to the cloud event element. This adds the Send Event
event to the BLE characteristic element’s Read
trigger, which sends the set value data to the Atmosphere when the BLE characteristic is read. Connect the BLE element to the Analog meter event and set the ranges and other characteristics if required.
These are the basic things that need to be done for the basic setup inside the Applications tab. but I have added a few more customizations such as adding background images and logos to give credits to certain entities.
Now let's move on to the Cloud tab.
Add the following elements:
- Cloud storage element: The cloud storage element is used to persistently store data on the Atmosphere. This is most commonly used alongside the cloud event element to store the embedded data sent to the Atmosphere from a device.
Connect the temperature data cloud event element to the cloud storage element. By default, this creates an event using the Add Data
ability within the cloud event’s Event Received
trigger. This allows the atmosphere to add (and store) data sent to it from the connected cloud event element. Within the Add Data event, modify the Value field to {"Temperature": value}
, which will label the temperature dataset when displayed in the cloud.
We have completed our program. Now we need to flash the same on to the device.
Once the project is finished, it needs to be compiled. Compiling readies the entire project’s source code for deployment. From any tab, click the hammer button in the project options menu on the top-right of the screen. You’ll see a loading message on the screen indicating compiling has started, and will be notified when the project is compiled.
You will get a confirmation at the bottom after successful compilation.
With the project compiled, your RSL10-SENSE-GEVK can be programmed with the project’s embedded firmware. Programming the RSL10-SENSE-GEVK involves using the programmer interface in Atmosphere Studio to install embedded firmware. Prior to programming a device, ensure you have completely made sure the initially specified pre-requisites are done.
Let's program our board.
Connect the JLink debugger board to the PC via USB and the RSL10-SENSE-GEVK via the provided USB cable.
While the Embedded tab is active, click the flash firmware button from the tab’s toolbar. This displays the Program Firmware window. Click Program to start programming.
If you happen to get the following prompt, it is because the JLink debugger is not properly connected to the USB. Recheck the connection or try with a new USB cable.
TIP: The board needs to be powered externally via a coin cell CR2032 battery or via external 3.3v supply. Richard LaBorde, who is an atmosphere IoT support member was of great help in assisting me to solve a lot of hurdles along the way. I wish to thank him for his support.
When complete, you’ll receive a notification stating the RSL10-SENSE-GEVK is programmed with the project’s embedded firmware.
With firmware installed, the device can now be recognized and connected to the Atmosphere network. From here, open the Atmosphere IoT app on your mobile device. We’ll use the mobile app to register the device, and eventually view the data on the project’s interface. To register the RSL10-SENSE-GEVK, navigate to the Devices area, and click the box button in the top-right of the screen to display the Add Device window. When the window opens it automatically starts scanning for available devices within range. Ensure your RSL10-SENSE-GEVK is within the range from the mobile device you are attempting to register from, otherwise, it may not appear. The list of available devices appears. Select your RSL10-SENSE-GEVK you just programmed and it will connect to the Atmosphere.
The device is now registered to the Atmosphere and added in the Devices area. The app interface we created will be displayed on the screen, with device data immediately shown on it. Since the interval in the project was set to run once per second, the readings should update every second.
Now that the device’s data is sent to the Atmosphere, let’s view it through one of the many device dashboard widgets available. We will use a data glance widget and a data graph widget to monitor the temperature data. We’ll do this directly on the device’s console page, so click on the newly-added RSL10-SENSE-GEVK to enter its console. To add a widget to the device’s dashboard, click the cogwheel button on the right side of the screen. This displays the menu of available widgets. Select the eye data glance widget to add a data glance to the dashboard. Once on the dashboard, click the widget’s 3 dot menu icon to display its menu, then click Settings. In the data glance’s settings, modify the following properties.
- Name: Give the widget a name, such as “Temperature Data.”
- Units: Enter
C
for its unit of measurement. - Icon: Select an icon that represents the data, such as the
Temperature
icon. - Color: Give the widget a color that represents the data.
In the Data Source field, click Select, then choose the following configuration options for the widget. Click the cloud storage and select the temperature dataset.
When finished click Save. The data glance is then populated with the temperature value, which updates every second. Now add a data graph widget to add a graph to the dashboard, then go to its settings.
Give the data graph a name (such as “Temperature Data”), then in its Data Source field click Select and choose the following configuration options for the widget: Select the cloud storage that is storing the data. For X-axis Value: Select the timestamp to go along the graph’s x-axis. For Y-axis Value: Select the temperature dataset to go up the graph’s y-axis. When finished click Save. This populates the data graph plotting the temperature values as time progresses. If you’d like to adjust the graph’s timeline or its bounds, you can edit those properties from the data graph’s menu as well.
The same widgets can be viewed on the mobile app from the dashboard view.
The module which we have developed is scalable and can accommodate any use-case scenario. For the making of smart band wearable, the module should be worn on the body of the subject. The best practical way of approach is to wear on the hand. To make an example, I could salvage a band from my previous smartwatch to make a carrier for the module so that it can be worn easily on the subject's hand. Since I do not own a 3D printer nor have access to any, I could print any sample band cases. So as of now, the module is attached to the band using double-sided tape.
After it was attached to the band, it can be worn with great ease.
In short, what the smart band wearable application does is that it will continuously monitor the body to measure the changes in skin temperature and would display it in real-time on the custom made application as well as the web dashboard to monitor the occurrence of possible hot flashes. It also works with the network connected temperature control device to help decrease body temperature and night sweats by regulating the ambient room temperature.
ConclusionSmart Band for Monitoring Hot flashes consists of a Smart Band module and a network-connected room temperature control device that connects to the cloud for accessing the data logged by the smart band to determine to regulate the ambient room temperature when there is a possibility of occurrence of hot flashes.
The band can be 3D printed to have a more aesthetic appeal. Even though we planned for more features to be included, due to the COVID lockdown, most of the features of the project had to be cut short owing to the inability to procure the required resources.
We certainly hope that this project serves as simple know-how for anyone who wants to monitor their daily health and activities. The project can be further extended to make use of more features of the RSL10 module to enable a much higher level application. But, here in this project, we totally focussed on body temperature regulation.
{
"name": "SmartBand",
"createVersion": "2017-08-12",
"description": "New Project",
"lastModified": "2020-03-11T23:12:22.070Z",
"created": "2020-03-11T23:12:22.070Z",
"meta": {
"projectTypeName": "RSL10-SENSE-GEVK",
"projectTypeId": "RSL10-SENSE-GEVK"
},
"planes": {
"RSL10-SENSE-GEVK": {
"type": "OnSemi",
"compilerVersion": "latest",
"variants": [
"RSL10",
"RSL10-SENSE-GEVK"
],
"meta": {},
"elements": [
{
"name": "Interval",
"type": "EmbeddedInterval",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_INTERVAL_Handle_t intervalHandle;\n ATMO_INTERVAL_AddAbilityInterval(\n\t\tATMO_PROPERTY(Interval, instance), \n\t\tATMO_ABILITY(Interval, interval), \n\t\tATMO_PROPERTY(Interval, time), \n\t\t&intervalHandle\n\t);\n\t\n\treturn ATMO_Status_Success;\n\t",
"interval": "\treturn ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"interval": false
},
"instance": "ATMO_DRIVERINSTANCE_INTERVAL_INTERVAL1",
"time": 1000
},
"meta": {
"editorX": 38,
"editorY": 388,
"lastTrigger": "interval"
},
"triggers": {
"triggered": [],
"interval": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "BME680",
"targetAbility": "readTemperature"
}
]
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"interval": true
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "interval",
"triggers": [
"interval"
]
}
]
},
{
"name": "BME680",
"type": "EmbeddedBME680",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "BME680_Config_t config;\nconfig.i2cInstance = ATMO_PROPERTY(BME680, i2cInstance );\nconfig.i2cAddr = ATMO_PROPERTY(BME680, i2cAddress );\n\nif ( !BME680_Init( &config ) )\n{\n\treturn ATMO_Status_Fail;\n}\n\nreturn ATMO_Status_Success;",
"readTemperature": "float temperature = 0.0;\n\nif ( BME680_GetTempData( &temperature ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, temperature );\n\nreturn ATMO_Status_Success;",
"readHumidity": "float humidity = 0.0;\n\nif ( BME680_GetHumidity( &humidity ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, humidity );\n\nreturn ATMO_Status_Success;",
"readPressure": "float pressure = 0.0;\n\nif ( BME680_GetPressure( &pressure ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, pressure );\n\nreturn ATMO_Status_Success;",
"readGasResistance": "float gas_resistance = 0.0;\n\nif ( BME680_GetGasRes( &gas_resistance ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, gas_resistance );\n\nreturn ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"readTemperature": false,
"readHumidity": false,
"readPressure": false,
"readGasResistance": false
},
"i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1",
"i2cAddress": "0x76"
},
"meta": {
"editorX": 212,
"editorY": 386,
"lastTrigger": "humidityRead"
},
"triggers": {
"triggered": [],
"temperatureRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "BLE_Write_Temp",
"targetAbility": "setValue"
}
],
"humidityRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "BLE_Write_Humi",
"targetAbility": "setValue"
}
],
"pressureRead": [
{
"mapping": {},
"targetOrder": [],
"targetElement": "BLE_Write_Pres",
"targetAbility": "setValue"
}
],
"gasResistanceRead": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"readTemperature": false,
"readHumidity": false,
"readPressure": false,
"readGasResistance": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "readTemperature",
"triggers": [
"temperatureRead"
]
},
{
"name": "readHumidity",
"triggers": [
"humidityRead"
]
},
{
"name": "readPressure",
"triggers": [
"pressureRead"
]
},
{
"name": "readGasResistance",
"triggers": [
"gasResistanceRead"
]
}
]
},
{
"name": "NOA1305AmbientLight",
"type": "EmbeddedNOA1305",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": " if(!NOA1305_Init(ATMO_PROPERTY(NOA1305AmbientLight, i2cInstance)))\n {\n return ATMO_Status_Fail;\n }\n\n return ATMO_Status_Success;",
"readAmbientLight": " uint32_t ambientLightLux = 0;\n if(!NOA1305_GetAmbientLight(&ambientLightLux))\n {\n return ATMO_Status_Fail;\n }\n ATMO_CreateValueUnsignedInt(out, ambientLightLux);\n return ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"readAmbientLight": false
},
"i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1"
},
"meta": {
"editorX": 24,
"editorY": 3,
"lastTrigger": "ambientLightRead"
},
"triggers": {
"triggered": [],
"ambientLightRead": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"readAmbientLight": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "readAmbientLight",
"triggers": [
"ambientLightRead"
]
}
]
},
{
"name": "EmbeddedBHI160",
"type": "EmbeddedBHI160",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": " BHI160_Config_t config;\n config.i2cInstance = ATMO_PROPERTY(EmbeddedBHI160, i2cInstance);\n config.gpioInstance = ATMO_PROPERTY(EmbeddedBHI160, gpioInstance);\n config.intPin = ATMO_PROPERTY(EmbeddedBHI160, intPin);\n\n if(!BHI160_Init(&config))\n {\n return ATMO_Status_Fail;\n }\n return ATMO_Status_Success;",
"xAcceleration": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;",
"yAcceleration": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;",
"zAcceleration": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;",
"acceleration": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;",
"angularRate": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;",
"xAngularRate": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;",
"yAngularRate": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;",
"zAngularRate": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;",
"orientation": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;",
"xOrientation": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;",
"yOrientation": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;",
"zOrientation": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;"
},
"variables": {},
"embeddedPropertyConversions": {},
"codeUserChanged": {
"setup": false,
"xAcceleration": false,
"yAcceleration": false,
"zAcceleration": false,
"acceleration": false,
"angularRate": false,
"xAngularRate": false,
"yAngularRate": false,
"zAngularRate": false,
"orientation": false,
"xOrientation": false,
"yOrientation": false,
"zOrientation": false
},
"i2cInstance": "ATMO_DRIVERINSTANCE_I2C_I2C1",
"gpioInstance": "ATMO_DRIVERINSTANCE_GPIO_GPIO1",
"intPin": 9
},
"meta": {
"editorX": 129,
"editorY": 3,
"lastTrigger": "xAccelerationRead"
},
"triggers": {
"triggered": [],
"xAccelerationRead": [],
"yAccelerationRead": [],
"zAccelerationRead": [],
"accelerationRead": [],
"angularRateRead": [],
"xAngularRateRead": [],
"yAngularRateRead": [],
"zAngularRateRead": [],
"orientationRead": [],
"xOrientationRead": [],
"yOrientationRead": [],
"zOrientationRead": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"xAcceleration": false,
"yAcceleration": false,
"zAcceleration": false,
"acceleration": false,
"angularRate": false,
"xAngularRate": false,
"yAngularRate": false,
"zAngularRate": false,
"orientation": false,
"xOrientation": false,
"yOrientation": false,
"zOrientation": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "xAcceleration",
"triggers": [
"xAccelerationRead"
]
},
{
"name": "yAcceleration",
"triggers": [
"yAccelerationRead"
]
},
{
"name": "zAcceleration",
"triggers": [
"zAccelerationRead"
]
},
{
"name": "acceleration",
"triggers": [
"accelerationRead"
]
},
{
"name": "angularRate",
"triggers": [
"angularRateRead"
]
},
{
"name": "xAngularRate",
"triggers": [
"xAngularRateRead"
]
},
{
"name": "yAngularRate",
"triggers": [
"yAngularRateRead"
]
},
{
"name": "zAngularRate",
"triggers": [
"zAngularRateRead"
]
},
{
"name": "orientation",
"triggers": [
"orientationRead"
]
},
{
"name": "xOrientation",
"triggers": [
"xOrientationRead"
]
},
{
"name": "yOrientation",
"triggers": [
"yOrientationRead"
]
},
{
"name": "zOrientation",
"triggers": [
"zOrientationRead"
]
}
]
},
{
"name": "BLE_Write_Temp",
"type": "EmbeddedBLECharacteristicCustom",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"ble"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Temp, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Temp, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Temp, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Temp, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Temp, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Temp, writeDataType), ATMO_PROPERTY(BLE_Write_Temp, readDataType), ATMO_PROPERTY(BLE_Write_Temp, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Temp, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Temp, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\tATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Temp, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
"setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Temp, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Temp, instance),\n\t\tATMO_VARIABLE(BLE_Write_Temp, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
"written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Temp, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
"subscibed": "\treturn ATMO_Status_Success;",
"unsubscribed": "\treturn ATMO_Status_Success;"
},
"variables": {
"bleServiceHandle": {
"type": "ATMO_BLE_Handle_t"
},
"bleCharacteristicHandle": {
"type": "ATMO_BLE_Handle_t"
}
},
"embeddedPropertyConversions": {
"bleServiceUuid": "string",
"bleCharacteristicUuid": "string"
},
"codeUserChanged": {
"setup": false,
"setValue": false,
"written": false,
"subscibed": false,
"unsubscribed": false
},
"instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
"bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
"bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba66",
"read": true,
"write": true,
"notify": false,
"readDataType": "ATMO_DATATYPE_FLOAT",
"writeDataType": "ATMO_DATATYPE_FLOAT",
"notifyDataType": "ATMO_DATATYPE_STRING"
},
"meta": {
"editorX": 395,
"editorY": 281,
"lastTrigger": "written"
},
"triggers": {
"triggered": [],
"written": [],
"subscibed": [],
"unsubscribed": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"setValue": "valueSet",
"written": false,
"subscibed": false,
"unsubscribed": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setValue",
"triggers": []
},
{
"name": "written",
"triggers": [
"written"
]
},
{
"name": "subscibed",
"triggers": [
"subscibed"
]
},
{
"name": "unsubscribed",
"triggers": [
"unsubscribed"
]
}
]
},
{
"name": "BLE_Write_Pres",
"type": "EmbeddedBLECharacteristicCustom",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"ble"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Pres, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Pres, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Pres, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Pres, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Pres, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Pres, writeDataType), ATMO_PROPERTY(BLE_Write_Pres, readDataType), ATMO_PROPERTY(BLE_Write_Pres, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Pres, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Pres, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\tATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Pres, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
"setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Pres, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Pres, instance),\n\t\tATMO_VARIABLE(BLE_Write_Pres, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
"written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Pres, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
"subscibed": "\treturn ATMO_Status_Success;",
"unsubscribed": "\treturn ATMO_Status_Success;"
},
"variables": {
"bleServiceHandle": {
"type": "ATMO_BLE_Handle_t"
},
"bleCharacteristicHandle": {
"type": "ATMO_BLE_Handle_t"
}
},
"embeddedPropertyConversions": {
"bleServiceUuid": "string",
"bleCharacteristicUuid": "string"
},
"codeUserChanged": {
"setup": false,
"setValue": false,
"written": false,
"subscibed": false,
"unsubscribed": false
},
"instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
"bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
"bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba67",
"read": true,
"write": true,
"notify": false,
"readDataType": "ATMO_DATATYPE_FLOAT",
"writeDataType": "ATMO_DATATYPE_FLOAT",
"notifyDataType": "ATMO_DATATYPE_STRING"
},
"meta": {
"editorX": 397,
"editorY": 386,
"lastTrigger": "written"
},
"triggers": {
"triggered": [],
"written": [],
"subscibed": [],
"unsubscribed": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"setValue": "valueSet",
"written": false,
"subscibed": false,
"unsubscribed": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setValue",
"triggers": []
},
{
"name": "written",
"triggers": [
"written"
]
},
{
"name": "subscibed",
"triggers": [
"subscibed"
]
},
{
"name": "unsubscribed",
"triggers": [
"unsubscribed"
]
}
]
},
{
"name": "BLE_Write_Humi",
"type": "EmbeddedBLECharacteristicCustom",
"variants": [
"embedded",
"triggers",
"abilities",
"properties",
"variables",
"ble"
],
"properties": {
"errorData": {},
"code": {
"trigger": "\treturn ATMO_Status_Success;",
"setup": "\n\tATMO_BLE_GATTSAddService(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Humi, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Humi, bleServiceUuid));\n\t\n\tuint8_t property = 0;\n\tuint8_t permission = 0;\n\t\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, read) ? ATMO_BLE_Property_Read : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, write) ? ATMO_BLE_Property_Write : 0;\n\tproperty |= ATMO_PROPERTY(BLE_Write_Humi, notify) ? ATMO_BLE_Property_Notify : 0;\n\n\tpermission |= ATMO_PROPERTY(BLE_Write_Humi, read) ? ATMO_BLE_Permission_Read : 0;\n\tpermission |= ATMO_PROPERTY(BLE_Write_Humi, write) ? ATMO_BLE_Permission_Write : 0;\n\n\tATMO_DATATYPE types[3] = {ATMO_PROPERTY(BLE_Write_Humi, writeDataType), ATMO_PROPERTY(BLE_Write_Humi, readDataType), ATMO_PROPERTY(BLE_Write_Humi, notifyDataType)};\n\t\n\tATMO_BLE_GATTSAddCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\t&ATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle), \n\t\tATMO_VARIABLE(BLE_Write_Humi, bleServiceHandle), \n\t\tATMO_PROPERTY(BLE_Write_Humi, bleCharacteristicUuid), \n\t\tproperty, permission, ATMO_GetMaxValueSize(3, 64, types));\n\t\n\tATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\tATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle), \n\t\tATMO_BLE_Characteristic_Written, \n\t\tATMO_ABILITY(BLE_Write_Humi, written));\n\t\n\treturn ATMO_Status_Success;\n\t",
"setValue": "\n\t\n\t// Convert to the desired write data type\n\tATMO_Value_t convertedValue;\n\tATMO_InitValue(&convertedValue);\n\tATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(BLE_Write_Humi, readDataType), in);\n\n\tATMO_BLE_GATTSSetCharacteristic(\n\t\tATMO_PROPERTY(BLE_Write_Humi, instance),\n\t\tATMO_VARIABLE(BLE_Write_Humi, bleCharacteristicHandle),\n\t\tconvertedValue.size, \n\t\t(uint8_t *)convertedValue.data,\n\t\tNULL);\n\t\n\tATMO_FreeValue(&convertedValue);\n\t\t\n\treturn ATMO_Status_Success;\n\t",
"written": "\n\tATMO_CreateValueConverted(out, ATMO_PROPERTY(BLE_Write_Humi, writeDataType), in);\n\treturn ATMO_Status_Success;\n\t",
"subscibed": "\treturn ATMO_Status_Success;",
"unsubscribed": "\treturn ATMO_Status_Success;"
},
"variables": {
"bleServiceHandle": {
"type": "ATMO_BLE_Handle_t"
},
"bleCharacteristicHandle": {
"type": "ATMO_BLE_Handle_t"
}
},
"embeddedPropertyConversions": {
"bleServiceUuid": "string",
"bleCharacteristicUuid": "string"
},
"codeUserChanged": {
"setup": false,
"setValue": false,
"written": false,
"subscibed": false,
"unsubscribed": false
},
"instance": "ATMO_DRIVERINSTANCE_BLE_BLE1",
"bleServiceUuid": "dbc7024c-dede-49a1-8dd8-43238503ba65",
"bleCharacteristicUuid": "dbc7024c-dede-49a1-8dd8-43238503ba68",
"read": true,
"write": true,
"notify": false,
"readDataType": "ATMO_DATATYPE_FLOAT",
"writeDataType": "ATMO_DATATYPE_FLOAT",
"notifyDataType": "ATMO_DATATYPE_STRING"
},
"meta": {
"editorX": 398,
"editorY": 499,
"lastTrigger": "written"
},
"triggers": {
"triggered": [],
"written": [],
"subscibed": [],
"unsubscribed": []
},
"interruptAbilities": {
"trigger": false,
"setup": false,
"setValue": "valueSet",
"written": false,
"subscibed": false,
"unsubscribed": false
},
"abilities": [
{
"name": "trigger",
"triggers": [
"triggered"
]
},
{
"name": "setup",
"triggers": []
},
{
"name": "setValue",
"triggers": []
},
{
"name": "written",
"triggers": [
"written"
]
},
{
"name": "subscibed",
"triggers": [
"subscibed"
]
},
{
"name": "unsubscribed",
"triggers": [
"unsubscribed"
]
}
]
}
],
"libraries": {
"bme680": {
"libName": "bme680",
"manufacturer": "Bosch",
"description": "BME680 is a low power gas, pressure, temperature and humidity sensor",
"type": "Environmental sensor",
"icon": "EmbeddedTempHumidity.svg",
"version": "",
"eelVersion": "3",
"shoppingCartLinks": {
"digikey": {
"links": {
"info": "https://www.digikey.com/product-detail/en/bosch-sensortec/SHUTTLE-BOARD-BME680/828-1078-ND/7401318"
},
"cartData": {
"part": "828-1078-ND",
"source": "dkstudio",
"qty": "1"
}
}
},
"requires": [
"embedded",
"i2c"
],
"elements": [
{
"name": "BME680",
"type": "EmbeddedBME680",
"icon": "EmbeddedTempHumidity.svg",
"defaultAbility": "readTemperature",
"defaultTrigger": "temperatureRead",
"hidden": false,
"abilities": [
{
"name": "setup",
"hidden": true,
"code": "BME680_Config_t config;\nconfig.i2cInstance = ATMO_PROPERTY( undefined, i2cInstance );\nconfig.i2cAddr = ATMO_PROPERTY( undefined, i2cAddress );\n\nif ( !BME680_Init( &config ) )\n{\n\treturn ATMO_Status_Fail;\n}\n\nreturn ATMO_Status_Success;"
},
{
"name": "readTemperature",
"triggers": [
"temperatureRead"
],
"code": "float temperature = 0.0;\n\nif ( BME680_GetTempData( &temperature ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, temperature );\n\nreturn ATMO_Status_Success;"
},
{
"name": "readHumidity",
"triggers": [
"humidityRead"
],
"code": "float humidity = 0.0;\n\nif ( BME680_GetHumidity( &humidity ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, humidity );\n\nreturn ATMO_Status_Success;"
},
{
"name": "readPressure",
"triggers": [
"pressureRead"
],
"code": "float pressure = 0.0;\n\nif ( BME680_GetPressure( &pressure ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, pressure );\n\nreturn ATMO_Status_Success;"
},
{
"name": "readGasResistance",
"triggers": [
"gasResistanceRead"
],
"code": "float gas_resistance = 0.0;\n\nif ( BME680_GetGasRes( &gas_resistance ) != BME680_Status_Success )\n{\n\treturn ATMO_Status_Fail;\n}\n\nATMO_CreateValueFloat( out, gas_resistance );\n\nreturn ATMO_Status_Success;"
}
],
"properties": [
{
"name": "i2cInstance",
"input": "driverInstance",
"driverType": "i2c"
},
{
"name": "i2cAddress",
"input": "select",
"inputOptions": [
"0x76",
"0x77"
],
"value": "0x76"
}
],
"triggers": [],
"variables": [],
"language": {
"en-US": {
"EmbeddedBME680": "BME680 Environmental",
"i2cInstance": "I2C Driver Instance",
"i2cAddress": "I2C Address",
"setup": "Setup",
"readTemperature": "Read Temperature (C)",
"temperatureRead": "Temperature Read",
"readHumidity": "Read Humidity (%rh)",
"humidityRead": "Humidity Read",
"readPressure": "Read Pressure (Pa)",
"pressureRead": "Pressure Read",
"readGasResistance": "Read Gas Resistance (ohm)",
"gasResistanceRead": "Gas Resistance Read"
}
}
}
],
"files": {
"common": {
"headers": {
"bme680.h": "#ifndef ATMO_BME680_H_\n#define ATMO_BME680_H_\n\n#include \"../app_src/atmosphere_platform.h\"\n\ntypedef struct\n{\n\tATMO_DriverInstanceHandle_t i2cInstance;\n\tuint8_t i2cAddr;\n} BME680_Config_t;\n\ntypedef enum\n{\n\tBME680_Status_Success = 0,\n\tBME680_Status_Fail\n} BME680_Status_t;\n\nBME680_Status_t BME680_Init( BME680_Config_t *config );\n\nBME680_Status_t BME680_GetPressure( float *pressureHpa );\n\nBME680_Status_t BME680_GetTempData( float *tempC );\n\nBME680_Status_t BME680_GetHumidity( float *humidity );\n\nBME680_Status_t BME680_GetGasRes( float *gas_resistance );\n\n#endif\n",
"bme680_defs.h": "/**\n * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of the copyright holder nor the names of the\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER\n * OR CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\n *\n * The information provided is believed to be accurate and reliable.\n * The copyright holder assumes no responsibility\n * for the consequences of use\n * of such information nor for any infringement of patents or\n * other rights of third parties which may result from its use.\n * No license is granted by implication or otherwise under any patent or\n * patent rights of the copyright holder.\n *\n * @file\tbme680_defs.h\n * @date\t22 Feb 2018\n * @version\t3.5.8\n * @brief\n *\n */\n\n/*! @file bme680_defs.h\n @brief Sensor driver for BME680 sensor */\n/*!\n * @defgroup BME680_DRIVER_GRP BME680 SENSOR API\n * @brief\n * @{*/\n#ifndef BME680_DEFS_H_\n#define BME680_DEFS_H_\n\n/********************************************************/\n/* header includes */\n#ifdef __KERNEL__\n#include <linux/types.h>\n#include <linux/kernel.h>\n#else\n#include \"../app_src/atmosphere_platform.h\"\n#endif\n\n/******************************************************************************/\n/*! @name\t\tCommon macros\t\t\t\t\t */\n/******************************************************************************/\n\n#if !defined(UINT8_C) && !defined(INT8_C)\n#define INT8_C(x) S8_C(x)\n#define UINT8_C(x) U8_C(x)\n#endif\n\n#if !defined(UINT16_C) && !defined(INT16_C)\n#define INT16_C(x) S16_C(x)\n#define UINT16_C(x) U16_C(x)\n#endif\n\n#if !defined(INT32_C) && !defined(UINT32_C)\n#define INT32_C(x) S32_C(x)\n#define UINT32_C(x) U32_C(x)\n#endif\n\n#if !defined(INT64_C) && !defined(UINT64_C)\n#define INT64_C(x) S64_C(x)\n#define UINT64_C(x) U64_C(x)\n#endif\n\n/**@}*/\n\n/**\\name C standard macros */\n#ifndef NULL\n#ifdef __cplusplus\n#define NULL 0\n#else\n#define NULL ((void *) 0)\n#endif\n#endif\n\n/** BME680 configuration macros */\n/** Enable or un-comment the macro to provide floating point data output */\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n#define BME680_FLOAT_POINT_COMPENSATION\n#endif\n\n/** BME680 General config */\n#define BME680_POLL_PERIOD_MS\t\tUINT8_C(10)\n\n/** BME680 I2C addresses */\n#define BME680_I2C_ADDR_PRIMARY\t\tUINT8_C(0x76)\n#define BME680_I2C_ADDR_SECONDARY\tUINT8_C(0x77)\n\n/** BME680 unique chip identifier */\n#define BME680_CHIP_ID UINT8_C(0x61)\n\n/** BME680 coefficients related defines */\n#define BME680_COEFF_SIZE\t\tUINT8_C(41)\n#define BME680_COEFF_ADDR1_LEN\t\tUINT8_C(25)\n#define BME680_COEFF_ADDR2_LEN\t\tUINT8_C(16)\n\n/** BME680 field_x related defines */\n#define BME680_FIELD_LENGTH\t\tUINT8_C(15)\n#define BME680_FIELD_ADDR_OFFSET\tUINT8_C(17)\n\n/** Soft reset command */\n#define BME680_SOFT_RESET_CMD UINT8_C(0xb6)\n\n/** Error code definitions */\n#define BME680_OK\t\tINT8_C(0)\n/* Errors */\n#define BME680_E_NULL_PTR\t\t INT8_C(-1)\n#define BME680_E_COM_FAIL\t\t INT8_C(-2)\n#define BME680_E_DEV_NOT_FOUND\t\tINT8_C(-3)\n#define BME680_E_INVALID_LENGTH\t\tINT8_C(-4)\n\n/* Warnings */\n#define BME680_W_DEFINE_PWR_MODE\tINT8_C(1)\n#define BME680_W_NO_NEW_DATA INT8_C(2)\n\n/* Info's */\n#define BME680_I_MIN_CORRECTION\t\tUINT8_C(1)\n#define BME680_I_MAX_CORRECTION\t\tUINT8_C(2)\n\n/** Register map */\n/** Other coefficient's address */\n#define BME680_ADDR_RES_HEAT_VAL_ADDR\tUINT8_C(0x00)\n#define BME680_ADDR_RES_HEAT_RANGE_ADDR\tUINT8_C(0x02)\n#define BME680_ADDR_RANGE_SW_ERR_ADDR\tUINT8_C(0x04)\n#define BME680_ADDR_SENS_CONF_START\tUINT8_C(0x5A)\n#define BME680_ADDR_GAS_CONF_START\tUINT8_C(0x64)\n\n/** Field settings */\n#define BME680_FIELD0_ADDR\t\tUINT8_C(0x1d)\n\n/** Heater settings */\n#define BME680_RES_HEAT0_ADDR\t\tUINT8_C(0x5a)\n#define BME680_GAS_WAIT0_ADDR\t\tUINT8_C(0x64)\n\n/** Sensor configuration registers */\n#define BME680_CONF_HEAT_CTRL_ADDR\t\tUINT8_C(0x70)\n#define BME680_CONF_ODR_RUN_GAS_NBC_ADDR\tUINT8_C(0x71)\n#define BME680_CONF_OS_H_ADDR\t\t\tUINT8_C(0x72)\n#define BME680_MEM_PAGE_ADDR\t\t\tUINT8_C(0xf3)\n#define BME680_CONF_T_P_MODE_ADDR\t\tUINT8_C(0x74)\n#define BME680_CONF_ODR_FILT_ADDR\t\tUINT8_C(0x75)\n\n/** Coefficient's address */\n#define BME680_COEFF_ADDR1\tUINT8_C(0x89)\n#define BME680_COEFF_ADDR2\tUINT8_C(0xe1)\n\n/** Chip identifier */\n#define BME680_CHIP_ID_ADDR\tUINT8_C(0xd0)\n\n/** Soft reset register */\n#define BME680_SOFT_RESET_ADDR\t\tUINT8_C(0xe0)\n\n/** Heater control settings */\n#define BME680_ENABLE_HEATER\t\tUINT8_C(0x00)\n#define BME680_DISABLE_HEATER\t\tUINT8_C(0x08)\n\n/** Gas measurement settings */\n#define BME680_DISABLE_GAS_MEAS\t\tUINT8_C(0x00)\n#define BME680_ENABLE_GAS_MEAS\t\tUINT8_C(0x01)\n\n/** Over-sampling settings */\n#define BME680_OS_NONE\t\tUINT8_C(0)\n#define BME680_OS_1X\t\tUINT8_C(1)\n#define BME680_OS_2X\t\tUINT8_C(2)\n#define BME680_OS_4X\t\tUINT8_C(3)\n#define BME680_OS_8X\t\tUINT8_C(4)\n#define BME680_OS_16X\t\tUINT8_C(5)\n\n/** IIR filter settings */\n#define BME680_FILTER_SIZE_0\tUINT8_C(0)\n#define BME680_FILTER_SIZE_1\tUINT8_C(1)\n#define BME680_FILTER_SIZE_3\tUINT8_C(2)\n#define BME680_FILTER_SIZE_7\tUINT8_C(3)\n#define BME680_FILTER_SIZE_15\tUINT8_C(4)\n#define BME680_FILTER_SIZE_31\tUINT8_C(5)\n#define BME680_FILTER_SIZE_63\tUINT8_C(6)\n#define BME680_FILTER_SIZE_127\tUINT8_C(7)\n\n/** Power mode settings */\n#define BME680_SLEEP_MODE\tUINT8_C(0)\n#define BME680_FORCED_MODE\tUINT8_C(1)\n\n/** Delay related macro declaration */\n#define BME680_RESET_PERIOD\tUINT32_C(10)\n\n/** SPI memory page settings */\n#define BME680_MEM_PAGE0\tUINT8_C(0x10)\n#define BME680_MEM_PAGE1\tUINT8_C(0x00)\n\n/** Ambient humidity shift value for compensation */\n#define BME680_HUM_REG_SHIFT_VAL\tUINT8_C(4)\n\n/** Run gas enable and disable settings */\n#define BME680_RUN_GAS_DISABLE\tUINT8_C(0)\n#define BME680_RUN_GAS_ENABLE\tUINT8_C(1)\n\n/** Buffer length macro declaration */\n#define BME680_TMP_BUFFER_LENGTH\tUINT8_C(40)\n#define BME680_REG_BUFFER_LENGTH\tUINT8_C(6)\n#define BME680_FIELD_DATA_LENGTH\tUINT8_C(3)\n#define BME680_GAS_REG_BUF_LENGTH\tUINT8_C(20)\n\n/** Settings selector */\n#define BME680_OST_SEL\t\t\tUINT16_C(1)\n#define BME680_OSP_SEL\t\t\tUINT16_C(2)\n#define BME680_OSH_SEL\t\t\tUINT16_C(4)\n#define BME680_GAS_MEAS_SEL\t\tUINT16_C(8)\n#define BME680_FILTER_SEL\t\tUINT16_C(16)\n#define BME680_HCNTRL_SEL\t\tUINT16_C(32)\n#define BME680_RUN_GAS_SEL\t\tUINT16_C(64)\n#define BME680_NBCONV_SEL\t\tUINT16_C(128)\n#define BME680_GAS_SENSOR_SEL\t\t(BME680_GAS_MEAS_SEL | BME680_RUN_GAS_SEL | BME680_NBCONV_SEL)\n\n/** Number of conversion settings*/\n#define BME680_NBCONV_MIN\t\tUINT8_C(0)\n#define BME680_NBCONV_MAX\t\tUINT8_C(10)\n\n/** Mask definitions */\n#define BME680_GAS_MEAS_MSK\tUINT8_C(0x30)\n#define BME680_NBCONV_MSK\tUINT8_C(0X0F)\n#define BME680_FILTER_MSK\tUINT8_C(0X1C)\n#define BME680_OST_MSK\t\tUINT8_C(0XE0)\n#define BME680_OSP_MSK\t\tUINT8_C(0X1C)\n#define BME680_OSH_MSK\t\tUINT8_C(0X07)\n#define BME680_HCTRL_MSK\tUINT8_C(0x08)\n#define BME680_RUN_GAS_MSK\tUINT8_C(0x10)\n#define BME680_MODE_MSK\t\tUINT8_C(0x03)\n#define BME680_RHRANGE_MSK\tUINT8_C(0x30)\n#define BME680_RSERROR_MSK\tUINT8_C(0xf0)\n#define BME680_NEW_DATA_MSK\tUINT8_C(0x80)\n#define BME680_GAS_INDEX_MSK\tUINT8_C(0x0f)\n#define BME680_GAS_RANGE_MSK\tUINT8_C(0x0f)\n#define BME680_GASM_VALID_MSK\tUINT8_C(0x20)\n#define BME680_HEAT_STAB_MSK\tUINT8_C(0x10)\n#define BME680_MEM_PAGE_MSK\tUINT8_C(0x10)\n#define BME680_SPI_RD_MSK\tUINT8_C(0x80)\n#define BME680_SPI_WR_MSK\tUINT8_C(0x7f)\n#define\tBME680_BIT_H1_DATA_MSK\tUINT8_C(0x0F)\n\n/** Bit position definitions for sensor settings */\n#define BME680_GAS_MEAS_POS\tUINT8_C(4)\n#define BME680_FILTER_POS\tUINT8_C(2)\n#define BME680_OST_POS\t\tUINT8_C(5)\n#define BME680_OSP_POS\t\tUINT8_C(2)\n#define BME680_RUN_GAS_POS\tUINT8_C(4)\n\n/** Array Index to Field data mapping for Calibration Data*/\n#define BME680_T2_LSB_REG\t(1)\n#define BME680_T2_MSB_REG\t(2)\n#define BME680_T3_REG\t\t(3)\n#define BME680_P1_LSB_REG\t(5)\n#define BME680_P1_MSB_REG\t(6)\n#define BME680_P2_LSB_REG\t(7)\n#define BME680_P2_MSB_REG\t(8)\n#define BME680_P3_REG\t\t(9)\n#define BME680_P4_LSB_REG\t(11)\n#define BME680_P4_MSB_REG\t(12)\n#define BME680_P5_LSB_REG\t(13)\n#define BME680_P5_MSB_REG\t(14)\n#define BME680_P7_REG\t\t(15)\n#define BME680_P6_REG\t\t(16)\n#define BME680_P8_LSB_REG\t(19)\n#define BME680_P8_MSB_REG\t(20)\n#define BME680_P9_LSB_REG\t(21)\n#define BME680_P9_MSB_REG\t(22)\n#define BME680_P10_REG\t\t(23)\n#define BME680_H2_MSB_REG\t(25)\n#define BME680_H2_LSB_REG\t(26)\n#define BME680_H1_LSB_REG\t(26)\n#define BME680_H1_MSB_REG\t(27)\n#define BME680_H3_REG\t\t(28)\n#define BME680_H4_REG\t\t(29)\n#define BME680_H5_REG\t\t(30)\n#define BME680_H6_REG\t\t(31)\n#define BME680_H7_REG\t\t(32)\n#define BME680_T1_LSB_REG\t(33)\n#define BME680_T1_MSB_REG\t(34)\n#define BME680_GH2_LSB_REG\t(35)\n#define BME680_GH2_MSB_REG\t(36)\n#define BME680_GH1_REG\t\t(37)\n#define BME680_GH3_REG\t\t(38)\n\n/** BME680 register buffer index settings*/\n#define BME680_REG_FILTER_INDEX\t\tUINT8_C(5)\n#define BME680_REG_TEMP_INDEX\t\tUINT8_C(4)\n#define BME680_REG_PRES_INDEX\t\tUINT8_C(4)\n#define BME680_REG_HUM_INDEX\t\tUINT8_C(2)\n#define BME680_REG_NBCONV_INDEX\t\tUINT8_C(1)\n#define BME680_REG_RUN_GAS_INDEX\tUINT8_C(1)\n#define BME680_REG_HCTRL_INDEX\t\tUINT8_C(0)\n\n/** BME680 pressure calculation macros */\n/*! This max value is used to provide precedence to multiplication or division\n * in pressure compensation equation to achieve least loss of precision and\n * avoiding overflows.\n * i.e Comparing value, BME680_MAX_OVERFLOW_VAL = INT32_C(1 << 30)\n */\n#define BME680_MAX_OVERFLOW_VAL INT32_C(0x40000000)\n\n/** Macro to combine two 8 bit data's to form a 16 bit data */\n#define BME680_CONCAT_BYTES(msb, lsb)\t(((uint16_t)msb << 8) | (uint16_t)lsb)\n\n/** Macro to SET and GET BITS of a register */\n#define BME680_SET_BITS(reg_data, bitname, data) \\\n\t\t((reg_data & ~(bitname##_MSK)) | \\\n\t\t((data << bitname##_POS) & bitname##_MSK))\n#define BME680_GET_BITS(reg_data, bitname)\t((reg_data & (bitname##_MSK)) >> \\\n\t(bitname##_POS))\n\n/** Macro variant to handle the bitname position if it is zero */\n#define BME680_SET_BITS_POS_0(reg_data, bitname, data) \\\n\t\t\t\t((reg_data & ~(bitname##_MSK)) | \\\n\t\t\t\t(data & bitname##_MSK))\n#define BME680_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK))\n\n/** Type definitions */\n/*!\n * Generic communication function pointer\n * @param[in] dev_id: Place holder to store the id of the device structure\n * Can be used to store the index of the Chip select or\n * I2C address of the device.\n * @param[in] reg_addr:\tUsed to select the register the where data needs to\n * be read from or written to.\n * @param[in/out] reg_data: Data array to read/write\n * @param[in] len: Length of the data array\n */\ntypedef int8_t ( *bme680_com_fptr_t )( uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len );\n\n/*!\n * Delay function pointer\n * @param[in] period: Time period in milliseconds\n */\ntypedef void ( *bme680_delay_fptr_t )( uint32_t period );\n\n/*!\n * @brief Interface selection Enumerations\n */\nenum bme680_intf\n{\n\t/*! SPI interface */\n\tBME680_SPI_INTF,\n\t/*! I2C interface */\n\tBME680_I2C_INTF\n};\n\n/* structure definitions */\n/*!\n * @brief Sensor field data structure\n */\nstruct\tbme680_field_data\n{\n\t/*! Contains new_data, gasm_valid & heat_stab */\n\tuint8_t status;\n\t/*! The index of the heater profile used */\n\tuint8_t gas_index;\n\t/*! Measurement index to track order */\n\tuint8_t meas_index;\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\t/*! Temperature in degree celsius x100 */\n\tint16_t temperature;\n\t/*! Pressure in Pascal */\n\tuint32_t pressure;\n\t/*! Humidity in % relative humidity x1000 */\n\tuint32_t humidity;\n\t/*! Gas resistance in Ohms */\n\tuint32_t gas_resistance;\n#else\n\t/*! Temperature in degree celsius */\n\tfloat temperature;\n\t/*! Pressure in Pascal */\n\tfloat pressure;\n\t/*! Humidity in % relative humidity x1000 */\n\tfloat humidity;\n\t/*! Gas resistance in Ohms */\n\tfloat gas_resistance;\n\n#endif\n\n};\n\n/*!\n * @brief Structure to hold the Calibration data\n */\nstruct\tbme680_calib_data\n{\n\t/*! Variable to store calibrated humidity data */\n\tuint16_t par_h1;\n\t/*! Variable to store calibrated humidity data */\n\tuint16_t par_h2;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h3;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h4;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h5;\n\t/*! Variable to store calibrated humidity data */\n\tuint8_t par_h6;\n\t/*! Variable to store calibrated humidity data */\n\tint8_t par_h7;\n\t/*! Variable to store calibrated gas data */\n\tint8_t par_gh1;\n\t/*! Variable to store calibrated gas data */\n\tint16_t par_gh2;\n\t/*! Variable to store calibrated gas data */\n\tint8_t par_gh3;\n\t/*! Variable to store calibrated temperature data */\n\tuint16_t par_t1;\n\t/*! Variable to store calibrated temperature data */\n\tint16_t par_t2;\n\t/*! Variable to store calibrated temperature data */\n\tint8_t par_t3;\n\t/*! Variable to store calibrated pressure data */\n\tuint16_t par_p1;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p2;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p3;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p4;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p5;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p6;\n\t/*! Variable to store calibrated pressure data */\n\tint8_t par_p7;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p8;\n\t/*! Variable to store calibrated pressure data */\n\tint16_t par_p9;\n\t/*! Variable to store calibrated pressure data */\n\tuint8_t par_p10;\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\t/*! Variable to store t_fine size */\n\tint32_t t_fine;\n#else\n\t/*! Variable to store t_fine size */\n\tfloat t_fine;\n#endif\n\t/*! Variable to store heater resistance range */\n\tuint8_t res_heat_range;\n\t/*! Variable to store heater resistance value */\n\tint8_t res_heat_val;\n\t/*! Variable to store error range */\n\tint8_t range_sw_err;\n};\n\n/*!\n * @brief BME680 sensor settings structure which comprises of ODR,\n * over-sampling and filter settings.\n */\nstruct\tbme680_tph_sett\n{\n\t/*! Humidity oversampling */\n\tuint8_t os_hum;\n\t/*! Temperature oversampling */\n\tuint8_t os_temp;\n\t/*! Pressure oversampling */\n\tuint8_t os_pres;\n\t/*! Filter coefficient */\n\tuint8_t filter;\n};\n\n/*!\n * @brief BME680 gas sensor which comprises of gas settings\n * and status parameters\n */\nstruct\tbme680_gas_sett\n{\n\t/*! Variable to store nb conversion */\n\tuint8_t nb_conv;\n\t/*! Variable to store heater control */\n\tuint8_t heatr_ctrl;\n\t/*! Run gas enable value */\n\tuint8_t run_gas;\n\t/*! Heater temperature value */\n\tuint16_t heatr_temp;\n\t/*! Duration profile value */\n\tuint16_t heatr_dur;\n};\n\n/*!\n * @brief BME680 device structure\n */\nstruct\tbme680_dev\n{\n\t/*! Chip Id */\n\tuint8_t chip_id;\n\t/*! Device Id */\n\tuint8_t dev_id;\n\t/*! SPI/I2C interface */\n\tenum bme680_intf intf;\n\t/*! Memory page used */\n\tuint8_t mem_page;\n\t/*! Ambient temperature in Degree C */\n\tint8_t amb_temp;\n\t/*! Sensor calibration data */\n\tstruct bme680_calib_data calib;\n\t/*! Sensor settings */\n\tstruct bme680_tph_sett tph_sett;\n\t/*! Gas Sensor settings */\n\tstruct bme680_gas_sett gas_sett;\n\t/*! Sensor power modes */\n\tuint8_t power_mode;\n\t/*! New sensor fields */\n\tuint8_t new_fields;\n\t/*! Store the info messages */\n\tuint8_t info_msg;\n\t/*! Bus read function pointer */\n\tbme680_com_fptr_t read;\n\t/*! Bus write function pointer */\n\tbme680_com_fptr_t write;\n\t/*! delay function pointer */\n\tbme680_delay_fptr_t delay_ms;\n\t/*! Communication function result */\n\tint8_t com_rslt;\n};\n\n\n\n#endif /* BME680_DEFS_H_ */\n/** @}*/\n/** @}*/\n",
"bme680_env.h": "//-----------------------------------------------------------------------------\n// Copyright (c) 2018 Semiconductor Components Industries LLC\n// (d/b/a \"ON Semiconductor\"). All rights reserved.\n// This software and/or documentation is licensed by ON Semiconductor under\n// limited terms and conditions. The terms and conditions pertaining to the\n// software and/or documentation are available at\n// http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf (\"ON Semiconductor Standard\n// Terms and Conditions of Sale, Section 8 Software\") and if applicable the\n// software license agreement. Do not use this software and/or documentation\n// unless you have carefully read and you agree to the limited terms and\n// conditions. By using this software and/or documentation, you agree to the\n// limited terms and conditions.\n//-----------------------------------------------------------------------------\n//! \\file RTE_BDK_BME680_ENV.h\n//!\n//! This file contains the Run Time Configuration (RTE) options for BME680_ENV\n//! CMSIS Component.\n//!\n//! These options can be edited by opening this file in CMSIS Configuration\n//! Wizard Editor that is part of Eclipse installation.\n//!\n//! \\addtogroup BDK_GRP\n//! \\{\n//! \\addtogroup COMPONENTS\n//! \\{\n//! \\addtogroup BME680_ENV_GRP\n//! \\{\n//! \\name Run Time Environment Configuration\n//!\n//! These parameters are part of the \\ref RTE_BME680_ENV.h RTE configuration\n//! file and can be used to adjust library behavior.\n//! This file is copied into the Eclipse project when the BME680_ENV component\n//! is selected and can be edited by using the <i>CMIS Configuration Wizard</i>\n//! editor.\n//!\n//! \\image html rte_bme680_env.jpg\n//!\n//-----------------------------------------------------------------------------\n\n#ifndef RTE_BME680_ENV_H_\n#define RTE_BME680_ENV_H_\n\n// <<< Use Configuration Wizard in Context Menu >>>\n\n/** \\def RTE_BME680_ENV_TEMP_ENABLE\n * \\brief Enables or disables temperature measurement.\n *\n * Disabling is discouraged as other measurements depend on temperature\n * measurement for calibration.\n *\n * If disabled a constant value of INT16_MAX will be reported in\n * \\ref BME680_ENV_Data::temperature.\n */\n// <e> Temperature measurement\n// <i> Enables temperature measurement.\n// <i> Disabling is discouraged as other measurements depend on temperature measurement for calibration.\n// <i> If disabled a constant value of INT16_MAX will be reported.\n#ifndef RTE_BME680_ENV_TEMP_ENABLE\n#define RTE_BME680_ENV_TEMP_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_TEMP_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_TEMP\n * \\brief Temperature measurement oversampling setting.\n *\n * Oversampling improves temperature measurement resolution by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.1 Temperature Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Oversampling improves temperature measurement resolution by reducing noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.1 Temperature Measurement' of BME680 datasheet for more details.\n// <1=> 1x\n// <2=> 2x\n// <3=> 4x\n// <4=> 8x\n// <5=> 16x\n#define RTE_BME680_ENV_OS_TEMP 2\n\n#else\n#define RTE_BME680_ENV_OS_TEMP 0\n#endif /* defined RTE_BME680_ENV_TEMP_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_PRES_ENABLE\n * \\brief Enables or disables pressure measurement.\n *\n * If disabled a constant value of UINT32_MAX will be reported in\n * \\ref BME680_ENV_Data::pressure.\n */\n// <e> Pressure measurement\n// <i> Enables pressure measurement.\n// <i> If disabled a constant value of UINT32_MAX will be reported.\n#ifndef RTE_BME680_ENV_PRES_ENABLE\n#define RTE_BME680_ENV_PRES_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_PRES_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_PRES\n * \\brief Pressure measurement oversampling setting.\n *\n * Oversampling improves pressure measurement resolution by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.2 Pressure Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Oversampling improves pressure measurement resolution by reducing noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.2 Pressure Measurement' of BME680 datasheet for more details.\n// <1=> 1x\n// <2=> 2x\n// <3=> 4x\n// <4=> 8x\n// <5=> 16x\n#define RTE_BME680_ENV_OS_PRES 2\n\n#else\n#define RTE_BME680_ENV_OS_PRES 0\n#endif /* defined RTE_BME680_ENV_PRES_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_HUM_ENABLE\n * \\brief Enables or disables humidity measurement.\n *\n * If disabled a constant value of UINT32_MAX will be reported in\n * \\ref BME680_ENV_Data::humidity.\n */\n// <e> Humidity measurement\n// <i> Enables humidity measurement\n// <i> If disabled a constant value of UINT32_MAX will be reported.\n#ifndef RTE_BME680_ENV_HUM_ENABLE\n#define RTE_BME680_ENV_HUM_ENABLE 1\n#endif\n\n#if defined RTE_BME680_ENV_HUM_ENABLE == 1\n\n/** \\def RTE_BME680_ENV_OS_HUM\n * \\brief Humidity measurement oversampling setting.\n *\n * Oversampling improves humidity measurement by reducing noise.\n * Higher oversampling values will result in longer measurement duration.\n *\n * \\see\n * Section <b>3.3.3 Humidity Measurement</b> of BME680 datasheet for more\n * details.\n */\n// <o> Oversampling\n// <i> Higher oversampling setting reduces noise.\n// <i> Higher oversampling values will result in longer measurement duration.\n// <i> See section '3.3.3 Humidity Measurement' of BME680 datasheet for more details.\n// <1=> 1x\n// <2=> 2x\n// <3=> 4x\n// <4=> 8x\n// <5=> 16x\n#ifndef RTE_BME680_ENV_OS_HUM\n#define RTE_BME680_ENV_OS_HUM 2\n#endif\n\n#else\n#define RTE_BME680_ENV_OS_HUM 0\n#endif /* defined RTE_BME680_ENV_HUM_ENABLE == 1 */\n\n// </e>\n\n/** \\def RTE_BME680_ENV_FILTER_SIZE\n * \\brief IIR filter coefficient value.\n *\n * Reduces the bandwidth of temperature and pressure output signals and\n * increases the resolution of output data to 20 bit.\n *\n * \\see\n * Section <b>3.3.4 IIR filter</b> of BME680 datasheet for more details.\n */\n// <o> IIR Filter Size\n// <i> Reduces the bandwidth of temperature and pressure output signals and increases the resolution of output data to 20 bit.\n// <i> See section '3.3.4 IIR filter' of BME680 datasheet for more details.\n// <0=> 0\n// <1=> 1\n// <2=> 3\n// <3=> 7\n// <4=> 15\n// <5=> 31\n// <6=> 63\n// <7=> 127\n#ifndef RTE_BME680_ENV_FILTER_SIZE\n#define RTE_BME680_ENV_FILTER_SIZE 1\n#endif\n\n// <<< end of configuration section >>>\n\n#endif /* RTE_BME680_ENV_H_ */\n\n//! \\}\n//! \\}\n//! \\}\n//! \\}\n",
"bme680_reg.h": "/**\n * Copyright (C) 2017 - 2018 Bosch Sensortec GmbH\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n *\n * Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * Neither the name of the copyright holder nor the names of the\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n * CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER\n * OR CONTRIBUTORS BE LIABLE FOR ANY\n * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n * OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS\n * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE\n *\n * The information provided is believed to be accurate and reliable.\n * The copyright holder assumes no responsibility\n * for the consequences of use\n * of such information nor for any infringement of patents or\n * other rights of third parties which may result from its use.\n * No license is granted by implication or otherwise under any patent or\n * patent rights of the copyright holder.\n *\n * @file\tbme680.h\n * @date\t22 Feb 2018\n * @version\t3.5.8\n * @brief\n *\n */\n/*! @file bme680.h\n @brief Sensor driver for BME680 sensor */\n/*!\n * @defgroup BME680_DRIVER_GRP BME680 SENSOR API\n * @{*/\n#ifndef BME680_H_\n#define BME680_H_\n\n/*! CPP guard */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/* Header includes */\n#include \"bme680_defs.h\"\n\n/* function prototype declarations */\n/*!\n * @brief This API is the entry point.\n * It reads the chip-id and calibration data from the sensor.\n *\n * @param[in,out] dev : Structure instance of bme680_dev\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_init( struct bme680_dev *dev );\n\n/*!\n * @brief This API writes the given data to the register address\n * of the sensor.\n *\n * @param[in] reg_addr : Register address from where the data to be written.\n * @param[in] reg_data : Pointer to data buffer which is to be written\n * in the sensor.\n * @param[in] len : No of bytes of data to write..\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_set_regs( const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev );\n\n/*!\n * @brief This API reads the data from the given register address of the sensor.\n *\n * @param[in] reg_addr : Register address from where the data to be read\n * @param[out] reg_data : Pointer to data buffer to store the read data.\n * @param[in] len : No of bytes of data to be read.\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_regs( uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev );\n\n/*!\n * @brief This API performs the soft reset of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_soft_reset( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the power mode of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev\n * @note : Pass the value to bme680_dev.power_mode structure variable.\n *\n * value\t|\tmode\n * -------------|------------------\n *\t0x00\t|\tBME680_SLEEP_MODE\n *\t0x01\t|\tBME680_FORCED_MODE\n *\n * * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_set_sensor_mode( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the power mode of the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev\n * @note : bme680_dev.power_mode structure variable hold the power mode.\n *\n * value\t|\tmode\n * ---------|------------------\n *\t0x00\t|\tBME680_SLEEP_MODE\n *\t0x01\t|\tBME680_FORCED_MODE\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_sensor_mode( struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the profile duration of the sensor.\n *\n * @param[in] dev\t : Structure instance of bme680_dev.\n * @param[in] duration : Duration of the measurement in ms.\n *\n * @return Nothing\n */\nvoid bme680_set_profile_dur( uint16_t duration, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the profile duration of the sensor.\n *\n * @param[in] dev\t : Structure instance of bme680_dev.\n * @param[in] duration : Duration of the measurement in ms.\n *\n * @return Nothing\n */\nvoid bme680_get_profile_dur( uint16_t *duration, const struct bme680_dev *dev );\n\n/*!\n * @brief This API reads the pressure, temperature and humidity and gas data\n * from the sensor, compensates the data and store it in the bme680_data\n * structure instance passed by the user.\n *\n * @param[out] data: Structure instance to hold the data.\n * @param[in] dev : Structure instance of bme680_dev.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error\n */\nint8_t bme680_get_sensor_data( struct bme680_field_data *data, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to set the oversampling, filter and T,P,H, gas selection\n * settings in the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n * @param[in] desired_settings : Variable used to select the settings which\n * are to be set in the sensor.\n *\n *\t Macros\t | Functionality\n *---------------------------------|----------------------------------------------\n *\tBME680_OST_SEL | To set temperature oversampling.\n *\tBME680_OSP_SEL | To set pressure oversampling.\n *\tBME680_OSH_SEL | To set humidity oversampling.\n *\tBME680_GAS_MEAS_SEL | To set gas measurement setting.\n *\tBME680_FILTER_SEL | To set filter setting.\n *\tBME680_HCNTRL_SEL | To set humidity control setting.\n *\tBME680_RUN_GAS_SEL | To set run gas setting.\n *\tBME680_NBCONV_SEL | To set NB conversion setting.\n *\tBME680_GAS_SENSOR_SEL | To set all gas sensor related settings\n *\n * @note : Below are the macros to be used by the user for selecting the\n * desired settings. User can do OR operation of these macros for configuring\n * multiple settings.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_set_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev );\n\n/*!\n * @brief This API is used to get the oversampling, filter and T,P,H, gas selection\n * settings in the sensor.\n *\n * @param[in] dev : Structure instance of bme680_dev.\n * @param[in] desired_settings : Variable used to select the settings which\n * are to be get from the sensor.\n *\n * @return Result of API execution status\n * @retval zero -> Success / +ve value -> Warning / -ve value -> Error.\n */\nint8_t bme680_get_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev );\n#ifdef __cplusplus\n}\n#endif /* End of CPP guard */\n#endif /* BME680_H_ */\n/** @}*/\n"
},
"objects": {
"bme680.c": "#include \"bme680.h\"\n#include \"bme680_reg.h\"\n#include \"bme680_env.h\"\n\nstatic struct bme680_dev _BME680_DriverConfig = {0};\nstatic BME680_Config_t _BME680_PrivConfig;\nstatic uint16_t _BLE680_Meas_Delay_Ms = 0;\n\n\nstatic int8_t BME680_I2C_Write( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len )\n{\n\tuint8_t status;\n\n\tuint8_t writeData[len + 1];\n\n\twriteData[0] = reg_addr;\n\tmemcpy( &writeData[1], reg_data, len );\n\n\treturn ATMO_I2C_MasterWrite( _BME680_PrivConfig.i2cInstance, dev_id, NULL, 0, writeData, len + 1, 0 ) == ATMO_I2C_Status_Success ? 0 : 1;\n}\n\nstatic int8_t BME680_I2C_Read( uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data, uint16_t len )\n{\n\tATMO_I2C_Status_t status = ATMO_I2C_Status_Success;\n\tuint8_t currentReg = reg_addr;\n\n\tunsigned int i;\n\n\tstatus = ATMO_I2C_MasterRead( _BME680_PrivConfig.i2cInstance, dev_id,\n\t ®_addr, 1, reg_data, len, 0 );\n\n\treturn ( status == ATMO_I2C_Status_Success ) ? 0 : 1;\n}\n\nBME680_Status_t BME680_Init( BME680_Config_t *config )\n{\n\tif ( config == NULL )\n\t{\n\t\treturn BME680_Status_Fail;\n\t}\n\n\tmemcpy( &_BME680_PrivConfig, config, sizeof( _BME680_PrivConfig ) );\n\n\tATMO_I2C_Peripheral_t i2cConfig;\n\ti2cConfig.operatingMode = ATMO_I2C_OperatingMode_Master;\n\ti2cConfig.baudRate = ATMO_I2C_BaudRate_Standard_Mode;\n\tATMO_I2C_SetConfiguration( config->i2cInstance, &i2cConfig );\n\n\tATMO_PLATFORM_DelayMilliseconds( 1000 );\n\n\tint8_t status;\n\tuint8_t sel_setting;\n\n\t_BME680_DriverConfig.dev_id = config->i2cAddr;\n\t_BME680_DriverConfig.intf = BME680_I2C_INTF;\n\t_BME680_DriverConfig.read = &BME680_I2C_Read;\n\t_BME680_DriverConfig.write = &BME680_I2C_Write;\n\t_BME680_DriverConfig.delay_ms = &ATMO_PLATFORM_DelayMilliseconds;\n\t_BME680_DriverConfig.amb_temp = 25;\n\n\tATMO_PLATFORM_DebugPrint( \"BME680 I2C Address: %02X\\r\\n\", _BME680_DriverConfig.dev_id );\n\n\tstatus = bme680_init( &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error initializing BME680: %d\\r\\n\", status );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\t_BME680_DriverConfig.tph_sett.os_hum = RTE_BME680_ENV_OS_HUM;\n\t_BME680_DriverConfig.tph_sett.os_pres = RTE_BME680_ENV_OS_PRES;\n\t_BME680_DriverConfig.tph_sett.os_temp = RTE_BME680_ENV_OS_TEMP;\n\t_BME680_DriverConfig.tph_sett.filter = RTE_BME680_ENV_FILTER_SIZE;\n\n\t_BME680_DriverConfig.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;\n\t_BME680_DriverConfig.gas_sett.heatr_temp = 320;\n\t_BME680_DriverConfig.gas_sett.heatr_dur = 150;\n\n\t_BME680_DriverConfig.power_mode = BME680_SLEEP_MODE;\n\n\tsel_setting = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL\n\t | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;\n\n\tstatus = bme680_set_sensor_settings( sel_setting, &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error setting sensor settings\\r\\n\" );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\tstatus = bme680_set_sensor_mode( &_BME680_DriverConfig );\n\n\tif ( status != BME680_OK )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error setting sensor mode\\r\\n\" );\n\t\treturn BME680_Status_Fail;\n\t}\n\n\t// How long it takes between turning sensor on and getting a reading\n\tbme680_get_profile_dur( &_BLE680_Meas_Delay_Ms, &_BME680_DriverConfig );\n\n\tATMO_PLATFORM_DebugPrint( \"Meas Delay: %d\\r\\n\", _BLE680_Meas_Delay_Ms );\n\n\treturn 0;\n}\n\nstatic void _BME680_StartMeasurement()\n{\n\t// Turn sensor on to start measure\n\t_BME680_DriverConfig.power_mode = BME680_FORCED_MODE;\n\tbme680_set_sensor_mode( &_BME680_DriverConfig );\n\n\t// Wait for measurement to complete\n\tATMO_PLATFORM_DelayMilliseconds( _BLE680_Meas_Delay_Ms );\n}\n\nstatic void _BME680_Sleep()\n{\n\t// Go back to sleep\n\t_BME680_DriverConfig.power_mode = BME680_SLEEP_MODE;\n\tbme680_set_sensor_mode( &_BME680_DriverConfig );\n}\n\nBME680_Status_t BME680_GetTempData( float *tempC )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*tempC = 0;\n\t}\n\telse\n\t{\n\t\t*tempC = data.temperature;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetPressure( float *pressureHpa )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*pressureHpa = 0;\n\t}\n\telse\n\t{\n\t\t*pressureHpa = data.pressure;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetHumidity( float *humidity )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*humidity = 0;\n\t}\n\telse\n\t{\n\t\t*humidity = data.humidity;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n\nBME680_Status_t BME680_GetGasRes( float *gas_resistance )\n{\n\t_BME680_StartMeasurement();\n\n\tstruct bme680_field_data data;\n\tint8_t retval = bme680_get_sensor_data( &data, &_BME680_DriverConfig );\n\n\tif ( retval != 0 )\n\t{\n\t\tATMO_PLATFORM_DebugPrint( \"Error getting sensor data! %d\\r\\n\", retval );\n\t\t*gas_resistance = 0;\n\t}\n\telse\n\t{\n\t\t*gas_resistance = data.gas_resistance;\n\t}\n\n\t_BME680_Sleep();\n\treturn BME680_Status_Success;\n}\n",
"bme680_reg.c": "#include \"bme680_reg.h\"\n\nstatic int8_t get_calib_data( struct bme680_dev *dev );\nstatic int8_t set_gas_config( struct bme680_dev *dev );\nstatic int8_t get_gas_config( struct bme680_dev *dev );\nstatic uint8_t calc_heater_dur( uint16_t dur );\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\nstatic int16_t calc_temperature( uint32_t temp_adc, struct bme680_dev *dev );\nstatic uint32_t calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev );\nstatic uint32_t calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev );\nstatic uint32_t calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev );\nstatic uint8_t calc_heater_res( uint16_t temp, const struct bme680_dev *dev );\n\n#else\nstatic float calc_temperature( uint32_t temp_adc, struct bme680_dev *dev );\nstatic float calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev );\nstatic float calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev );\nstatic float calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev );\nstatic float calc_heater_res( uint16_t temp, const struct bme680_dev *dev );\n\n#endif\n\nstatic int8_t read_field_data( struct bme680_field_data *data, struct bme680_dev *dev );\nstatic int8_t set_mem_page( uint8_t reg_addr, struct bme680_dev *dev );\nstatic int8_t get_mem_page( struct bme680_dev *dev );\nstatic int8_t null_ptr_check( const struct bme680_dev *dev );\nstatic int8_t boundary_check( uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev );\n\nint8_t bme680_init( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_soft_reset( dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_CHIP_ID_ADDR, &dev->chip_id, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tif ( dev->chip_id == BME680_CHIP_ID )\n\t\t\t\t{\n\t\t\t\t\trslt = get_calib_data( dev );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_DEV_NOT_FOUND;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_regs( uint8_t reg_addr, uint8_t *reg_data, uint16_t len, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t{\n\t\t\trslt = set_mem_page( reg_addr, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\treg_addr = reg_addr | BME680_SPI_RD_MSK;\n\t\t\t}\n\t\t}\n\n\t\tdev->com_rslt = dev->read( dev->dev_id, reg_addr, reg_data, len );\n\n\t\tif ( dev->com_rslt != 0 )\n\t\t{\n\t\t\trslt = BME680_E_COM_FAIL;\n\t\t}\n\t}\n\n\treturn rslt;\n}\nint8_t bme680_set_regs( const uint8_t *reg_addr, const uint8_t *reg_data, uint8_t len, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t tmp_buff[BME680_TMP_BUFFER_LENGTH] = { 0 };\n\tuint16_t index;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( ( len > 0 ) && ( len < BME680_TMP_BUFFER_LENGTH / 2 ) )\n\t\t{\n\t\t\tfor ( index = 0; index < len; index++ )\n\t\t\t{\n\t\t\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t\t\t{\n\t\t\t\t\trslt = set_mem_page( reg_addr[index], dev );\n\t\t\t\t\ttmp_buff[( 2 * index )] = reg_addr[index] & BME680_SPI_WR_MSK;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttmp_buff[( 2 * index )] = reg_addr[index];\n\t\t\t\t}\n\n\t\t\t\ttmp_buff[( 2 * index ) + 1] = reg_data[index];\n\t\t\t}\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tdev->com_rslt = dev->write( dev->dev_id, tmp_buff[0], &tmp_buff[1], ( 2 * len ) - 1 );\n\n\t\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\trslt = BME680_E_INVALID_LENGTH;\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_soft_reset( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr = BME680_SOFT_RESET_ADDR;\n\tuint8_t soft_rst_cmd = BME680_SOFT_RESET_CMD;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t{\n\t\t\trslt = get_mem_page( dev );\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( ®_addr, &soft_rst_cmd, 1, dev );\n\t\t\tdev->delay_ms( BME680_RESET_PERIOD );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tif ( dev->intf == BME680_SPI_INTF )\n\t\t\t\t{\n\t\t\t\t\trslt = get_mem_page( dev );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_set_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr;\n\tuint8_t data = 0;\n\tuint8_t count = 0;\n\tuint8_t reg_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\tuint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\tuint8_t intended_power_mode = dev->power_mode;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( desired_settings & BME680_GAS_MEAS_SEL )\n\t\t{\n\t\t\trslt = set_gas_config( dev );\n\t\t}\n\n\t\tdev->power_mode = BME680_SLEEP_MODE;\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_sensor_mode( dev );\n\t\t}\n\n\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.filter, BME680_FILTER_SIZE_0, BME680_FILTER_SIZE_127, dev );\n\t\t\treg_addr = BME680_CONF_ODR_FILT_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_FILTER, dev->tph_sett.filter );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & BME680_HCNTRL_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->gas_sett.heatr_ctrl, BME680_ENABLE_HEATER,\n\t\t\t BME680_DISABLE_HEATER, dev );\n\t\t\treg_addr = BME680_CONF_HEAT_CTRL_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_HCTRL, dev->gas_sett.heatr_ctrl );\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & ( BME680_OST_SEL | BME680_OSP_SEL ) )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.os_temp, BME680_OS_NONE, BME680_OS_16X, dev );\n\t\t\treg_addr = BME680_CONF_T_P_MODE_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OST_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_OST, dev->tph_sett.os_temp );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OSP_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_OSP, dev->tph_sett.os_pres );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & BME680_OSH_SEL )\n\t\t{\n\t\t\trslt = boundary_check( &dev->tph_sett.os_hum, BME680_OS_NONE, BME680_OS_16X, dev );\n\t\t\treg_addr = BME680_CONF_OS_H_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_OSH, dev->tph_sett.os_hum );\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( desired_settings & ( BME680_RUN_GAS_SEL | BME680_NBCONV_SEL ) )\n\t\t{\n\t\t\trslt = boundary_check( &dev->gas_sett.run_gas, BME680_RUN_GAS_DISABLE,\n\t\t\t BME680_RUN_GAS_ENABLE, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = boundary_check( &dev->gas_sett.nb_conv, BME680_NBCONV_MIN,\n\t\t\t\t BME680_NBCONV_MAX, dev );\n\t\t\t}\n\n\t\t\treg_addr = BME680_CONF_ODR_RUN_GAS_NBC_ADDR;\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( reg_addr, &data, 1, dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_RUN_GAS_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS( data, BME680_RUN_GAS, dev->gas_sett.run_gas );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_NBCONV_SEL )\n\t\t\t{\n\t\t\t\tdata = BME680_SET_BITS_POS_0( data, BME680_NBCONV, dev->gas_sett.nb_conv );\n\t\t\t}\n\n\t\t\treg_array[count] = reg_addr;\n\t\t\tdata_array[count] = data;\n\t\t\tcount++;\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( reg_array, data_array, count, dev );\n\t\t}\n\n\t\tdev->power_mode = intended_power_mode;\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_sensor_settings( uint16_t desired_settings, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr = BME680_CONF_HEAT_CTRL_ADDR;\n\tuint8_t data_array[BME680_REG_BUFFER_LENGTH] = { 0 };\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( reg_addr, data_array, BME680_REG_BUFFER_LENGTH, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\tif ( desired_settings & BME680_GAS_MEAS_SEL )\n\t\t\t{\n\t\t\t\trslt = get_gas_config( dev );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_FILTER_SEL )\n\t\t\t\tdev->tph_sett.filter = BME680_GET_BITS( data_array[BME680_REG_FILTER_INDEX],\n\t\t\t\t BME680_FILTER );\n\n\t\t\tif ( desired_settings & ( BME680_OST_SEL | BME680_OSP_SEL ) )\n\t\t\t{\n\t\t\t\tdev->tph_sett.os_temp = BME680_GET_BITS( data_array[BME680_REG_TEMP_INDEX], BME680_OST );\n\t\t\t\tdev->tph_sett.os_pres = BME680_GET_BITS( data_array[BME680_REG_PRES_INDEX], BME680_OSP );\n\t\t\t}\n\n\t\t\tif ( desired_settings & BME680_OSH_SEL )\n\t\t\t\tdev->tph_sett.os_hum = BME680_GET_BITS_POS_0( data_array[BME680_REG_HUM_INDEX],\n\t\t\t\t BME680_OSH );\n\n\t\t\tif ( desired_settings & BME680_HCNTRL_SEL )\n\t\t\t\tdev->gas_sett.heatr_ctrl = BME680_GET_BITS_POS_0( data_array[BME680_REG_HCTRL_INDEX],\n\t\t\t\t BME680_HCTRL );\n\n\t\t\tif ( desired_settings & ( BME680_RUN_GAS_SEL | BME680_NBCONV_SEL ) )\n\t\t\t{\n\t\t\t\tdev->gas_sett.nb_conv = BME680_GET_BITS_POS_0( data_array[BME680_REG_NBCONV_INDEX],\n\t\t\t\t BME680_NBCONV );\n\t\t\t\tdev->gas_sett.run_gas = BME680_GET_BITS( data_array[BME680_REG_RUN_GAS_INDEX],\n\t\t\t\t BME680_RUN_GAS );\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_set_sensor_mode( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t tmp_pow_mode;\n\tuint8_t pow_mode = 0;\n\tuint8_t reg_addr = BME680_CONF_T_P_MODE_ADDR;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tdo\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_CONF_T_P_MODE_ADDR, &tmp_pow_mode, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tpow_mode = ( tmp_pow_mode & BME680_MODE_MSK );\n\n\t\t\t\tif ( pow_mode != BME680_SLEEP_MODE )\n\t\t\t\t{\n\t\t\t\t\ttmp_pow_mode = tmp_pow_mode & ( ~BME680_MODE_MSK );\n\t\t\t\t\trslt = bme680_set_regs( ®_addr, &tmp_pow_mode, 1, dev );\n\t\t\t\t\tdev->delay_ms( BME680_POLL_PERIOD_MS );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twhile ( pow_mode != BME680_SLEEP_MODE );\n\n\t\tif ( dev->power_mode != BME680_SLEEP_MODE )\n\t\t{\n\t\t\ttmp_pow_mode = ( tmp_pow_mode & ~BME680_MODE_MSK ) | ( dev->power_mode & BME680_MODE_MSK );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_set_regs( ®_addr, &tmp_pow_mode, 1, dev );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nint8_t bme680_get_sensor_mode( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t mode;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( BME680_CONF_T_P_MODE_ADDR, &mode, 1, dev );\n\t\tdev->power_mode = mode & BME680_MODE_MSK;\n\t}\n\n\treturn rslt;\n}\n\nvoid bme680_set_profile_dur( uint16_t duration, struct bme680_dev *dev )\n{\n\tuint32_t tph_dur;\n\tuint32_t meas_cycles;\n\tuint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};\n\n\tmeas_cycles = os_to_meas_cycles[dev->tph_sett.os_temp];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_pres];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_hum];\n\n\ttph_dur = meas_cycles * UINT32_C( 1963 );\n\ttph_dur += UINT32_C( 477 * 4 );\n\ttph_dur += UINT32_C( 477 * 5 );\n\ttph_dur += UINT32_C( 500 );\n\ttph_dur /= UINT32_C( 1000 );\n\n\ttph_dur += UINT32_C( 1 );\n\tdev->gas_sett.heatr_dur = duration - ( uint16_t ) tph_dur;\n}\n\nvoid bme680_get_profile_dur( uint16_t *duration, const struct bme680_dev *dev )\n{\n\tuint32_t tph_dur;\n\tuint32_t meas_cycles;\n\tuint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};\n\n\tmeas_cycles = os_to_meas_cycles[dev->tph_sett.os_temp];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_pres];\n\tmeas_cycles += os_to_meas_cycles[dev->tph_sett.os_hum];\n\n\ttph_dur = meas_cycles * UINT32_C( 1963 );\n\ttph_dur += UINT32_C( 477 * 4 );\n\ttph_dur += UINT32_C( 477 * 5 );\n\ttph_dur += UINT32_C( 500 );\n\ttph_dur /= UINT32_C( 1000 );\n\n\ttph_dur += UINT32_C( 1 );\n\n\t*duration = ( uint16_t ) tph_dur;\n\n\tif ( dev->gas_sett.run_gas )\n\t{\n\t\t*duration += dev->gas_sett.heatr_dur;\n\t}\n}\n\nint8_t bme680_get_sensor_data( struct bme680_field_data *data, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = read_field_data( data, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\tif ( data->status & BME680_NEW_DATA_MSK )\n\t\t\t{\n\t\t\t\tdev->new_fields = 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdev->new_fields = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_calib_data( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t coeff_array[BME680_COEFF_SIZE] = { 0 };\n\tuint8_t temp_var = 0;\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\trslt = bme680_get_regs( BME680_COEFF_ADDR1, coeff_array, BME680_COEFF_ADDR1_LEN, dev );\n\n\t\tif ( rslt == BME680_OK )\n\t\t\trslt = bme680_get_regs( BME680_COEFF_ADDR2, &coeff_array[BME680_COEFF_ADDR1_LEN]\n\t\t\t , BME680_COEFF_ADDR2_LEN, dev );\n\n\t\tdev->calib.par_t1 = ( uint16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_T1_MSB_REG],\n\t\t coeff_array[BME680_T1_LSB_REG] ) );\n\t\tdev->calib.par_t2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_T2_MSB_REG],\n\t\t coeff_array[BME680_T2_LSB_REG] ) );\n\t\tdev->calib.par_t3 = ( int8_t ) ( coeff_array[BME680_T3_REG] );\n\n\t\tdev->calib.par_p1 = ( uint16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P1_MSB_REG],\n\t\t coeff_array[BME680_P1_LSB_REG] ) );\n\t\tdev->calib.par_p2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P2_MSB_REG],\n\t\t coeff_array[BME680_P2_LSB_REG] ) );\n\t\tdev->calib.par_p3 = ( int8_t ) coeff_array[BME680_P3_REG];\n\t\tdev->calib.par_p4 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P4_MSB_REG],\n\t\t coeff_array[BME680_P4_LSB_REG] ) );\n\t\tdev->calib.par_p5 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P5_MSB_REG],\n\t\t coeff_array[BME680_P5_LSB_REG] ) );\n\t\tdev->calib.par_p6 = ( int8_t ) ( coeff_array[BME680_P6_REG] );\n\t\tdev->calib.par_p7 = ( int8_t ) ( coeff_array[BME680_P7_REG] );\n\t\tdev->calib.par_p8 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P8_MSB_REG],\n\t\t coeff_array[BME680_P8_LSB_REG] ) );\n\t\tdev->calib.par_p9 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_P9_MSB_REG],\n\t\t coeff_array[BME680_P9_LSB_REG] ) );\n\t\tdev->calib.par_p10 = ( uint8_t ) ( coeff_array[BME680_P10_REG] );\n\n\t\tdev->calib.par_h1 = ( uint16_t ) ( ( ( uint16_t ) coeff_array[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL )\n\t\t | ( coeff_array[BME680_H1_LSB_REG] & BME680_BIT_H1_DATA_MSK ) );\n\t\tdev->calib.par_h2 = ( uint16_t ) ( ( ( uint16_t ) coeff_array[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL )\n\t\t | ( ( coeff_array[BME680_H2_LSB_REG] ) >> BME680_HUM_REG_SHIFT_VAL ) );\n\t\tdev->calib.par_h3 = ( int8_t ) coeff_array[BME680_H3_REG];\n\t\tdev->calib.par_h4 = ( int8_t ) coeff_array[BME680_H4_REG];\n\t\tdev->calib.par_h5 = ( int8_t ) coeff_array[BME680_H5_REG];\n\t\tdev->calib.par_h6 = ( uint8_t ) coeff_array[BME680_H6_REG];\n\t\tdev->calib.par_h7 = ( int8_t ) coeff_array[BME680_H7_REG];\n\n\t\tdev->calib.par_gh1 = ( int8_t ) coeff_array[BME680_GH1_REG];\n\t\tdev->calib.par_gh2 = ( int16_t ) ( BME680_CONCAT_BYTES( coeff_array[BME680_GH2_MSB_REG],\n\t\t coeff_array[BME680_GH2_LSB_REG] ) );\n\t\tdev->calib.par_gh3 = ( int8_t ) coeff_array[BME680_GH3_REG];\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( BME680_ADDR_RES_HEAT_RANGE_ADDR, &temp_var, 1, dev );\n\n\t\t\tdev->calib.res_heat_range = ( ( temp_var & BME680_RHRANGE_MSK ) / 16 );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\trslt = bme680_get_regs( BME680_ADDR_RES_HEAT_VAL_ADDR, &temp_var, 1, dev );\n\n\t\t\t\tdev->calib.res_heat_val = ( int8_t ) temp_var;\n\n\t\t\t\tif ( rslt == BME680_OK )\n\t\t\t\t{\n\t\t\t\t\trslt = bme680_get_regs( BME680_ADDR_RANGE_SW_ERR_ADDR, &temp_var, 1, dev );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdev->calib.range_sw_err = ( ( int8_t ) temp_var & ( int8_t ) BME680_RSERROR_MSK ) / 16;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t set_gas_config( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\n\t\tuint8_t reg_addr[2] = {0};\n\t\tuint8_t reg_data[2] = {0};\n\n\t\tif ( dev->power_mode == BME680_FORCED_MODE )\n\t\t{\n\t\t\treg_addr[0] = BME680_RES_HEAT0_ADDR;\n\t\t\treg_data[0] = calc_heater_res( dev->gas_sett.heatr_temp, dev );\n\t\t\treg_addr[1] = BME680_GAS_WAIT0_ADDR;\n\t\t\treg_data[1] = calc_heater_dur( dev->gas_sett.heatr_dur );\n\t\t\tdev->gas_sett.nb_conv = 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t\trslt = BME680_W_DEFINE_PWR_MODE;\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_set_regs( reg_addr, reg_data, 2, dev );\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_gas_config( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg_addr1 = BME680_ADDR_SENS_CONF_START;\n\tuint8_t reg_addr2 = BME680_ADDR_GAS_CONF_START;\n\tuint8_t reg_data = 0;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( BME680_SPI_INTF == dev->intf )\n\t\t{\n\t\t\trslt = set_mem_page( reg_addr1, dev );\n\t\t}\n\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( reg_addr1, ®_data, 1, dev );\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\tdev->gas_sett.heatr_temp = reg_data;\n\t\t\t\trslt = bme680_get_regs( reg_addr2, ®_data, 1, dev );\n\n\t\t\t\tif ( rslt == BME680_OK )\n\t\t\t\t{\n\t\t\t\t\tdev->gas_sett.heatr_dur = reg_data;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\n#ifndef BME680_FLOAT_POINT_COMPENSATION\n\nstatic int16_t calc_temperature( uint32_t temp_adc, struct bme680_dev *dev )\n{\n\tint64_t var1;\n\tint64_t var2;\n\tint64_t var3;\n\tint16_t calc_temp;\n\n\tvar1 = ( ( int32_t ) temp_adc >> 3 ) - ( ( int32_t ) dev->calib.par_t1 << 1 );\n\tvar2 = ( var1 * ( int32_t ) dev->calib.par_t2 ) >> 11;\n\tvar3 = ( ( var1 >> 1 ) * ( var1 >> 1 ) ) >> 12;\n\tvar3 = ( ( var3 ) * ( ( int32_t ) dev->calib.par_t3 << 4 ) ) >> 14;\n\tdev->calib.t_fine = ( int32_t ) ( var2 + var3 );\n\tcalc_temp = ( int16_t ) ( ( ( dev->calib.t_fine * 5 ) + 128 ) >> 8 );\n\n\treturn calc_temp;\n}\n\nstatic uint32_t calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev )\n{\n\tint32_t var1 = 0;\n\tint32_t var2 = 0;\n\tint32_t var3 = 0;\n\tint32_t pressure_comp = 0;\n\n\tvar1 = ( ( ( int32_t )dev->calib.t_fine ) >> 1 ) - 64000;\n\tvar2 = ( ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 11 ) *\n\t ( int32_t )dev->calib.par_p6 ) >> 2;\n\tvar2 = var2 + ( ( var1 * ( int32_t )dev->calib.par_p5 ) << 1 );\n\tvar2 = ( var2 >> 2 ) + ( ( int32_t )dev->calib.par_p4 << 16 );\n\tvar1 = ( ( ( ( ( var1 >> 2 ) * ( var1 >> 2 ) ) >> 13 ) *\n\t ( ( int32_t )dev->calib.par_p3 << 5 ) ) >> 3 ) +\n\t ( ( ( int32_t )dev->calib.par_p2 * var1 ) >> 1 );\n\tvar1 = var1 >> 18;\n\tvar1 = ( ( 32768 + var1 ) * ( int32_t )dev->calib.par_p1 ) >> 15;\n\tpressure_comp = 1048576 - pres_adc;\n\tpressure_comp = ( int32_t )( ( pressure_comp - ( var2 >> 12 ) ) * ( ( uint32_t )3125 ) );\n\n\tif ( pressure_comp >= BME680_MAX_OVERFLOW_VAL )\n\t{\n\t\tpressure_comp = ( ( pressure_comp / ( uint32_t )var1 ) << 1 );\n\t}\n\telse\n\t{\n\t\tpressure_comp = ( ( pressure_comp << 1 ) / ( uint32_t )var1 );\n\t}\n\n\tvar1 = ( ( int32_t )dev->calib.par_p9 * ( int32_t )( ( ( pressure_comp >> 3 ) *\n\t ( pressure_comp >> 3 ) ) >> 13 ) ) >> 12;\n\tvar2 = ( ( int32_t )( pressure_comp >> 2 ) *\n\t ( int32_t )dev->calib.par_p8 ) >> 13;\n\tvar3 = ( ( int32_t )( pressure_comp >> 8 ) * ( int32_t )( pressure_comp >> 8 ) *\n\t ( int32_t )( pressure_comp >> 8 ) *\n\t ( int32_t )dev->calib.par_p10 ) >> 17;\n\n\tpressure_comp = ( int32_t )( pressure_comp ) + ( ( var1 + var2 + var3 +\n\t ( ( int32_t )dev->calib.par_p7 << 7 ) ) >> 4 );\n\n\treturn ( uint32_t )pressure_comp;\n\n}\n\nstatic uint32_t calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev )\n{\n\tint32_t var1;\n\tint32_t var2;\n\tint32_t var3;\n\tint32_t var4;\n\tint32_t var5;\n\tint32_t var6;\n\tint32_t temp_scaled;\n\tint32_t calc_hum;\n\n\ttemp_scaled = ( ( ( int32_t ) dev->calib.t_fine * 5 ) + 128 ) >> 8;\n\tvar1 = ( int32_t ) ( hum_adc - ( ( int32_t ) ( ( int32_t ) dev->calib.par_h1 * 16 ) ) )\n\t - ( ( ( temp_scaled * ( int32_t ) dev->calib.par_h3 ) / ( ( int32_t ) 100 ) ) >> 1 );\n\tvar2 = ( ( int32_t ) dev->calib.par_h2\n\t * ( ( ( temp_scaled * ( int32_t ) dev->calib.par_h4 ) / ( ( int32_t ) 100 ) )\n\t + ( ( ( temp_scaled * ( ( temp_scaled * ( int32_t ) dev->calib.par_h5 ) / ( ( int32_t ) 100 ) ) ) >> 6 )\n\t / ( ( int32_t ) 100 ) ) + ( int32_t ) ( 1 << 14 ) ) ) >> 10;\n\tvar3 = var1 * var2;\n\tvar4 = ( int32_t ) dev->calib.par_h6 << 7;\n\tvar4 = ( ( var4 ) + ( ( temp_scaled * ( int32_t ) dev->calib.par_h7 ) / ( ( int32_t ) 100 ) ) ) >> 4;\n\tvar5 = ( ( var3 >> 14 ) * ( var3 >> 14 ) ) >> 10;\n\tvar6 = ( var4 * var5 ) >> 1;\n\tcalc_hum = ( ( ( var3 + var6 ) >> 10 ) * ( ( int32_t ) 1000 ) ) >> 12;\n\n\tif ( calc_hum > 100000 )\n\t{\n\t\tcalc_hum = 100000;\n\t}\n\telse if ( calc_hum < 0 )\n\t{\n\t\tcalc_hum = 0;\n\t}\n\n\treturn ( uint32_t ) calc_hum;\n}\n\nstatic uint32_t calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev )\n{\n\tint64_t var1;\n\tuint64_t var2;\n\tint64_t var3;\n\tuint32_t calc_gas_res;\n\tuint32_t lookupTable1[16] = { UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 ),\n\t UINT32_C( 2147483647 ), UINT32_C( 2126008810 ), UINT32_C( 2147483647 ), UINT32_C( 2130303777 ),\n\t UINT32_C( 2147483647 ), UINT32_C( 2147483647 ), UINT32_C( 2143188679 ), UINT32_C( 2136746228 ),\n\t UINT32_C( 2147483647 ), UINT32_C( 2126008810 ), UINT32_C( 2147483647 ), UINT32_C( 2147483647 )\n\t };\n\tuint32_t lookupTable2[16] = { UINT32_C( 4096000000 ), UINT32_C( 2048000000 ), UINT32_C( 1024000000 ), UINT32_C( 512000000 ),\n\t UINT32_C( 255744255 ), UINT32_C( 127110228 ), UINT32_C( 64000000 ), UINT32_C( 32258064 ), UINT32_C( 16016016 ),\n\t UINT32_C( 8000000 ), UINT32_C( 4000000 ), UINT32_C( 2000000 ), UINT32_C( 1000000 ), UINT32_C( 500000 ),\n\t UINT32_C( 250000 ), UINT32_C( 125000 )\n\t };\n\n\tvar1 = ( int64_t ) ( ( 1340 + ( 5 * ( int64_t ) dev->calib.range_sw_err ) ) *\n\t ( ( int64_t ) lookupTable1[gas_range] ) ) >> 16;\n\tvar2 = ( ( ( int64_t ) ( ( int64_t ) gas_res_adc << 15 ) - ( int64_t ) ( 16777216 ) ) + var1 );\n\tvar3 = ( ( ( int64_t ) lookupTable2[gas_range] * ( int64_t ) var1 ) >> 9 );\n\tcalc_gas_res = ( uint32_t ) ( ( var3 + ( ( int64_t ) var2 >> 1 ) ) / ( int64_t ) var2 );\n\n\treturn calc_gas_res;\n}\n\nstatic uint8_t calc_heater_res( uint16_t temp, const struct bme680_dev *dev )\n{\n\tuint8_t heatr_res;\n\tint32_t var1;\n\tint32_t var2;\n\tint32_t var3;\n\tint32_t var4;\n\tint32_t var5;\n\tint32_t heatr_res_x100;\n\n\tif ( temp > 400 )\n\t{\n\t\ttemp = 400;\n\t}\n\n\tvar1 = ( ( ( int32_t ) dev->amb_temp * dev->calib.par_gh3 ) / 1000 ) * 256;\n\tvar2 = ( dev->calib.par_gh1 + 784 ) * ( ( ( ( ( dev->calib.par_gh2 + 154009 ) * temp * 5 ) / 100 ) + 3276800 ) / 10 );\n\tvar3 = var1 + ( var2 / 2 );\n\tvar4 = ( var3 / ( dev->calib.res_heat_range + 4 ) );\n\tvar5 = ( 131 * dev->calib.res_heat_val ) + 65536;\n\theatr_res_x100 = ( int32_t ) ( ( ( var4 / var5 ) - 250 ) * 34 );\n\theatr_res = ( uint8_t ) ( ( heatr_res_x100 + 50 ) / 100 );\n\n\treturn heatr_res;\n}\n\n#else\n\nstatic float calc_temperature( uint32_t temp_adc, struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat calc_temp = 0;\n\n\tvar1 = ( ( ( ( float )temp_adc / 16384.0f ) - ( ( float )dev->calib.par_t1 / 1024.0f ) )\n\t * ( ( float )dev->calib.par_t2 ) );\n\n\tvar2 = ( ( ( ( ( float )temp_adc / 131072.0f ) - ( ( float )dev->calib.par_t1 / 8192.0f ) ) *\n\t ( ( ( float )temp_adc / 131072.0f ) - ( ( float )dev->calib.par_t1 / 8192.0f ) ) ) *\n\t ( ( float )dev->calib.par_t3 * 16.0f ) );\n\n\tdev->calib.t_fine = ( var1 + var2 );\n\n\tcalc_temp = ( ( dev->calib.t_fine ) / 5120.0f );\n\n\treturn calc_temp;\n}\n\nstatic float calc_pressure( uint32_t pres_adc, const struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat calc_pres = 0;\n\n\tvar1 = ( ( ( float )dev->calib.t_fine / 2.0f ) - 64000.0f );\n\tvar2 = var1 * var1 * ( ( ( float )dev->calib.par_p6 ) / ( 131072.0f ) );\n\tvar2 = var2 + ( var1 * ( ( float )dev->calib.par_p5 ) * 2.0f );\n\tvar2 = ( var2 / 4.0f ) + ( ( ( float )dev->calib.par_p4 ) * 65536.0f );\n\tvar1 = ( ( ( ( ( float )dev->calib.par_p3 * var1 * var1 ) / 16384.0f )\n\t + ( ( float )dev->calib.par_p2 * var1 ) ) / 524288.0f );\n\tvar1 = ( ( 1.0f + ( var1 / 32768.0f ) ) * ( ( float )dev->calib.par_p1 ) );\n\tcalc_pres = ( 1048576.0f - ( ( float )pres_adc ) );\n\n\tif ( ( int )var1 != 0 )\n\t{\n\t\tcalc_pres = ( ( ( calc_pres - ( var2 / 4096.0f ) ) * 6250.0f ) / var1 );\n\t\tvar1 = ( ( ( float )dev->calib.par_p9 ) * calc_pres * calc_pres ) / 2147483648.0f;\n\t\tvar2 = calc_pres * ( ( ( float )dev->calib.par_p8 ) / 32768.0f );\n\t\tvar3 = ( ( calc_pres / 256.0f ) * ( calc_pres / 256.0f ) * ( calc_pres / 256.0f )\n\t\t * ( dev->calib.par_p10 / 131072.0f ) );\n\t\tcalc_pres = ( calc_pres + ( var1 + var2 + var3 + ( ( float )dev->calib.par_p7 * 128.0f ) ) / 16.0f );\n\t}\n\telse\n\t{\n\t\tcalc_pres = 0;\n\t}\n\n\treturn calc_pres;\n}\n\nstatic float calc_humidity( uint16_t hum_adc, const struct bme680_dev *dev )\n{\n\tfloat calc_hum = 0;\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat var4 = 0;\n\tfloat temp_comp;\n\n\ttemp_comp = ( ( dev->calib.t_fine ) / 5120.0f );\n\n\tvar1 = ( float )( ( float )hum_adc ) - ( ( ( float )dev->calib.par_h1 * 16.0f ) + ( ( ( float )dev->calib.par_h3 / 2.0f )\n\t * temp_comp ) );\n\n\tvar2 = var1 * ( ( float )( ( ( float ) dev->calib.par_h2 / 262144.0f ) * ( 1.0f + ( ( ( float )dev->calib.par_h4 / 16384.0f )\n\t * temp_comp ) + ( ( ( float )dev->calib.par_h5 / 1048576.0f ) * temp_comp * temp_comp ) ) ) );\n\n\tvar3 = ( float ) dev->calib.par_h6 / 16384.0f;\n\n\tvar4 = ( float ) dev->calib.par_h7 / 2097152.0f;\n\n\tcalc_hum = var2 + ( ( var3 + ( var4 * temp_comp ) ) * var2 * var2 );\n\n\tif ( calc_hum > 100.0f )\n\t{\n\t\tcalc_hum = 100.0f;\n\t}\n\telse if ( calc_hum < 0.0f )\n\t{\n\t\tcalc_hum = 0.0f;\n\t}\n\n\treturn calc_hum;\n}\n\nstatic float calc_gas_resistance( uint16_t gas_res_adc, uint8_t gas_range, const struct bme680_dev *dev )\n{\n\tfloat calc_gas_res;\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\n\tconst float lookup_k1_range[16] =\n\t{\n\t\t0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,\n\t\t0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0\n\t};\n\tconst float lookup_k2_range[16] =\n\t{\n\t\t0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,\n\t\t-0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0\n\t};\n\n\tvar1 = ( 1340.0f + ( 5.0f * dev->calib.range_sw_err ) );\n\tvar2 = ( var1 ) * ( 1.0f + lookup_k1_range[gas_range] / 100.0f );\n\tvar3 = 1.0f + ( lookup_k2_range[gas_range] / 100.0f );\n\n\tcalc_gas_res = 1.0f / ( float )( var3 * ( 0.000000125f ) * ( float )( 1 << gas_range ) * ( ( ( ( ( float )gas_res_adc )\n\t - 512.0f ) / var2 ) + 1.0f ) );\n\n\treturn calc_gas_res;\n}\n\nstatic float calc_heater_res( uint16_t temp, const struct bme680_dev *dev )\n{\n\tfloat var1 = 0;\n\tfloat var2 = 0;\n\tfloat var3 = 0;\n\tfloat var4 = 0;\n\tfloat var5 = 0;\n\tfloat res_heat = 0;\n\n\tif ( temp > 400 )\n\t{\n\t\ttemp = 400;\n\t}\n\n\tvar1 = ( ( ( float )dev->calib.par_gh1 / ( 16.0f ) ) + 49.0f );\n\tvar2 = ( ( ( ( float )dev->calib.par_gh2 / ( 32768.0f ) ) * ( 0.0005f ) ) + 0.00235f );\n\tvar3 = ( ( float )dev->calib.par_gh3 / ( 1024.0f ) );\n\tvar4 = ( var1 * ( 1.0f + ( var2 * ( float )temp ) ) );\n\tvar5 = ( var4 + ( var3 * ( float )dev->amb_temp ) );\n\tres_heat = ( uint8_t )( 3.4f * ( ( var5 * ( 4 / ( 4 + ( float )dev->calib.res_heat_range ) ) *\n\t ( 1 / ( 1 + ( ( float ) dev->calib.res_heat_val * 0.002f ) ) ) ) - 25 ) );\n\n\treturn res_heat;\n}\n\n#endif\n\nstatic uint8_t calc_heater_dur( uint16_t dur )\n{\n\tuint8_t factor = 0;\n\tuint8_t durval;\n\n\tif ( dur >= 0xfc0 )\n\t{\n\t\tdurval = 0xff; /* Max duration*/\n\t}\n\telse\n\t{\n\t\twhile ( dur > 0x3F )\n\t\t{\n\t\t\tdur = dur / 4;\n\t\t\tfactor += 1;\n\t\t}\n\n\t\tdurval = ( uint8_t ) ( dur + ( factor * 64 ) );\n\t}\n\n\treturn durval;\n}\n\nstatic int8_t read_field_data( struct bme680_field_data *data, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t buff[BME680_FIELD_LENGTH] = { 0 };\n\tuint8_t gas_range;\n\tuint32_t adc_temp;\n\tuint32_t adc_pres;\n\tuint16_t adc_hum;\n\tuint16_t adc_gas_res;\n\tuint8_t tries = 10;\n\n\trslt = null_ptr_check( dev );\n\n\tdo\n\t{\n\t\tif ( rslt == BME680_OK )\n\t\t{\n\t\t\trslt = bme680_get_regs( ( ( uint8_t ) ( BME680_FIELD0_ADDR ) ), buff, ( uint16_t ) BME680_FIELD_LENGTH,\n\t\t\t dev );\n\n\t\t\tdata->status = buff[0] & BME680_NEW_DATA_MSK;\n\t\t\tdata->gas_index = buff[0] & BME680_GAS_INDEX_MSK;\n\t\t\tdata->meas_index = buff[1];\n\n\t\t\tadc_pres = ( uint32_t ) ( ( ( uint32_t ) buff[2] * 4096 ) | ( ( uint32_t ) buff[3] * 16 )\n\t\t\t | ( ( uint32_t ) buff[4] / 16 ) );\n\t\t\tadc_temp = ( uint32_t ) ( ( ( uint32_t ) buff[5] * 4096 ) | ( ( uint32_t ) buff[6] * 16 )\n\t\t\t | ( ( uint32_t ) buff[7] / 16 ) );\n\t\t\tadc_hum = ( uint16_t ) ( ( ( uint32_t ) buff[8] * 256 ) | ( uint32_t ) buff[9] );\n\t\t\tadc_gas_res = ( uint16_t ) ( ( uint32_t ) buff[13] * 4 | ( ( ( uint32_t ) buff[14] ) / 64 ) );\n\t\t\tgas_range = buff[14] & BME680_GAS_RANGE_MSK;\n\n\t\t\tdata->status |= buff[14] & BME680_GASM_VALID_MSK;\n\t\t\tdata->status |= buff[14] & BME680_HEAT_STAB_MSK;\n\n\t\t\tif ( data->status & BME680_NEW_DATA_MSK )\n\t\t\t{\n\t\t\t\tdata->temperature = calc_temperature( adc_temp, dev );\n\t\t\t\tdata->pressure = calc_pressure( adc_pres, dev );\n\t\t\t\tdata->humidity = calc_humidity( adc_hum, dev );\n\t\t\t\tdata->gas_resistance = calc_gas_resistance( adc_gas_res, gas_range, dev );\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdev->delay_ms( BME680_POLL_PERIOD_MS );\n\t\t}\n\n\t\ttries--;\n\t}\n\twhile ( tries );\n\n\tif ( !tries )\n\t{\n\t\trslt = BME680_W_NO_NEW_DATA;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t set_mem_page( uint8_t reg_addr, struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg;\n\tuint8_t mem_page;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tif ( reg_addr > 0x7f )\n\t\t{\n\t\t\tmem_page = BME680_MEM_PAGE1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tmem_page = BME680_MEM_PAGE0;\n\t\t}\n\n\t\tif ( mem_page != dev->mem_page )\n\t\t{\n\t\t\tdev->mem_page = mem_page;\n\n\t\t\tdev->com_rslt = dev->read( dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, ®, 1 );\n\n\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t{\n\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t}\n\n\t\t\tif ( rslt == BME680_OK )\n\t\t\t{\n\t\t\t\treg = reg & ( ~BME680_MEM_PAGE_MSK );\n\t\t\t\treg = reg | ( dev->mem_page & BME680_MEM_PAGE_MSK );\n\n\t\t\t\tdev->com_rslt = dev->write( dev->dev_id, BME680_MEM_PAGE_ADDR & BME680_SPI_WR_MSK,\n\t\t\t\t ®, 1 );\n\n\t\t\t\tif ( dev->com_rslt != 0 )\n\t\t\t\t{\n\t\t\t\t\trslt = BME680_E_COM_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t get_mem_page( struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\tuint8_t reg;\n\n\trslt = null_ptr_check( dev );\n\n\tif ( rslt == BME680_OK )\n\t{\n\t\tdev->com_rslt = dev->read( dev->dev_id, BME680_MEM_PAGE_ADDR | BME680_SPI_RD_MSK, ®, 1 );\n\n\t\tif ( dev->com_rslt != 0 )\n\t\t{\n\t\t\trslt = BME680_E_COM_FAIL;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdev->mem_page = reg & BME680_MEM_PAGE_MSK;\n\t\t}\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t boundary_check( uint8_t *value, uint8_t min, uint8_t max, struct bme680_dev *dev )\n{\n\tint8_t rslt = BME680_OK;\n\n\tif ( value != NULL )\n\t{\n\t\tif ( *value < min )\n\t\t{\n\t\t\t*value = min;\n\t\t\tdev->info_msg |= BME680_I_MIN_CORRECTION;\n\t\t}\n\n\t\tif ( *value > max )\n\t\t{\n\t\t\t*value = max;\n\t\t\tdev->info_msg |= BME680_I_MAX_CORRECTION;\n\t\t}\n\t}\n\telse\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\n\treturn rslt;\n}\n\nstatic int8_t null_ptr_check( const struct bme680_dev *dev )\n{\n\tint8_t rslt;\n\n\tif ( ( dev == NULL ) || ( dev->read == NULL ) || ( dev->write == NULL ) || ( dev->delay_ms == NULL ) )\n\t{\n\t\trslt = BME680_E_NULL_PTR;\n\t}\n\telse\n\t{\n\t\trslt = BME680_OK;\n\t}\n\n\treturn rslt;\n}\n"
}
}
},
"md5": "beec437787975a2dac4ad728546aab28"
},
"bhi160": {
"libName": "bhi160",
"manufacturer": "Bosch",
"description": "Sensor Hub",
"type": "Accelerometer Gyroscope",
"icon": "",
"image": "",
"version": "",
"eelVersion": "3",
"shoppingCartLinks": {
"digikey": {
"links": {
"info": "https://www.digikey.com/short/p905n3"
},
"cartData": {
"part": "1471-1676-ND",
"source": "dkstudio",
"qty": "1"
}
}
},
"requires": [
"embedded",
"i2c",
"gpio",
"fpmath"
],
"elements": [
{
"name": "EmbeddedBHI160",
"type": "EmbeddedBHI160",
"icon": "EmbeddedGyroscope.svg",
"defaultAbility": "xAcceleration",
"defaultTrigger": "xAccelerationRead",
"hidden": false,
"abilities": [
{
"name": "setup",
"hidden": true,
"code": " BHI160_Config_t config;\n config.i2cInstance = ATMO_PROPERTY(undefined, i2cInstance);\n config.gpioInstance = ATMO_PROPERTY(undefined, gpioInstance);\n config.intPin = ATMO_PROPERTY(undefined, intPin);\n\n if(!BHI160_Init(&config))\n {\n return ATMO_Status_Fail;\n }\n return ATMO_Status_Success;"
},
{
"name": "xAcceleration",
"triggers": [
"xAccelerationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;"
},
{
"name": "yAcceleration",
"triggers": [
"yAccelerationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;"
},
{
"name": "zAcceleration",
"triggers": [
"zAccelerationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;"
},
{
"name": "acceleration",
"triggers": [
"accelerationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(&data, NULL, NULL);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;"
},
{
"name": "angularRate",
"triggers": [
"angularRateRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;"
},
{
"name": "xAngularRate",
"triggers": [
"xAngularRateRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;"
},
{
"name": "yAngularRate",
"triggers": [
"yAngularRateRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;"
},
{
"name": "zAngularRate",
"triggers": [
"zAngularRateRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, &data, NULL);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;"
},
{
"name": "orientation",
"triggers": [
"orientationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValue3dVectorFloat(out, &data);\n return ATMO_Status_Success;"
},
{
"name": "xOrientation",
"triggers": [
"xOrientationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.x);\n return ATMO_Status_Success;"
},
{
"name": "yOrientation",
"triggers": [
"yOrientationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.y);\n return ATMO_Status_Success;"
},
{
"name": "zOrientation",
"triggers": [
"zOrientationRead"
],
"code": " ATMO_3dFloatVector_t data;\n BHI160_GetData(NULL, NULL, &data);\n ATMO_CreateValueFloat(out, data.z);\n return ATMO_Status_Success;"
}
],
"properties": [
{
"name": "i2cInstance",
"input": "driverInstance",
"driverType": "i2c"
},
{
"name": "gpioInstance",
"input": "driverInstance",
"driverType": "gpio"
},
{
"name": "intPin",
"input": "number",
"value": 9
}
],
...
This file has been truncated, please download it to see its full contents.
Comments