| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <bluetooth/bluetooth.h> |
| #include <bluetooth/hci.h> |
| #include <bluetooth/uuid.h> |
| #include <bluetooth/gatt.h> |
| #include <device.h> |
| #include <ipm.h> |
| #include <ipm/ipm_quark_se.h> |
| #include <misc/byteorder.h> |
| #include <misc/printk.h> |
| #include <sensor.h> |
| #include <zephyr.h> |
| |
| #define DEVICE_NAME "Environmental Sensor" |
| #define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) |
| #define TEMPERATURE_CUD "Temperature" |
| #define HUMIDITY_CUD "Humidity" |
| #define PRESSURE_CUD "Pressure" |
| |
| QUARK_SE_IPM_DEFINE(ess_ipm, 0, QUARK_SE_IPM_INBOUND); |
| |
| static int16_t temp_value; |
| static uint16_t humidity_value; |
| static uint32_t pressure_value; |
| |
| static ssize_t read_u16(struct bt_conn *conn, const struct bt_gatt_attr *attr, |
| void *buf, uint16_t len, uint16_t offset) |
| { |
| const uint16_t *u16 = attr->user_data; |
| uint16_t value = sys_cpu_to_le16(*u16); |
| |
| return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, |
| sizeof(value)); |
| } |
| |
| static ssize_t read_u32(struct bt_conn *conn, const struct bt_gatt_attr *attr, |
| void *buf, uint16_t len, uint16_t offset) |
| { |
| const uint32_t *u32 = attr->user_data; |
| uint16_t value = sys_cpu_to_le32(*u32); |
| |
| return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, |
| sizeof(value)); |
| } |
| |
| static struct bt_gatt_attr attrs[] = { |
| BT_GATT_PRIMARY_SERVICE(BT_UUID_ESS), |
| |
| BT_GATT_CHARACTERISTIC(BT_UUID_TEMPERATURE, BT_GATT_CHRC_READ), |
| BT_GATT_DESCRIPTOR(BT_UUID_TEMPERATURE, BT_GATT_PERM_READ, |
| read_u16, NULL, &temp_value), |
| BT_GATT_CUD(TEMPERATURE_CUD, BT_GATT_PERM_READ), |
| |
| BT_GATT_CHARACTERISTIC(BT_UUID_HUMIDITY, BT_GATT_CHRC_READ), |
| BT_GATT_DESCRIPTOR(BT_UUID_HUMIDITY, BT_GATT_PERM_READ, |
| read_u16, NULL, &humidity_value), |
| BT_GATT_CUD(HUMIDITY_CUD, BT_GATT_PERM_READ), |
| |
| BT_GATT_CHARACTERISTIC(BT_UUID_PRESSURE, BT_GATT_CHRC_READ), |
| BT_GATT_DESCRIPTOR(BT_UUID_PRESSURE, BT_GATT_PERM_READ, |
| read_u32, NULL, &pressure_value), |
| BT_GATT_CUD(PRESSURE_CUD, BT_GATT_PERM_READ), |
| }; |
| |
| static const struct bt_data ad[] = { |
| BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), |
| }; |
| |
| static struct bt_data sd[] = { |
| BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), |
| }; |
| |
| static void bt_ready(int err) |
| { |
| if (err) { |
| printk("Bluetooth init failed (err %d)\n", err); |
| return; |
| } |
| |
| bt_gatt_register(attrs, ARRAY_SIZE(attrs)); |
| |
| err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), |
| sd, ARRAY_SIZE(sd)); |
| if (err) { |
| printk("Advertising failed to start (err %d)\n", err); |
| return; |
| } |
| } |
| |
| static void sensor_ipm_callback(void *context, uint32_t id, volatile void *data) |
| { |
| volatile struct sensor_value *val = data; |
| |
| switch (id) { |
| case SENSOR_CHAN_TEMP: |
| /* resolution of 0.01 degrees Celsius */ |
| temp_value = val->val1 * 100 + val->val2 / 10000; |
| break; |
| case SENSOR_CHAN_HUMIDITY: |
| /* resolution of 0.01 percent */ |
| humidity_value = val->val1 / 10; |
| break; |
| case SENSOR_CHAN_PRESS: |
| /* resolution of 0.1 Pa */ |
| pressure_value = val->val1 * 10000 + val->val2 / 100; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| void main(void) |
| { |
| struct device *ipm; |
| int rc; |
| |
| rc = bt_enable(bt_ready); |
| if (rc) { |
| printk("Bluetooth init failed (err %d)\n", rc); |
| return; |
| } |
| |
| ipm = device_get_binding("ess_ipm"); |
| ipm_register_callback(ipm, sensor_ipm_callback, NULL); |
| ipm_set_enabled(ipm, 1); |
| |
| k_sleep(K_FOREVER); |
| } |