/* * Copyright (c) 2023 Andriy Gelman * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT infineon_xmc4xxx_temp #include #include #include #include #include #include LOG_MODULE_REGISTER(xmc4xxx_temp, CONFIG_SENSOR_LOG_LEVEL); struct xmc4xxx_temp_data { float temp_out; }; static int xmc4xxx_temp_sample_fetch(const struct device *dev, enum sensor_channel chan) { struct xmc4xxx_temp_data *data = dev->data; int32_t val; int ret; if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) { return -ENOTSUP; } ret = XMC_SCU_StartTemperatureMeasurement(); if (ret != 0) { return -EBUSY; } while (XMC_SCU_IsTemperatureSensorBusy()) { }; val = XMC_SCU_GetTemperatureMeasurement(); /* See Infineon XMC4500 Reference Manual Section 11.2.5.1 */ data->temp_out = (val - 605) / 2.05f; return ret; } static int xmc4xxx_temp_channel_get(const struct device *dev, enum sensor_channel chan, struct sensor_value *val) { struct xmc4xxx_temp_data *data = dev->data; if (chan != SENSOR_CHAN_DIE_TEMP) { return -ENOTSUP; } return sensor_value_from_double(val, data->temp_out); } static const struct sensor_driver_api xmc4xxx_temp_driver_api = { .sample_fetch = xmc4xxx_temp_sample_fetch, .channel_get = xmc4xxx_temp_channel_get, }; static int xmc4xxx_temp_init(const struct device *dev) { ARG_UNUSED(dev); XMC_SCU_EnableTemperatureSensor(); BUILD_ASSERT(CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET >= -64 && CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET <= 63); BUILD_ASSERT(CONFIG_XMC4XXX_TEMP_CALIBRATE_GAIN >= 0 && CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET <= 63); XMC_SCU_CalibrateTemperatureSensor(CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET & 0x7f, CONFIG_XMC4XXX_TEMP_CALIBRATE_GAIN); return 0; } #define XMC4XXX_TEMP_DEFINE(inst) \ static struct xmc4xxx_temp_data xmc4xxx_temp_dev_data_##inst; \ \ SENSOR_DEVICE_DT_INST_DEFINE(inst, xmc4xxx_temp_init, NULL, \ &xmc4xxx_temp_dev_data_##inst, NULL, \ POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ &xmc4xxx_temp_driver_api); \ DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_TEMP_DEFINE)