| /* |
| * Copyright (c) 2019 Peter Bigot Consulting, LLC |
| * Copyright (c) 2016 Intel Corporation. |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/kernel.h> |
| #include <zephyr/device.h> |
| #include <zephyr/drivers/sensor.h> |
| #include <stdio.h> |
| |
| #define UCEL_PER_CEL 1000000 |
| #define UCEL_PER_MCEL 1000 |
| #define TEMP_INITIAL_CEL 25 |
| #define TEMP_WINDOW_HALF_UCEL 500000 |
| |
| static const char *now_str(void) |
| { |
| static char buf[16]; /* ...HH:MM:SS.MMM */ |
| uint32_t now = k_uptime_get_32(); |
| unsigned int ms = now % MSEC_PER_SEC; |
| unsigned int s; |
| unsigned int min; |
| unsigned int h; |
| |
| now /= MSEC_PER_SEC; |
| s = now % 60U; |
| now /= 60U; |
| min = now % 60U; |
| now /= 60U; |
| h = now; |
| |
| snprintf(buf, sizeof(buf), "%u:%02u:%02u.%03u", |
| h, min, s, ms); |
| return buf; |
| } |
| |
| #ifdef CONFIG_JC42_TRIGGER |
| |
| static struct sensor_trigger sensor_trig; |
| |
| static int set_window(const struct device *dev, |
| const struct sensor_value *temp) |
| { |
| const int temp_ucel = temp->val1 * UCEL_PER_CEL + temp->val2; |
| const int low_ucel = temp_ucel - TEMP_WINDOW_HALF_UCEL; |
| const int high_ucel = temp_ucel + TEMP_WINDOW_HALF_UCEL; |
| struct sensor_value val = { |
| .val1 = low_ucel / UCEL_PER_CEL, |
| .val2 = low_ucel % UCEL_PER_CEL, |
| }; |
| int rc = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP, |
| SENSOR_ATTR_LOWER_THRESH, &val); |
| if (rc == 0) { |
| val.val1 = high_ucel / UCEL_PER_CEL, |
| val.val2 = high_ucel % UCEL_PER_CEL, |
| rc = sensor_attr_set(dev, SENSOR_CHAN_AMBIENT_TEMP, |
| SENSOR_ATTR_UPPER_THRESH, &val); |
| } |
| |
| if (rc == 0) { |
| printf("Alert on temp outside [%d, %d] milli-Celsius\n", |
| low_ucel / UCEL_PER_MCEL, |
| high_ucel / UCEL_PER_MCEL); |
| } |
| |
| return rc; |
| } |
| |
| static inline int set_window_ucel(const struct device *dev, |
| int temp_ucel) |
| { |
| struct sensor_value val = { |
| .val1 = temp_ucel / UCEL_PER_CEL, |
| .val2 = temp_ucel % UCEL_PER_CEL, |
| }; |
| |
| return set_window(dev, &val); |
| } |
| |
| static void trigger_handler(const struct device *dev, |
| const struct sensor_trigger *trig) |
| { |
| struct sensor_value temp; |
| static size_t cnt; |
| int rc; |
| |
| ++cnt; |
| rc = sensor_sample_fetch(dev); |
| if (rc != 0) { |
| printf("sensor_sample_fetch error: %d\n", rc); |
| return; |
| } |
| rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); |
| if (rc != 0) { |
| printf("sensor_channel_get error: %d\n", rc); |
| return; |
| } |
| |
| printf("trigger fired %u, temp %g deg C\n", cnt, |
| sensor_value_to_double(&temp)); |
| set_window(dev, &temp); |
| } |
| #endif |
| |
| int main(void) |
| { |
| const struct device *const dev = DEVICE_DT_GET_ANY(jedec_jc_42_4_temp); |
| int rc; |
| |
| if (dev == NULL) { |
| printf("Device not found.\n"); |
| return 0; |
| } |
| if (!device_is_ready(dev)) { |
| printf("Device %s is not ready.\n", dev->name); |
| return 0; |
| } |
| |
| #ifdef CONFIG_JC42_TRIGGER |
| rc = set_window_ucel(dev, TEMP_INITIAL_CEL * UCEL_PER_CEL); |
| if (rc == 0) { |
| sensor_trig.type = SENSOR_TRIG_THRESHOLD; |
| sensor_trig.chan = SENSOR_CHAN_AMBIENT_TEMP; |
| rc = sensor_trigger_set(dev, &sensor_trig, trigger_handler); |
| } |
| |
| if (rc != 0) { |
| printf("Trigger set failed: %d\n", rc); |
| return 0; |
| } |
| printk("Trigger set got %d\n", rc); |
| #endif |
| |
| while (1) { |
| struct sensor_value temp; |
| |
| rc = sensor_sample_fetch(dev); |
| if (rc != 0) { |
| printf("sensor_sample_fetch error: %d\n", rc); |
| break; |
| } |
| |
| rc = sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); |
| if (rc != 0) { |
| printf("sensor_channel_get error: %d\n", rc); |
| break; |
| } |
| |
| printf("%s: %g C\n", now_str(), |
| sensor_value_to_double(&temp)); |
| |
| k_sleep(K_SECONDS(2)); |
| } |
| return 0; |
| } |