mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-17 05:12:57 +01:00
cpu/efm32: add coretemp driver
This commit is contained in:
parent
a11514a198
commit
431e6efdf6
@ -29,4 +29,9 @@ ifneq (,$(filter cpu_ezr32wg,$(USEMODULE)))
|
||||
DIRS += families/ezr32wg
|
||||
endif
|
||||
|
||||
# add EFM32 specific drivers, if enabled
|
||||
ifneq (,$(filter efm32_coretemp,$(USEMODULE)))
|
||||
DIRS += drivers/coretemp
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
@ -16,6 +16,10 @@ USEPKG += gecko_sdk
|
||||
# include layered power management
|
||||
USEMODULE += pm_layered
|
||||
|
||||
ifneq (,$(filter efm32_coretemp,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_adc
|
||||
endif
|
||||
|
||||
# CMSIS-DSP is needed for arm_math.h on Cortex-M0+ architectures
|
||||
ifeq ($(CPU_CORE),cortex-m0plus)
|
||||
USEPKG += cmsis-dsp
|
||||
|
@ -16,6 +16,9 @@ RIOTBOOT_LEN ?= 0x2000
|
||||
# the em_device.h header requires a global define with the cpu model
|
||||
CFLAGS += -D$(call uppercase_and_underscore,$(CPU_MODEL))
|
||||
|
||||
# include EFM32 specific driver headers
|
||||
INCLUDES += -I$(RIOTCPU)/efm32/include/drivers
|
||||
|
||||
# include cortexm_common
|
||||
LINKER_SCRIPT = cortexm.ld
|
||||
|
||||
|
3
cpu/efm32/drivers/coretemp/Makefile
Normal file
3
cpu/efm32/drivers/coretemp/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = efm32_coretemp
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
79
cpu/efm32/drivers/coretemp/coretemp.c
Normal file
79
cpu/efm32/drivers/coretemp/coretemp.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_efm32_drivers_coretemp
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of EFM32 internal temperature sensor
|
||||
*
|
||||
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "coretemp.h"
|
||||
|
||||
#include "periph/adc.h"
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
int16_t coretemp_read(void)
|
||||
{
|
||||
/* initialize factory calibration values */
|
||||
int32_t cal_temp = ((DEVINFO->CAL & _DEVINFO_CAL_TEMP_MASK) >>
|
||||
_DEVINFO_CAL_TEMP_SHIFT);
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
int32_t cal_value = ((DEVINFO->ADC0CAL2 & _DEVINFO_ADC0CAL2_TEMP1V25_MASK) >>
|
||||
_DEVINFO_ADC0CAL2_TEMP1V25_SHIFT);
|
||||
#else
|
||||
int32_t cal_value = ((DEVINFO->ADC0CAL3 & _DEVINFO_ADC0CAL3_TEMPREAD1V25_MASK) >>
|
||||
_DEVINFO_ADC0CAL3_TEMPREAD1V25_SHIFT);
|
||||
#endif
|
||||
|
||||
/* no factory calibration values */
|
||||
if ((cal_temp == 0xFF) || (cal_value == 0x0FFF)) {
|
||||
return -10000;
|
||||
}
|
||||
|
||||
/* convert temperature channel */
|
||||
int32_t value = adc_sample(CORETEMP_ADC, ADC_RES_12BIT);
|
||||
|
||||
/* t_grad is the inverse of 1.25 Vref / (4096 * mV/C) times 1000, so that
|
||||
we can divide by an integer below with sufficient resolution (values
|
||||
are from the datasheets) */
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
int32_t t_grad = -6291; /* -1.92 mV/C */
|
||||
#else
|
||||
int32_t t_grad = -6029; /* -1.84 mv/C */
|
||||
#endif
|
||||
|
||||
/* convert to degrees centi-degrees Celsius (times 100) */
|
||||
return (int16_t) ((cal_temp * 100) - ((cal_value - value) * 100000 / t_grad));
|
||||
}
|
||||
|
||||
int coretemp_init(void)
|
||||
{
|
||||
/* sanity check to ensure the internal temperature sensor is selected */
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
assert(adc_channel_config[CORETEMP_ADC].input == adcSingleInputTemp);
|
||||
#else
|
||||
assert(adc_channel_config[CORETEMP_ADC].input == adcPosSelTEMP);
|
||||
#endif
|
||||
|
||||
/* initialize ADC */
|
||||
if (adc_init(CORETEMP_ADC) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
44
cpu/efm32/drivers/coretemp/coretemp_saul.c
Normal file
44
cpu/efm32/drivers/coretemp/coretemp_saul.c
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_efm32_drivers_coretemp
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief SAUL adoption for EFM32 internal temperature sensor
|
||||
*
|
||||
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "coretemp.h"
|
||||
|
||||
#include "saul_reg.h"
|
||||
|
||||
static int _read(const void *dev, phydat_t *res)
|
||||
{
|
||||
(void)dev;
|
||||
|
||||
res->val[0] = coretemp_read();
|
||||
res->unit = UNIT_TEMP_C;
|
||||
res->scale = -2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const saul_driver_t efm32_coretemp_saul_driver = {
|
||||
.read = _read,
|
||||
.write = saul_notsup,
|
||||
.type = SAUL_SENSE_TEMP
|
||||
};
|
||||
|
||||
const saul_reg_info_t efm32_coretemp_saul_info = {
|
||||
.name = "coretemp"
|
||||
};
|
5
cpu/efm32/drivers/doc.txt
Normal file
5
cpu/efm32/drivers/doc.txt
Normal file
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @defgroup cpu_efm32_drivers EFM32 specific drivers
|
||||
* @ingroup cpu_efm32
|
||||
* @brief Specific drivers for the EFM32 family of CPUs.
|
||||
*/
|
68
cpu/efm32/include/drivers/coretemp.h
Normal file
68
cpu/efm32/include/drivers/coretemp.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup cpu_efm32_drivers_coretemp EFM32 internal temperature sensor
|
||||
* @ingroup cpu_efm32_drivers
|
||||
* @ingroup drivers_saul
|
||||
* @brief Driver for the EFM32 internal temperature sensor
|
||||
*
|
||||
* All EFM32 chips have an internal ADC input channel that reads the internal
|
||||
* temperature sensor. This EFM32-specific driver provides an interface for
|
||||
* reading this value, compensated using factory-calibrated values.
|
||||
*
|
||||
* The board must define `CORETEMP_ADC` to point to the ADC line that connects
|
||||
* to the right ADC input channel.
|
||||
*
|
||||
* This driver provides @ref drivers_saul capabilities.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Interface definition of the EFM32 internal temperature sensor
|
||||
* driver.
|
||||
*
|
||||
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef DRIVERS_CORETEMP_H
|
||||
#define DRIVERS_CORETEMP_H
|
||||
|
||||
#include "kernel_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize the sensor.
|
||||
*
|
||||
* @return 0 on successful initialization
|
||||
* @return -EIO on ADC initialization error
|
||||
*
|
||||
* This driver assumes that the `CORETEMP_ADC` is defined and points to the ADC
|
||||
* input channel that is connected to the internal temperature sensor.
|
||||
*/
|
||||
int coretemp_init(void);
|
||||
|
||||
/**
|
||||
* @brief Read the current temperature from the sensor.
|
||||
*
|
||||
* @return current temperature in centi-degrees Celsius
|
||||
* (times 100)
|
||||
*
|
||||
* Temperature readings are compensated using the factory-calibration values.
|
||||
*/
|
||||
int16_t coretemp_read(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* DRIVERS_CORETEMP_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user