text: /*
   * Amazon FreeRTOS Common IO V0.1.0
   * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy of
   * this software and associated documentation files (the "Software"), to deal in
   * the Software without restriction, including without limitation the rights to
   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
   * the Software, and to permit persons to whom the Software is furnished to do so,
   * subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
   * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
   * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   *
   * http://aws.amazon.com/freertos
   * http://www.FreeRTOS.org
   */
  
  /*******************************************************************************
   * @file iot_battery.h
   *
   * @brief HAL APIs for Battery
   *******************************************************************************
   */
  
  /**
   * @file    iot_battery.h
   * @brief   This file contains all the Battery HAL API definitions. The APIs defined in this file
   *          helps with battery information and charging related functions.
   */
  
  #ifndef _IOT_BATTERY_H_
  #define _IOT_BATTERY_H_
  
  /**
   * @defgroup iot_battery BATTERY HAL APIs
   * @{
   */
  
  /**
   * @brief Return values used by BATTERY driver
   */
  #define IOT_BATTERY_SUCCESS                   ( 0 )  /*!< Battery operation completed successfully. */
  #define IOT_BATTERY_INVALID_VALUE             ( 1 )  /*!< At least one parameter is invalid. */
  #define IOT_BATTERY_NOT_EXIST                 ( 2 )  /*!< No battery exists in this hardware. */
  #define IOT_BATTERY_READ_FAILED               ( 3 )  /*!< Battery read operation failed. */
  #define IOT_BATTERY_FUNCTION_NOT_SUPPORTED    ( 4 )  /*!< Battery operation not supported. */
  
  /**
   * @brief Battery Type
   */
  typedef enum
  {
      eBatteryChargeable,   /*!< Re-chargeable batteries with charging enabled */
      eBatteryNotChargeable /*!< Not chargeable batteries */
  } IotBatteryType_t;
  
  /**
   * @brief Charger type
   */
  typedef enum
  {
      eBatteryChargeNone,        /*!< No Charge source, or non-chargeable battery */
      eBatteryChargeUSB,         /*!< USB battery source */
      eBatteryChargePowerSupply, /*!< AC power supply source */
      erBatteryChargeWireless,   /*!< Wireless charging source */
  } IotBatteryChargeSource_t;
  
  /**
   * @brief Battery status
   */
  typedef enum
  {
      eBatteryCharging,          /*!< Battery is Charging. Applicable only if the battery is chargeable */
      eBatteryDischarging,       /*!< Battery is Discharging. This is the normal status of battery is no charger
                                  *  is connected */
      eBatteryNotCharging,       /*!< Battery is not charging. This is set when charger is connected, but battery is not
                                  *  charging - usually an error condition */
      eBatteryChargeFull,        /*!< Battery is fully charged. This status will be set only when the charger is connected
                                  *  and battery is fully charged */
      eBatteryChargeLow,         /*!< Battery is low on charging and no charger connected. This status is set when battery
                                  *  is discharging and reaches a low cahrge value. Low charge value is defined by implementation */
      eBatteryOverVoltage,       /*!< Battery maximum voltage limit reached. */
      eBatteryUnderVoltage,      /*!< Battery low voltage limit reached. */
      eBatteryOverTemp,          /*!< Battery maximum temperature limit reached. */
      eBatteryUnderTemp,         /*!< Battery minimum temperature limit reached. */
      eBatteryOverChargingTemp,  /*!< Battery maximum charging temperature limit reached. */
      eBatteryUnderhargingTemp,  /*!< Battery minimum charging temperature limit reached. */
      eBatteryChargeTimeExpired, /*!< Battery charge timer expired. Charge timer can be set if the underlying hardware supports it using
                                  * eSetBatteryChargeTimer IOCTL, and once the chargeTimer expires registered callback is called with this status set */
      eBatteryUnknown            /*!< Unknown status. Default status if no battery is present */
  } IotBatteryStatus_t;
  
  /**
   * @brief Battery information.
   */
  typedef struct IotBatteryInfo
  {
      IotBatteryType_t xBatteryType; /*!< Battery type. chargeable or non-chargeable */
      uint16_t usMinVoltage;         /*!< minimum designed voltage battery can be used at */
      uint16_t usMaxVoltage;         /*!< maximum designed voltage battery can be used at */
      int16_t sMinTemperature;       /*!< lowest temperature the battery can be used at by design */
      int16_t sMaxTemperature;       /*!< max temperature the battery can be used at by design */
      uint8_t usMaxCapacity;         /*!< max capacity of battery by design */
      uint8_t ucAsyncSupported;      /*!< Is asynchronous notifications supported by the driver. This will be
                                      *  set, if the battery/charging has an IC/battery and charging hw module that
                                      *  can atonomously monitor battery characterstics and generate interrupts */
  } IotBatteryInfo_t;
  
  /**
   * @brief Ioctl request types.
   */
  typedef enum IotBatteryIoctlRequest
  {
      eSetBatteryMinVoltageThreshold,     /*!< Set the battery minimum voltage threshold. When the voltage goes below this threshold
                                           *   value, the registered callback will be called with the status set to "eBatteryUnderVoltage".
                                           *   If battery management HW does not have a way to monitor voltage, this IOCTL will not be supported.
                                           *   Parameter is uint16_t value in milliVolt units. */
      eSetBatteryMaxVoltageThreshold,     /*!< Set the battery mimimum voltage threshold. When the voltage goes below this threshold
                                           *   value, the registered callback will be called with the status set to "eBatteryOverVoltage".
                                           *   If battery management HW does not have a way to monitor voltage, this IOCTL will not be supported.
                                           *   Parameter is uint16_t value in milliVolt units. */
      eSetBatteryMinBatteryTempThreshold, /*!< Set the minimum battery temperature threshold. When the battery temperature goes below this value,
                                           *   the registered callback will be called with the status value "eBatteryUnderTemp".
                                           *   This IOCTL takes int16_t value as input in milliCelcius units. */
      eSetBatteryMaxBatteryTempThreshold, /*!< Set the maximum battery temperature threshold. When the battery temperature goes above this value,
                                           *   the registered callback will be called with the status value "eBatteryUnderTemp".
                                           *   This IOCTL takes int16_t value as input in milliCelcius units. */
      eSetBatteryMinChargeTempThreshold,  /*!< Set the minimum charge temperature threshold. When the charging temperature goes below this value,
                                           *   the registered callback will be called with the status value "eBatteryUnderChargingTemp".
                                           *   This IOCTL takes int16_t value as input in milliCelcius units.*/
      eSetBatteryMaxChargeTempThreshold,  /*!< Set the maximum charge temperature threshold. When the charging temperature goes above this value,
                                           *   the registered callback will be called with the status value "eBatteryOverChargingTemp".
                                           *   This IOCTL takes int16_t value as input in milliCelcius units. */
      eSetBatteryMaxOutputCurrent,        /*!< Set the maximum output current limit from the battery.
                                           *   This IOCTL takes uint16_t value as input in milliAmp units. */
      eSetBatteryMaxInputChargeCurrent,   /*!< Set the maximum input charging current limit to the battery.
                                           *   This IOCTL takes uint16_t value as input in milliAmp units. */
      eSetBatteryChargeTimer,             /*!< Set the battery charging timer limit. AFter the timer expires charging will stop.
                                           *   This IOCTL takes uint16_t value as input in milliSec units. */
      eGetBatteryMinVoltageThreshold,     /*!< Get the battery minimum thresold.
                                           *   This IOCTL returns uint16_t value in milliVolt units. */
      eGetBatteryMaxVoltageThreshold,     /*!< Get the battery maximum thresold.
                                           *   This IOCTL returns uint16_t value in milliVolt units. */
      eGetBatteryOCV,                     /*!< Get the battery OCV (open circuit voltage)
                                           *   This IOCTL returns uint16_t value in milliVolt units. */
      eGetBatteryBootVoltage,             /*!< Get the battery boot-up voltage
                                           *   This IOCTL returns uint16_t value in milliVolt units. */
      eGetBatteryMinBatteryTempThreshold, /*!< Get the minimum battery temperature thresholde
                                           *   This IOCTL returns int16_t value in milliCelcius units. */
      eGetBatteryMaxBatteryTempThreshold, /*!< Get the maximum battery temperature threshold.
                                           *   This IOCTL returns int16_t value in milliCelcius units. */
      eGetBatteryMinChargeTempThreshold,  /*!< Get the minimum charging temperature threshold.
                                           *   This IOCTL returns int16_t value in milliCelcius units. */
      eGetBatteryMaxChargeTempThreshold,  /*!< Get the maximum charging temperature threshold.
                                           *   This IOCTL returns int16_t value in milliCelcius units. */
      eGetBatteryMaxOutputCurrent,        /*!< Get the battery output current limit.
                                           *   This IOCTL returns uint16_t value in milliAmp units. */
      eGetBatteryMaxInputChargeCurrent,   /*!< Get the battery input charge current limit.
                                           *   This IOCTL returns uint16_t value in milliAmp units. */
      eGetBatteryChargeTimer,             /*!< Get the current battery charge time limit.
                                           *   This IOCTL returns uint16_t value in milliSec units. */
      eGetBatteryChargeSource,            /*!< Get the current battery charge source.
                                           *   This IOCTL returns a IotBatteryChargeSource_t as it's parameter. */
      eGetBatteryStatus                   /*!< Get the battery status. Returns one of the IotBatteryStatus_t values as it's parameter. */
  } IotBatteryIoctlRequest_t;
  
  /**
   * @brief   Battery descriptor type defined in the source file.
   */
  struct  IotBatteryDescriptor_t;
  
  /**
   * @brief   IotBatteryHandle_t type is the Battery handle returned by calling iot_battery_open()
   *          this is initialized in open and returned to caller. Caller must pass this pointer
   *          to the rest of the APIs.
   */
  typedef struct IotBatteryDescriptor_t * IotBatteryHandle_t;
  
  /**
   * @brief   Battery notification callback type. This callback is passed
   *          to the driver by using iot_battery_set_callback API. The callback is
   *          used to get the notifications about battery status changes for ex: when charging starts, or
   *          when critical threshold is reached or when battery is full etc...
   *          The callback is only used if the driver supports the asynchronous notifications. The caller
   *          must get the batteryInfo to find if the asynchronous notifications are supported.
   *          On simiple underlying batteries, the caller/application must manage the battery conditions by
   *          periodically probing the battery using read APIs, and for sophisticated battery management service
   *          modules, these can be managed in the HW hence asyncrhonous notifications can be sent (using registered callback)
   *
   * @param[in] xStatus       battery status from IotBatteryStatus_t
   * @param[in] pvUserContext User Context passed when setting the callback.
   *                          This is not used by the driver, but just passed back to the user
   *                          in the callback.
   */
  typedef void ( * IotBatteryCallback_t)( IotBatteryStatus_t xStatus,
                                          void * pvUserContext );
  
  /**
   * @brief   iot_battery_open is used to initialize the Battery and Charging driver.
   *
   * @param[in]   lBatteryInstance   The instance of the battery interface to initialize.
   *                                  Usually, there is only one battery interface.
   *
   * @return
   * - handle to the Battery controller on success
   * - NULL, if
   *    - invalid instance
   *    - open same instance more than once before closing it.
   *    - on failure.
   */
  IotBatteryHandle_t iot_battery_open( int32_t lBatteryInstance );
  
  /*!
   * @brief   iot_battery_set_callback is used to set the callback to be called when a notification
   *          needs to be sent to the caller. THe callback is only called if the battery supports async
   *          notifications. Caller must check isAsyncNotificationSupported value before registering
   *          for callbacks, if async is not supported, registering for callback has no affect, and the callback
   *          will never be called.
   *
   * @note Single callback is used for all features that support callback
   *   - eBatteryChargeTimeExpired,
   *   - eSetBatteryMinVoltageThreshold, eSetBatteryMaxVoltageThreshold,
   *   - eSetBatteryMinBatteryTempThreshold, eSetBatteryMaxBatteryTempThreshold,
   *   - eSetBatteryMinChargeTempThreshold, eSetBatteryMaxChargeTempThreshold,
   * @note Newly set callback overrides the one previously set
   * @note This callback is per handle. Each instance has its own callback.
   *
   * @warning If input handle or if callback function is NULL, this function silently takes no action.
   *
   * @param[in]   pxBatteryHandle  handle to Battery driver returned in
   *                          iot_battery_open()
   * @param[in]   xCallback   callback function to be called.
   * @param[in]   pvUserContext   user context to be passed when callback is called.
   *
   */
  void iot_battery_set_callback( IotBatteryHandle_t const pxBatteryHandle,
                                 IotBatteryCallback_t xCallback,
                                 void * pvUserContext );
  
  /*!
   * @brief   iot_battery_getInfo is used to get the battery info
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   *
   * @return
   * - returns a pointer to the IotBatteryInfo structure on success
   * - NULL on error
   */
  IotBatteryInfo_t * iot_battery_getInfo( IotBatteryHandle_t const pxBatteryHandle );
  
  /*!
   * @brief   iot_battery_current is used to get the battery current in mA.
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  pusCurrent   battery current value.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL or pusCurrent == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery present.
   * - IOT_BATTERY_READ_FAILED on error obtaining valid reading
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_current( IotBatteryHandle_t const pxBatteryHandle,
                               uint16_t * pusCurrent );
  
  /*!
   * @brief   iot_battery_voltage is used to get the battery voltage in milli-volts.
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  pusVoltage  battery voltage value.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL  or pusVoltage == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_READ_FAILED on error
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_voltage( IotBatteryHandle_t const pxBatteryHandle,
                               uint16_t * pusVoltage );
  
  /*!
   * @brief   iot_battery_chargeLevel is used to get the battery charging level in percentage (from 1 to 100).
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  pucChargeLevel battery charging value.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL or pusChargeLevel == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_READ_FAILED on error
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_chargeLevel( IotBatteryHandle_t const pxBatteryHandle,
                                   uint8_t * pucChargeLevel );
  
  
  /*!
   * @brief   iot_battery_capacity is used to get the current battery capacity value in mAh
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  pusCapacity  battery capacity value.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL or pusCapacity == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_READ_FAILED on error
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_capacity( IotBatteryHandle_t const pxBatteryHandle,
                                uint16_t * pusCapacity );
  
  /*!
   * @brief   iot_battery_temp is used to get the battery temperature in milliCelcius
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  psTemp   battery temperature in milliCelcius
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL or psTemp == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_READ_FAILED on error
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_temp( IotBatteryHandle_t const pxBatteryHandle,
                            int16_t * psTemp );
  
  /*!
   * @brief   iot_battery_enable_charging is used to enable battery charging if charging is supported.
   *          if battery is already at full charge, enable will not charge battery until the charging level
   *          drops below 100, and even if battery is at critical level, and charging is not enabled, battery will
   *          not be charging. Charging is always enabled by default unless disabled by using this API.
   *
   * @param[in]  pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[in]  pucEnable   Enable or Disable the charging of battery. set to 1 to enable, or 0 to disable.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if NULL handle or NULL voltage pointer
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_enable_charging( IotBatteryHandle_t const pxBatteryHandle,
                                       uint8_t * pucEnable );
  
  /*!
   * @brief   iot_battery_is_charging is used to query if the battery is currently charging.
   *
   * @param[in]   pxBatteryHandle handle to Battery driver returned in
   *                              iot_battery_open()
   * @param[out]  pucCharging   If charging this will contain value of 1 otherwise 0.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if pxBatteryHandle == NULL or pusCharging == NULL
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED if its not supported by the hardware.
   */
  int32_t iot_battery_is_charging( IotBatteryHandle_t const pxBatteryHandle,
                                   uint8_t * pucCharging );
  
  /**
   * @brief   iot_battery_ioctl is used to set Battery configuration and
   *          Battery properties like battery threshold,  temperature threshold, charging max, chargin min etc..
   *
   * @param[in]   pxBatteryHandle  handle to Battery driver returned in
   *                          iot_battery_open()
   * @param[in]   xRequest    configuration request of type IotBatteryIoctlRequest_t
   * @param[in,out] pvBuffer  buffer holding Battery set and get values.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if
   *    - pxBatteryHandle == NULL
   *    - invalid xRequest
   *    - pvBuffer == NULL when required
   * - IOT_BATTERY_NOT_EXIST if no battery in this hardware
   * - IOT_BATTERY_FUNCTION_NOT_SUPPORTED valid for any ioctl if its not supported by the hardware.
   */
  int32_t iot_battery_ioctl( IotBatteryHandle_t const pxBatteryHandle,
                             IotBatteryIoctlRequest_t xRequest,
                             void * const pvBuffer );
  
  /**
   * @brief   iot_battery_close is used to de-Initialize Battery driver.
   *
   * @param[in]   pxBatteryHandle  handle to Battery interface.
   *
   * @return
   * - IOT_BATTERY_SUCCESS on success
   * - IOT_BATTERY_INVALID_VALUE if
   *    - pxBatteryHandle == NULL
   *    - if is not in open state (already closed).
   */
  int32_t iot_battery_close( IotBatteryHandle_t const pxBatteryHandle );
  
  /**
   * @}
   */
  
  #endif /* ifndef _IOT_BATTERY_H_ */
  