Compare commits
No commits in common. "fc2f57e4cb7bacc0910f98dd23890eba9a6e4063" and "6250786c661d862e8c8228bd870e4b362fcfc4c0" have entirely different histories.
fc2f57e4cb
...
6250786c66
19 changed files with 10 additions and 2312 deletions
|
@ -1,4 +1,2 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory(drivers)
|
||||
|
|
2
Kconfig
2
Kconfig
|
@ -5,5 +5,5 @@
|
|||
# as the module Kconfig entry point (see zephyr/module.yml). You can browse
|
||||
# module options by going to Zephyr -> Modules in Kconfig.
|
||||
|
||||
rsource "drivers/Kconfig"
|
||||
# rsource "drivers/Kconfig"
|
||||
# rsource "lib/Kconfig"
|
|
@ -10,9 +10,6 @@ CONFIG_I2C_SHELL=y
|
|||
CONFIG_INPUT_SHELL=y
|
||||
CONFIG_LV_Z_SHELL=y
|
||||
|
||||
CONFIG_SENSOR_SHELL=y
|
||||
# CONFIG_SENSOR_SHELL_BATTERY=y
|
||||
|
||||
# LVGL
|
||||
CONFIG_LVGL=y
|
||||
CONFIG_LV_COLOR_DEPTH_32=y
|
||||
|
|
|
@ -12,14 +12,11 @@
|
|||
#include <lvgl_input_device.h>
|
||||
|
||||
#include <zephyr/drivers/display.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include <zephyr/input/input.h>
|
||||
#include <zephyr/random/random.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
|
||||
#include "../../drivers/sensor/mlx90640/mlx90640.h"
|
||||
|
||||
LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL);
|
||||
|
||||
int main(void)
|
||||
|
@ -29,7 +26,6 @@ int main(void)
|
|||
|
||||
char count_str[11] = {0};
|
||||
const struct device *display_dev;
|
||||
const struct device *ir_dev;
|
||||
|
||||
display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
|
||||
if (!device_is_ready(display_dev))
|
||||
|
@ -51,64 +47,33 @@ int main(void)
|
|||
lv_obj_t *ir_image = lv_canvas_create(lv_scr_act());
|
||||
lv_canvas_set_buffer(ir_image, cbuf, 32, 24, LV_IMG_CF_TRUE_COLOR);
|
||||
|
||||
lv_canvas_fill_bg(ir_image, lv_color_make(0x40, 0x40, 0x40), LV_OPA_COVER);
|
||||
lv_canvas_fill_bg(ir_image, lv_color_make(0x40,0x40,0x40), LV_OPA_COVER);
|
||||
|
||||
lv_obj_set_size(ir_image, 32, 24);
|
||||
lv_obj_align(ir_image, LV_ALIGN_TOP_LEFT, 4, 4);
|
||||
lv_img_set_pivot(ir_image, 0, 0);
|
||||
// lv_img_set_zoom(ir_image, 256 * 2);
|
||||
lv_img_set_zoom(ir_image, 256 * 12);
|
||||
lv_img_set_zoom(ir_image, 256 * 8);
|
||||
lv_img_set_antialias(ir_image, false);
|
||||
|
||||
lv_timer_handler();
|
||||
display_blanking_off(display_dev);
|
||||
|
||||
ir_dev = DEVICE_DT_GET(DT_NODELABEL(mlx90640_mlx90640_elecrow_i2c));
|
||||
if (!device_is_ready(ir_dev))
|
||||
{
|
||||
printf("Device %s not ready\n", ir_dev->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lv_color32_t color;
|
||||
float *temps = ((struct mlx90640_data *)ir_dev->data)->temps;
|
||||
int64_t reftime = k_uptime_get();
|
||||
while (1)
|
||||
{
|
||||
sensor_sample_fetch(ir_dev);
|
||||
mlx90640_calculate_to(ir_dev, 0.8, ((struct mlx90640_data *)ir_dev->data)->ta - 8.0f); // Tr = Ta - 8.0 from PDF
|
||||
|
||||
for (int y = 0; y < 24; y++)
|
||||
{
|
||||
for (int x = 0; x < 32; x++)
|
||||
{
|
||||
if (temps[y * 32 + x] < 0)
|
||||
{
|
||||
color = lv_color_black();
|
||||
}
|
||||
else if (temps[y * 32 + x] > 64)
|
||||
{
|
||||
color = lv_color_white();
|
||||
}
|
||||
else
|
||||
{
|
||||
color.ch.red = (uint8_t)(temps[y * 32 + x] * 4);
|
||||
color.ch.green = color.ch.red;
|
||||
color.ch.blue = color.ch.red;
|
||||
}
|
||||
color.ch.red = (color.ch.red + 11) % 255;
|
||||
color.ch.green = (color.ch.green + 17) % 255;
|
||||
color.ch.blue = (color.ch.blue + 13) % 255;
|
||||
lv_canvas_set_px_color(ir_image, x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
lv_timer_handler();
|
||||
|
||||
int64_t elapsed = k_uptime_delta(&reftime);
|
||||
printf("took %d ms", (uint32_t)elapsed);
|
||||
|
||||
if (elapsed < 100)
|
||||
{
|
||||
k_msleep(100 - elapsed);
|
||||
}
|
||||
int delay = lv_timer_handler_run_in_period(100);
|
||||
k_msleep(delay);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SHIELD_MLX90640_ELECROW_I2C
|
||||
|
||||
config SENSOR
|
||||
default y
|
||||
|
||||
config MLX90640
|
||||
default y
|
||||
|
||||
endif # SHIELD_MLX90640_ELECROW_I2C
|
|
@ -1,6 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config SHIELD_MLX90640_ELECROW_I2C
|
||||
def_bool $(shields_list_contains,mlx90640_elecrow_i2c)
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024 PM
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
&i2c0 {
|
||||
status = "okay";
|
||||
|
||||
mlx90640_mlx90640_elecrow_i2c: mlx90640@33 {
|
||||
compatible = "melexis,mlx90640";
|
||||
reg = <0x33>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
|
@ -82,7 +82,7 @@
|
|||
};
|
||||
|
||||
&i2c0 {
|
||||
clock-frequency = <I2C_BITRATE_FAST>;
|
||||
clock-frequency = <I2C_BITRATE_STANDARD>;
|
||||
pinctrl-0 = <&i2c0_default>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
CONFIG_BOARD_ELECROW_ESP_TERMINAL=y
|
||||
CONFIG_SOC_SERIES_ESP32S3=y
|
||||
|
||||
# increased for LVGL
|
||||
CONFIG_MAIN_STACK_SIZE=8192
|
||||
CONFIG_MAIN_STACK_SIZE=8192 # increased for LVGL
|
||||
|
||||
CONFIG_CONSOLE=y
|
||||
CONFIG_SERIAL=y
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_SENSOR sensor)
|
|
@ -1,6 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
menu "Drivers"
|
||||
rsource "sensor/Kconfig"
|
||||
endmenu
|
|
@ -1,4 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_MLX90640 mlx90640)
|
|
@ -1,6 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SENSOR
|
||||
rsource "mlx90640/Kconfig"
|
||||
endif # SENSOR
|
|
@ -1,7 +0,0 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
|
||||
zephyr_library_sources(mlx90640.c)
|
||||
# zephyr_library_sources_ifdef(CONFIG_MLX90640_TRIGGER mlx90640_trigger.c)
|
||||
# zephyr_library_sources(vendor/functions/MLX90640.c)
|
|
@ -1,55 +0,0 @@
|
|||
# MLX90640 infrared thermopile sensor configuration options
|
||||
|
||||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# menuconfig MLX90640
|
||||
config MLX90640
|
||||
bool "MLX90640 Infrared Thermopile Sensor"
|
||||
default y
|
||||
depends on DT_HAS_MELEXIS_MLX90640_ENABLED
|
||||
select I2C
|
||||
help
|
||||
Enable driver for MLX90640 infrared thermopile sensor.
|
||||
|
||||
# if MLX90640
|
||||
|
||||
# choice
|
||||
# prompt "Trigger mode"
|
||||
# default MLX90640_TRIGGER_NONE
|
||||
# help
|
||||
# Specify the type of triggering used by the driver.
|
||||
|
||||
# config MLX90640_TRIGGER_NONE
|
||||
# bool "No trigger"
|
||||
|
||||
# config MLX90640_TRIGGER_GLOBAL_THREAD
|
||||
# bool "Use global thread"
|
||||
# depends on GPIO
|
||||
# select MLX90640_TRIGGER
|
||||
|
||||
# config MLX90640_TRIGGER_OWN_THREAD
|
||||
# bool "Use own thread"
|
||||
# depends on GPIO
|
||||
# select MLX90640_TRIGGER
|
||||
|
||||
# endchoice
|
||||
|
||||
# config MLX90640_TRIGGER
|
||||
# bool
|
||||
|
||||
# config MLX90640_THREAD_PRIORITY
|
||||
# int "Thread priority"
|
||||
# depends on MLX90640_TRIGGER_OWN_THREAD
|
||||
# default 10
|
||||
# help
|
||||
# Priority of thread used by the driver to handle interrupts.
|
||||
|
||||
# config MLX90640_THREAD_STACK_SIZE
|
||||
# int "Thread stack size"
|
||||
# depends on MLX90640_TRIGGER_OWN_THREAD
|
||||
# default 1024
|
||||
# help
|
||||
# Stack size of thread used by the driver to handle interrupts.
|
||||
|
||||
# endif # MLX90640
|
File diff suppressed because it is too large
Load diff
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024 PM
|
||||
*
|
||||
* using code from Melexis https://github.com/melexis/mlx90640-library,
|
||||
* commit f6be7ca1d4a55146b705f3d347f84b773b29cc86 under Apache-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_DRIVERS_SENSOR_MLX90640_MLX90640_H_
|
||||
#define ZEPHYR_DRIVERS_SENSOR_MLX90640_MLX90640_H_
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t kVdd;
|
||||
int16_t vdd25;
|
||||
float KvPTAT;
|
||||
float KtPTAT;
|
||||
uint16_t vPTAT25;
|
||||
float alphaPTAT;
|
||||
int16_t gainEE;
|
||||
float tgc;
|
||||
float cpKv;
|
||||
float cpKta;
|
||||
uint8_t resolutionEE;
|
||||
uint8_t calibrationModeEE;
|
||||
float KsTa;
|
||||
float ksTo[5];
|
||||
int16_t ct[5];
|
||||
uint16_t alpha[768];
|
||||
uint8_t alphaScale;
|
||||
int16_t offset[768];
|
||||
int8_t kta[768];
|
||||
uint8_t ktaScale;
|
||||
int8_t kv[768];
|
||||
uint8_t kvScale;
|
||||
float cpAlpha[2];
|
||||
int16_t cpOffset[2];
|
||||
float ilChessC[3];
|
||||
uint16_t brokenPixels[5];
|
||||
uint16_t outlierPixels[5];
|
||||
} mlx90640_params;
|
||||
|
||||
enum mlx90640_refresh_rate
|
||||
{
|
||||
MLX90640_REFRESH_0_5 = 0,
|
||||
MLX90640_REFRESH_1 = 1,
|
||||
MLX90640_REFRESH_2 = 2,
|
||||
MLX90640_REFRESH_4 = 3,
|
||||
MLX90640_REFRESH_8 = 4,
|
||||
MLX90640_REFRESH_16 = 5,
|
||||
MLX90640_REFRESH_32 = 6,
|
||||
MLX90640_REFRESH_64 = 7,
|
||||
};
|
||||
|
||||
enum mlx90640_adc_resolution
|
||||
{
|
||||
MLX90640_ADC_RES_16 = 0,
|
||||
MLX90640_ADC_RES_17 = 1,
|
||||
MLX90640_ADC_RES_18 = 2,
|
||||
MLX90640_ADC_RES_19 = 3,
|
||||
};
|
||||
|
||||
enum mlx90640_reading_pattern
|
||||
{
|
||||
MLX90640_PATTERN_INTERLEAVED = 0,
|
||||
MLX90640_PATTERN_CHESS = 1,
|
||||
};
|
||||
|
||||
struct mlx90640_config
|
||||
{
|
||||
const struct i2c_dt_spec i2c;
|
||||
const enum mlx90640_refresh_rate refresh_rate;
|
||||
const enum mlx90640_adc_resolution adc_resolution;
|
||||
const enum mlx90640_reading_pattern reading_pattern;
|
||||
};
|
||||
|
||||
struct mlx90640_data
|
||||
{
|
||||
float temps[768];
|
||||
float vdd;
|
||||
float ta;
|
||||
uint16_t raw_data[833]; // 768 px + 64 metadata + 1 status
|
||||
mlx90640_params params;
|
||||
|
||||
#ifdef CONFIG_MLX90640_TRIGGER
|
||||
const struct device *dev;
|
||||
struct gpio_callback gpio_cb;
|
||||
|
||||
sensor_trigger_handler_t drdy_handler;
|
||||
const struct sensor_trigger *drdy_trigger;
|
||||
|
||||
sensor_trigger_handler_t th_handler;
|
||||
const struct sensor_trigger *th_trigger;
|
||||
|
||||
#if defined(CONFIG_MLX90640_TRIGGER_OWN_THREAD)
|
||||
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_MLX90640_THREAD_STACK_SIZE);
|
||||
struct k_sem gpio_sem;
|
||||
struct k_thread thread;
|
||||
#elif defined(CONFIG_MLX90640_TRIGGER_GLOBAL_THREAD)
|
||||
struct k_work work;
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_MLX90640_TRIGGER */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MLX90640_TRIGGER
|
||||
int mlx90640_attr_set(const struct device *dev, enum sensor_channel chan, enum sensor_attribute attr,
|
||||
const struct sensor_value *val);
|
||||
|
||||
int mlx90640_trigger_set(const struct device *dev, const struct sensor_trigger *trig, sensor_trigger_handler_t handler);
|
||||
|
||||
int mlx90640_init_interrupt(const struct device *dev);
|
||||
#endif /* CONFIG_MLX90640_TRIGGER */
|
||||
|
||||
// data
|
||||
int mlx90640_synch_frame(const struct device *dev);
|
||||
int mlx90640_trigger_measurement(const struct device *dev);
|
||||
int mlx90640_get_frame_data(const struct device *dev);
|
||||
|
||||
// process
|
||||
float mlx90640_get_vdd(const struct device *dev);
|
||||
float mlx90640_get_ta(const struct device *dev);
|
||||
|
||||
// void mlx90640_get_image(const struct device *dev);
|
||||
// or!
|
||||
void mlx90640_calculate_to(const struct device *dev, float emissivity, float tr);
|
||||
|
||||
// optional /
|
||||
void mlx90640_bad_pixels_correction(const struct device *dev, int mode);
|
||||
|
||||
int mlx90640_set_adc_resolution(const struct device *dev, enum mlx90640_adc_resolution res);
|
||||
enum mlx90640_adc_resolution mlx90640_get_adc_resolution(const struct device *dev);
|
||||
|
||||
int mlx90640_set_refresh_rate(const struct device *dev, enum mlx90640_refresh_rate res);
|
||||
enum mlx90640_refresh_rate mlx90640_get_refresh_rate(const struct device *dev);
|
||||
|
||||
int mlx90640_set_reading_pattern(const struct device *dev, enum mlx90640_reading_pattern res);
|
||||
enum mlx90640_reading_pattern mlx90640_get_reading_pattern(const struct device *dev);
|
||||
|
||||
#endif
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2019 Phytec Messtechnik GmbH
|
||||
* Copyright (c) 2017 Benedict Ohl (Benedict-Ohl@web.de)
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/drivers/gpio.h>
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/sys/util.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/sensor.h>
|
||||
#include "amg88xx.h"
|
||||
|
||||
extern struct amg88xx_data amg88xx_driver;
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(AMG88XX, CONFIG_SENSOR_LOG_LEVEL);
|
||||
|
||||
static inline void amg88xx_setup_int(const struct amg88xx_config *cfg,
|
||||
bool enable)
|
||||
{
|
||||
unsigned int flags = enable
|
||||
? GPIO_INT_EDGE_TO_ACTIVE
|
||||
: GPIO_INT_DISABLE;
|
||||
|
||||
gpio_pin_interrupt_configure_dt(&cfg->int_gpio, flags);
|
||||
}
|
||||
|
||||
int amg88xx_attr_set(const struct device *dev,
|
||||
enum sensor_channel chan,
|
||||
enum sensor_attribute attr,
|
||||
const struct sensor_value *val)
|
||||
{
|
||||
const struct amg88xx_config *config = dev->config;
|
||||
int16_t int_level = (val->val1 * 1000000 + val->val2) /
|
||||
AMG88XX_TREG_LSB_SCALING;
|
||||
uint8_t intl_reg;
|
||||
uint8_t inth_reg;
|
||||
|
||||
if (!config->int_gpio.port) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (chan != SENSOR_CHAN_AMBIENT_TEMP) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
LOG_DBG("set threshold to %d", int_level);
|
||||
|
||||
if (attr == SENSOR_ATTR_UPPER_THRESH) {
|
||||
intl_reg = AMG88XX_INTHL;
|
||||
inth_reg = AMG88XX_INTHH;
|
||||
} else if (attr == SENSOR_ATTR_LOWER_THRESH) {
|
||||
intl_reg = AMG88XX_INTLL;
|
||||
inth_reg = AMG88XX_INTLH;
|
||||
} else {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
intl_reg, (uint8_t)int_level)) {
|
||||
LOG_DBG("Failed to set INTxL attribute!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
inth_reg, (uint8_t)(int_level >> 8))) {
|
||||
LOG_DBG("Failed to set INTxH attribute!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void amg88xx_gpio_callback(const struct device *dev,
|
||||
struct gpio_callback *cb, uint32_t pins)
|
||||
{
|
||||
struct amg88xx_data *drv_data =
|
||||
CONTAINER_OF(cb, struct amg88xx_data, gpio_cb);
|
||||
const struct amg88xx_config *config = drv_data->dev->config;
|
||||
|
||||
amg88xx_setup_int(config, false);
|
||||
|
||||
#if defined(CONFIG_AMG88XX_TRIGGER_OWN_THREAD)
|
||||
k_sem_give(&drv_data->gpio_sem);
|
||||
#elif defined(CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD)
|
||||
k_work_submit(&drv_data->work);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void amg88xx_thread_cb(const struct device *dev)
|
||||
{
|
||||
struct amg88xx_data *drv_data = dev->data;
|
||||
const struct amg88xx_config *config = dev->config;
|
||||
uint8_t status;
|
||||
|
||||
if (i2c_reg_read_byte_dt(&config->i2c,
|
||||
AMG88XX_STAT, &status) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drv_data->drdy_handler != NULL) {
|
||||
drv_data->drdy_handler(dev, drv_data->drdy_trigger);
|
||||
}
|
||||
|
||||
if (drv_data->th_handler != NULL) {
|
||||
drv_data->th_handler(dev, drv_data->th_trigger);
|
||||
}
|
||||
|
||||
amg88xx_setup_int(config, true);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AMG88XX_TRIGGER_OWN_THREAD
|
||||
static void amg88xx_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
struct amg88xx_data *drv_data = p1;
|
||||
|
||||
while (42) {
|
||||
k_sem_take(&drv_data->gpio_sem, K_FOREVER);
|
||||
amg88xx_thread_cb(drv_data->dev);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD
|
||||
static void amg88xx_work_cb(struct k_work *work)
|
||||
{
|
||||
struct amg88xx_data *drv_data =
|
||||
CONTAINER_OF(work, struct amg88xx_data, work);
|
||||
amg88xx_thread_cb(drv_data->dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
int amg88xx_trigger_set(const struct device *dev,
|
||||
const struct sensor_trigger *trig,
|
||||
sensor_trigger_handler_t handler)
|
||||
{
|
||||
struct amg88xx_data *drv_data = dev->data;
|
||||
const struct amg88xx_config *config = dev->config;
|
||||
|
||||
if (!config->int_gpio.port) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
AMG88XX_INTC, AMG88XX_INTC_DISABLED)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
amg88xx_setup_int(config, false);
|
||||
|
||||
if (trig->type == SENSOR_TRIG_THRESHOLD) {
|
||||
drv_data->th_handler = handler;
|
||||
drv_data->th_trigger = trig;
|
||||
} else {
|
||||
LOG_ERR("Unsupported sensor trigger");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
amg88xx_setup_int(config, true);
|
||||
|
||||
if (i2c_reg_write_byte_dt(&config->i2c,
|
||||
AMG88XX_INTC, AMG88XX_INTC_ABS_MODE)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amg88xx_init_interrupt(const struct device *dev)
|
||||
{
|
||||
struct amg88xx_data *drv_data = dev->data;
|
||||
const struct amg88xx_config *config = dev->config;
|
||||
|
||||
if (!gpio_is_ready_dt(&config->int_gpio)) {
|
||||
LOG_ERR("%s: device %s is not ready", dev->name,
|
||||
config->int_gpio.port->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
gpio_pin_configure_dt(&config->int_gpio, GPIO_INPUT | config->int_gpio.dt_flags);
|
||||
|
||||
gpio_init_callback(&drv_data->gpio_cb,
|
||||
amg88xx_gpio_callback,
|
||||
BIT(config->int_gpio.pin));
|
||||
|
||||
if (gpio_add_callback(config->int_gpio.port, &drv_data->gpio_cb) < 0) {
|
||||
LOG_DBG("Failed to set gpio callback!");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
drv_data->dev = dev;
|
||||
|
||||
#if defined(CONFIG_AMG88XX_TRIGGER_OWN_THREAD)
|
||||
k_sem_init(&drv_data->gpio_sem, 0, K_SEM_MAX_LIMIT);
|
||||
|
||||
k_thread_create(&drv_data->thread, drv_data->thread_stack,
|
||||
CONFIG_AMG88XX_THREAD_STACK_SIZE,
|
||||
amg88xx_thread, drv_data,
|
||||
NULL, NULL, K_PRIO_COOP(CONFIG_AMG88XX_THREAD_PRIORITY),
|
||||
0, K_NO_WAIT);
|
||||
#elif defined(CONFIG_AMG88XX_TRIGGER_GLOBAL_THREAD)
|
||||
drv_data->work.handler = amg88xx_work_cb;
|
||||
#endif
|
||||
amg88xx_setup_int(config, true);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
# Copyright (c) 2024 PM
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Melexis MLX90640 32x24 (768) pixel infrared array sensor
|
||||
|
||||
compatible: "melexis,mlx90640"
|
||||
|
||||
include: [sensor-device.yaml, i2c-device.yaml]
|
||||
|
||||
properties:
|
||||
refresh-rate:
|
||||
type: int
|
||||
default: 2
|
||||
enum:
|
||||
- 0 # 0.5HZ
|
||||
- 1 # 1HZ
|
||||
- 2 # 2HZ
|
||||
- 3 # 4HZ
|
||||
- 4 # 8HZ
|
||||
- 5 # 16HZ
|
||||
- 6 # 32HZ
|
||||
- 7 # 64HZ
|
||||
description:
|
||||
Refresh rate of the sensor itself.
|
||||
The I2C must be configured to keep up with the data flow.
|
||||
This configures the rate for subfields, i.e. the full frame rate is half of this value.
|
||||
|
||||
adc-resolution:
|
||||
type: int
|
||||
default: 2
|
||||
enum:
|
||||
- 0 # 16BIT
|
||||
- 1 # 17BIT
|
||||
- 2 # 18BIT
|
||||
- 3 # 19BIT
|
||||
description:
|
||||
ADC resolution.
|
||||
|
||||
reading-pattern:
|
||||
type: int
|
||||
default: 1
|
||||
enum:
|
||||
- 0 # CHESS
|
||||
- 1 # INTERLEAVE
|
||||
description:
|
||||
Reading pattern.
|
||||
The sensor can be read in either line-interleaved subfields (similar to a TV video)
|
||||
or a pixel alternating "chess board" pattern.
|
Loading…
Reference in a new issue