551 lines
22 KiB
C
551 lines
22 KiB
C
/*
|
|
* Copyright (c) 2020, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/*!****************************************************************************
|
|
* @file Temperature.h
|
|
*
|
|
* @brief Temperature driver
|
|
*
|
|
* @anchor ti_drivers_Temperature_Overview
|
|
* # Overview #
|
|
* The Temperature driver provides services related to measuring and reacting
|
|
* to the current temperature of the chip and changes to it.
|
|
*
|
|
* The two main services provided are:
|
|
* - Getting the current temperature
|
|
* - Providing notification callbacks when the temperature changes
|
|
*
|
|
* @anchor ti_drivers_Temperature_Usage
|
|
* # Usage #
|
|
*
|
|
* ## Initialisation #
|
|
* Unlike most drivers, there is only a single instance of the temperature
|
|
* driver that is always available once #Temperature_init() is called.
|
|
* #Temperature_init() should be called once before using other Temperature
|
|
* driver APIs. Subsequent #Temperature_init() calls will have no effect.
|
|
*
|
|
* ## Getting the Current Temperature #
|
|
* The most basic function of the driver is to provide the current temperature
|
|
* and return it. It is encoded as a signed integer in degrees C.
|
|
*
|
|
* ## Notifications #
|
|
* The other major function of the Temperature driver is to notify the
|
|
* application when the temperature changes and crosses an application-defined
|
|
* threshold.
|
|
*
|
|
* There are three default usecases for this:
|
|
* - High threshold.
|
|
* The application will receive a notification callback when
|
|
* currentTemperature >= thresholdHigh.
|
|
* - Low threshold.
|
|
* The application will receive a notification callback when
|
|
* currentTemperature <= thresholdLow.
|
|
* - Range threshold.
|
|
* The application will receive a notification callback when
|
|
* currentTemperature >= thresholdHigh || currentTemperature <=
|
|
* thresholdLow. This setup addresses usecases
|
|
* where a notification is required when the temperature changes by a
|
|
* certain amount regardless of whether it is up or down. Adjusting
|
|
* clock offsets based on temperature is a good example of this.
|
|
*
|
|
* ### Registering Notifications
|
|
* There are three functions that register a notification for the application:
|
|
* - #Temperature_registerNotifyHigh()
|
|
* - #Temperature_registerNotifyLow()
|
|
* - #Temperature_registerNotifyRange()
|
|
*
|
|
* Multiple notifications may be registered. The different parts of the
|
|
* application and drivers that need to respond to a temperature change do not
|
|
* need to know of one another.
|
|
* Each notification must have its own #Temperature_NotifyObj and must be
|
|
* registered individually.
|
|
*
|
|
* ### Notification Callbacks
|
|
* Once the chip temperature crosses the smallest high threshold or largest
|
|
* low threshold amongst the registered notifications, the driver will
|
|
* iterate over the entire list of registered notification and check which
|
|
* ones have triggered. Notifications that have triggered are removed from
|
|
* the list of registered notifications and thus are no longer registered.
|
|
* Their callback function is then invoked.
|
|
*
|
|
* If an application wishes to reregister a notification that just triggered
|
|
* and was unregistered, it may register it again from within the notification
|
|
* callback or another context.
|
|
*
|
|
* It is possible to determine whether the high or low threshold triggered
|
|
* the notification callback as follows:
|
|
* - currentTemperature <= thresholdTemperature: Low threshold triggered
|
|
* - currentTemperature >= thresholdTemperature: High threshold triggered
|
|
* This information is only reasonably useful when registering a notification
|
|
* with both a high and low threshold using #Temperature_registerNotifyRange().
|
|
* Even then, the expected basic usecase only cares about the current
|
|
* temperature and adding an offset to it when registering the notification
|
|
* again.
|
|
*
|
|
* ### Unregistering Notifications
|
|
* Registered notifications are unregistered in two ways:
|
|
* - Automatically when a notification triggers
|
|
* - By calling #Temperature_unregisterNotify()
|
|
*
|
|
* Unregistered notifications may be registered again at any time.
|
|
*
|
|
* # Measured vs True Temperature
|
|
* While the driver aims to supply and act on an accurate absolute temperature,
|
|
* there will be differences between the measured vs the true temperature due
|
|
* to inherent variances in the manufacturing process. The nature of these
|
|
* differences varies by device family.
|
|
*
|
|
* Examples of such differences:
|
|
* - A constant per-chip offset between the measured and the true
|
|
* temperature
|
|
* - An temperature dependent per-chip offset between the measured and the
|
|
* true temperature
|
|
* - A variance in the measured temperature when measuring multiple times
|
|
* at the same chip temperature
|
|
*
|
|
* It is strongly recommended to read the device-specific Temperature driver
|
|
* documentation for details of the temperature sensor characteristics and
|
|
* how they might affect choices of threshold values.
|
|
*
|
|
* @anchor ti_drivers_Temperature_Synopsis
|
|
* # Synopsis #
|
|
* @anchor ti_drivers_Temperature_Synopsis_Code
|
|
* @code
|
|
* #include <ti/drivers/Temperature.h>
|
|
*
|
|
* #define WINDOW_DELTA 10
|
|
*
|
|
* Temperature_init();
|
|
*
|
|
* currentTemperature = Temperature_getTemperature();
|
|
*
|
|
* result = Temperature_registerNotifyRange(¬ifyObject,
|
|
* currentTemperature + WINDOW_DELTA,
|
|
* currentTemperature - WINDOW_DELTA,
|
|
* myNotifyFxn,
|
|
* clientArg);
|
|
* @endcode
|
|
*
|
|
* @anchor ti_drivers_Temperature_Examples
|
|
* # Examples #
|
|
*
|
|
* ## Register a High Threshold Notification #
|
|
*
|
|
* @code
|
|
*
|
|
* // The notification will trigger when the temperature reaches 40 C
|
|
* #define THRESHOLD_CUTOFF 40
|
|
*
|
|
* #include <ti/drivers/Temperature.h>
|
|
*
|
|
* void thresholdNotifyFxn(int16_t currentTemperature,
|
|
* int16_t thresholdTemperature,
|
|
* uintptr_t clientArg,
|
|
* Temperature_NotifyObj *notifyObject) {
|
|
* // Post a semaphore, set a flag, or otherwise act upon the temperature
|
|
* // change.
|
|
* }
|
|
*
|
|
* ...
|
|
*
|
|
* // Initialize the Temperature driver and register a notification.
|
|
*
|
|
* Temperature_init();
|
|
*
|
|
* int_fast16_t status = Temperature_registerNotifyHigh(notifyObject,
|
|
* THRESHOLD_CUTOFF,
|
|
* thresholdNotifyFxn,
|
|
* NULL);
|
|
*
|
|
* if (status != Temperature_STATUS_SUCCESS) {
|
|
* // Handle error
|
|
* }
|
|
*
|
|
* @endcode
|
|
*
|
|
* ## Register a Range Threshold Notification and Reregister in Callback #
|
|
*
|
|
* @code
|
|
*
|
|
* #define THRESHOLD_DELTA 5
|
|
*
|
|
* #include <ti/drivers/Temperature.h>
|
|
*
|
|
*
|
|
* void deltaNotificationFxn(int16_t currentTemperature,
|
|
* int16_t thresholdTemperature,
|
|
* uintptr_t clientArg,
|
|
* Temperature_NotifyObj *notifyObject) {
|
|
* int_fast16_t status;
|
|
*
|
|
* status = Temperature_registerNotifyRange(notifyObject,
|
|
* currentTemperature + THRESHOLD_DELTA,
|
|
* currentTemperature - THRESHOLD_DELTA,
|
|
* deltaNotificationFxn,
|
|
* NULL);
|
|
*
|
|
* if (status != Temperature_STATUS_SUCCESS) {
|
|
* while(1);
|
|
* }
|
|
* }
|
|
*
|
|
* ...
|
|
*
|
|
* // Initialize the Temperature driver and register a notification.
|
|
*
|
|
* Temperature_init();
|
|
*
|
|
* int16_t currentTemperature = Temperature_getTemperature();
|
|
*
|
|
* int_fast16_t status = Temperature_registerNotifyRange(notifyObject,
|
|
* currentTemperature + THRESHOLD_DELTA,
|
|
* currentTemperature - THRESHOLD_DELTA,
|
|
* deltaNotificationFxn,
|
|
* NULL);
|
|
* @endcode
|
|
*/
|
|
|
|
#ifndef ti_drivers_Temperature__include
|
|
#define ti_drivers_Temperature__include
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#include <ti/drivers/utils/List.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/*!
|
|
* Common Temperature status code reservation offset.
|
|
* Temperature driver implementations should offset status codes with
|
|
* Temperature_STATUS_RESERVED growing negatively.
|
|
*
|
|
* Example implementation specific status codes:
|
|
* @code
|
|
* #define TemperatureXYZ_STATUS_ERROR0 Temperature_STATUS_RESERVED - 0
|
|
* #define TemperatureXYZ_STATUS_ERROR1 Temperature_STATUS_RESERVED - 1
|
|
* #define TemperatureXYZ_STATUS_ERROR2 Temperature_STATUS_RESERVED - 2
|
|
* @endcode
|
|
*/
|
|
#define Temperature_STATUS_RESERVED (-32)
|
|
|
|
/*!
|
|
* @brief Successful status code.
|
|
*
|
|
* Functions return Temperature_STATUS_SUCCESS if the function was executed
|
|
* successfully.
|
|
*/
|
|
#define Temperature_STATUS_SUCCESS (0)
|
|
|
|
/*!
|
|
* @brief Generic error status code.
|
|
*
|
|
* Functions return Temperature_STATUS_ERROR if the function was not executed
|
|
* successfully.
|
|
*/
|
|
#define Temperature_STATUS_ERROR (-1)
|
|
|
|
|
|
/* @cond
|
|
*
|
|
* Type declaration for the notification object made separately from the
|
|
* struct definition because of the circular dependency between
|
|
* #Temperature_NotifyFxn() and #Temperature_NotifyObj.
|
|
*/
|
|
typedef struct Temperature_NotifyObj Temperature_NotifyObj;
|
|
/* @endcond */
|
|
|
|
/*!
|
|
* @brief Function prototype for a notification callback.
|
|
*
|
|
* @param [in] currentTemperature Current chip temperature
|
|
*
|
|
* @param [in] thresholdTemperature Temperature threshold that caused
|
|
* this notification callback.
|
|
*
|
|
* @param [in] clientArg Argument provided by the application
|
|
* during registration.
|
|
*
|
|
* @param [in/out] notifyObject The notification object that was
|
|
* registered previously. This pointer
|
|
* may be used to register the
|
|
* notification again with updated
|
|
* inputs from within the notification
|
|
* callback.
|
|
*/
|
|
typedef void (*Temperature_NotifyFxn) (int16_t currentTemperature,
|
|
int16_t thresholdTemperature,
|
|
uintptr_t clientArg,
|
|
Temperature_NotifyObj *notifyObject);
|
|
|
|
/*!
|
|
* @brief Temperature notify object structure.
|
|
*
|
|
* This structure specification is for internal use. Notification clients must
|
|
* pre-allocate a notify object when registering for a notification;
|
|
* #Temperature_registerNotifyHigh(), #Temperature_registerNotifyLow(),
|
|
* or #Temperature_registerNotifyRange() will take care initializing the
|
|
* internal elements appropriately.
|
|
*/
|
|
struct Temperature_NotifyObj {
|
|
List_Elem link; /*!< For placing on the notify list */
|
|
Temperature_NotifyFxn notifyFxn; /*!< Application callback function */
|
|
int16_t thresholdHigh; /*!< High threshold in degrees C */
|
|
int16_t thresholdLow; /*!< Low threshold in degrees C */
|
|
uintptr_t clientArg; /*!< Application provided arg */
|
|
bool isRegistered; /*!< Is the notification active */
|
|
};
|
|
|
|
|
|
/*!
|
|
* @brief This function initializes the Temperature driver.
|
|
*
|
|
* This function initializes the internal state of the Temperature driver.
|
|
* It must be called before calling any other Temperature functions. Calling
|
|
* this function multiple times will only have an effect the first time.
|
|
*/
|
|
void Temperature_init();
|
|
|
|
/*!
|
|
* @brief Gets the current temperature in degrees C.
|
|
*
|
|
* @return Current temperature in degrees C
|
|
*/
|
|
int16_t Temperature_getTemperature(void);
|
|
|
|
/*!
|
|
* @brief Registers a notification with a high threshold.
|
|
*
|
|
* This function registers a Temperature notification with a high threshold.
|
|
* Once the chip temperature rises above @c thresholdHigh, @c notifyFxn is
|
|
* called and the notification is automatically unregistered.
|
|
*
|
|
* @param notifyObject Structure to be initialized. After returning,
|
|
* it will contain the data necessary to issue a
|
|
* notification callback. The memory of the
|
|
* structure must persist while the notification
|
|
* is registered.
|
|
*
|
|
* @param [in] thresholdHigh Threshold temperature in degrees C
|
|
*
|
|
* @param [in] notifyFxn Callback function that is called once the
|
|
* chip temperature rises above
|
|
* @c thresholdHigh.
|
|
*
|
|
* @param [in] clientArg Application-specified argument
|
|
*
|
|
* @retval #Temperature_STATUS_SUCCESS The notification was successfully
|
|
* registered.
|
|
* @retval #Temperature_STATUS_ERROR There was an error during registration.
|
|
*
|
|
* @pre Temperature_init() called
|
|
*/
|
|
int_fast16_t Temperature_registerNotifyHigh(Temperature_NotifyObj *notifyObject,
|
|
int16_t thresholdHigh,
|
|
Temperature_NotifyFxn notifyFxn,
|
|
uintptr_t clientArg);
|
|
|
|
/*!
|
|
* @brief Registers a notification with a low threshold.
|
|
*
|
|
* This function registers a Temperature notification with a low threshold.
|
|
* Once the chip temperature falls below @c thresholdLow, @c notifyFxn is
|
|
* called and the notification is automatically unregistered.
|
|
*
|
|
* @param notifyObject Structure to be initialized. After returning,
|
|
* it will contain the data necessary to issue a
|
|
* notification callback. The memory of the
|
|
* structure must persist while the notification
|
|
* is registered.
|
|
*
|
|
* @param [in] thresholdLow Threshold temperature in degrees C
|
|
*
|
|
* @param [in] notifyFxn Callback function that is called once the
|
|
* chip temperature falls below
|
|
* @c thresholdLow.
|
|
*
|
|
* @param [in] clientArg Application-specified argument
|
|
*
|
|
* @retval #Temperature_STATUS_SUCCESS The notification was successfully
|
|
* registered.
|
|
* @retval #Temperature_STATUS_ERROR There was an error during registration.
|
|
*
|
|
* @pre Temperature_init() called
|
|
*/
|
|
int_fast16_t Temperature_registerNotifyLow(Temperature_NotifyObj *notifyObject,
|
|
int16_t thresholdLow,
|
|
Temperature_NotifyFxn notifyFxn,
|
|
uintptr_t clientArg);
|
|
|
|
/*!
|
|
* @brief Registers a notification with both a high and low threshold.
|
|
*
|
|
* This function registers a Temperature notification with a high and low
|
|
* threshold. Once the chip temperature rises above @c thresholdHigh or
|
|
* falls below @c thresholdLow, @c notifyFxn is called and the notification is
|
|
* automatically unregistered.
|
|
*
|
|
* @param notifyObject Structure to be initialized. After returning,
|
|
* it will contain the data necessary to issue a
|
|
* notification callback. The memory of the
|
|
* structure must persist while the notification
|
|
* is registered.
|
|
*
|
|
* @param [in] thresholdHigh High threshold temperature in degrees C
|
|
*
|
|
* @param [in] thresholdLow Low threshold temperature in degrees C
|
|
*
|
|
* @param [in] notifyFxn Callback function that is called once the
|
|
* chip temperature falls below
|
|
* @c thresholdLow, or rises above
|
|
* @c thresholdHigh.
|
|
*
|
|
* @param [in] clientArg Application-specified argument
|
|
*
|
|
* @retval #Temperature_STATUS_SUCCESS The notification was successfully
|
|
* registered
|
|
* @retval #Temperature_STATUS_ERROR There was an error during registration
|
|
*
|
|
* @pre Temperature_init() called
|
|
*/
|
|
int_fast16_t Temperature_registerNotifyRange(Temperature_NotifyObj *notifyObject,
|
|
int16_t thresholdHigh,
|
|
int16_t thresholdLow,
|
|
Temperature_NotifyFxn notifyFxn,
|
|
uintptr_t clientArg);
|
|
|
|
|
|
/*!
|
|
* @brief Unregisters a currently registered notification.
|
|
*
|
|
* This function unregisters a currently registered notification. It should not
|
|
* be called on a @c notifyObject that is not currently registered.
|
|
*
|
|
* @param notifyObject Notification to unregister.
|
|
*
|
|
* @retval #Temperature_STATUS_SUCCESS The notification was successfully
|
|
* unregistered.
|
|
* @retval #Temperature_STATUS_ERROR There was an error during
|
|
* unregistration.
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyHigh(),
|
|
* #Temperature_registerNotifyLow(), or #Temperature_registerNotifyRange()
|
|
*/
|
|
int_fast16_t Temperature_unregisterNotify(Temperature_NotifyObj *notifyObject);
|
|
|
|
/*!
|
|
* @brief Get the high threshold of a notification.
|
|
*
|
|
* This function should not be called on a @c notifyObject registered with
|
|
* #Temperature_registerNotifyLow(). The high threshold value returned in
|
|
* that case will be a device-specific invalid temperature.
|
|
*
|
|
* @param notifyObject Notification to get the high threshold of.
|
|
*
|
|
* @return High threshold in degrees C.
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyHigh(),
|
|
* or #Temperature_registerNotifyRange()
|
|
*/
|
|
int16_t Temperature_getThresholdHigh(Temperature_NotifyObj *notifyObject);
|
|
|
|
/*!
|
|
* @brief Get the low threshold of a notification.
|
|
*
|
|
* This function should not be called on a @c notifyObject registered with
|
|
* #Temperature_registerNotifyHigh(). The low threshold value returned in
|
|
* that case will be a device-specific invalid temperature.
|
|
*
|
|
* @param notifyObject Notification to get the low threshold of.
|
|
*
|
|
* @return Low threshold in degrees C.
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyLow(),
|
|
* or #Temperature_registerNotifyRange()
|
|
*/
|
|
int16_t Temperature_getThresholdLow(Temperature_NotifyObj *notifyObject);
|
|
|
|
/*!
|
|
* @brief Get the high and low threshold of a notification.
|
|
*
|
|
* This function should not be called on a @c notifyObject registered with
|
|
* #Temperature_registerNotifyLow() or #Temperature_registerNotifyHigh().
|
|
* The unconfigured threshold value returned in that case will be a
|
|
* device-specific invalid temperature.
|
|
*
|
|
* @param notifyObject Notification to get the high and low threshold of.
|
|
*
|
|
* @param [out] thresholdHigh High threshold value in degrees C written back
|
|
* by this function.
|
|
*
|
|
* @param [out] thresholdLow Low threshold value in degrees C written back
|
|
* by this function.
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyRange()
|
|
*/
|
|
void Temperature_getThresholdRange(Temperature_NotifyObj *notifyObject,
|
|
int16_t *thresholdHigh,
|
|
int16_t *thresholdLow);
|
|
|
|
/*!
|
|
* @brief Get the application-provided clientArg of a notification.
|
|
*
|
|
* @param notifyObject Notification to get the clientArg of.
|
|
*
|
|
* @return The clientArg provided during registration.
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyHigh(),
|
|
* #Temperature_registerNotifyLow(), or #Temperature_registerNotifyRange()
|
|
*/
|
|
uintptr_t Temperature_getClientArg(Temperature_NotifyObj *notifyObject);
|
|
|
|
/*!
|
|
* @brief Get the notifyFxn provided during registration.
|
|
*
|
|
* @param notifyObject Notification to get the notifyFxn of.
|
|
*
|
|
* @return The notifyFxn provided during registration
|
|
*
|
|
* @pre Register @c notifyObject with #Temperature_registerNotifyHigh(),
|
|
* #Temperature_registerNotifyLow(), or #Temperature_registerNotifyRange()
|
|
*/
|
|
Temperature_NotifyFxn Temperature_getNotifyFxn(Temperature_NotifyObj *notifyObject);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* ti_drivers_Temperature__include */
|