blob: 729f88548a6d97d45ffbdec78b411e10503bef37 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @file charge_control.h
* @brief Hardware-agnostic interface for battery charge control ICs
*
* The Charge Control interface provides a hardware-agnostic layer for driving
* battery charge controller ICs.
*/
#ifndef __CHARGE_CONTROL_H__
#define __CHARGE_CONTROL_H__
#include "os/mynewt.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Package init function. Remove when we have post-kernel init stages.
*/
void charge_control_pkg_init(void);
/* Forward declaration of charge_control structure. */
struct charge_control;
/* Comments above intentionally not in Doxygen format */
/* =================================================================
* ====================== DEFINES/MACROS ===========================
* =================================================================
*/
/**
* Charge control listener constants
*/
#define CHARGE_CONTROL_IGN_LISTENER 1
/**
* @{ Charge Control API
*/
/**
* Return the OS device structure corresponding to this charge controller
*/
#define CHARGE_CONTROL_GET_DEVICE(__c) ((__c)->cc_dev)
/**
* Return the interface for this charge controller
*/
#define CHARGE_CONTROL_GET_ITF(__c) (&((__c)->cc_itf))
// ---------------------- TYPE -------------------------------------
/**
* Charge controller supported functionality
*/
typedef enum {
/** No type, used for queries */
CHARGE_CONTROL_TYPE_NONE = (1 << 0),
/** Charging status reporting supported */
CHARGE_CONTROL_TYPE_STATUS = (1 << 1),
/** Fault reporting supported */
CHARGE_CONTROL_TYPE_FAULT = (1 << 2),
} charge_control_type_t;
/**
* Possible charge controller states
*/
typedef enum {
/** Charge controller is disabled (if enable/disable function exists) */
CHARGE_CONTROL_STATUS_DISABLED = 0,
/** No charge source is present at the charge controller input */
CHARGE_CONTROL_STATUS_NO_SOURCE,
/** Charge controller is charging a battery */
CHARGE_CONTROL_STATUS_CHARGING,
/** Charge controller has completed its charging cycle */
CHARGE_CONTROL_STATUS_CHARGE_COMPLETE,
/** Charging is temporarily suspended */
CHARGE_CONTROL_STATUS_SUSPEND,
/** Charge controller has detected a fault condition */
CHARGE_CONTROL_STATUS_FAULT,
/** Unspecified status; User must understand how to interpret */
CHARGE_CONTROL_STATUS_OTHER,
} charge_control_status_t;
/**
* Possible fault conditions for the charge controller
*/
typedef enum {
/** No fault detected */
CHARGE_CONTROL_FAULT_NONE = 0,
/** Charge controller input voltage exceeds threshold */
CHARGE_CONTROL_FAULT_OV = (1 << 0),
/** Charge controller input voltage below required operating level */
CHARGE_CONTROL_FAULT_UV = (1 << 1),
/** Charge controller is not running at its programmed charging current */
CHARGE_CONTROL_FAULT_ILIM = (1 << 2),
/** Charge controller detected an over-temperature condition */
CHARGE_CONTROL_FAULT_THERM = (1 << 3),
/** Unspecified fault; User must understand how to interpret */
CHARGE_CONTROL_FAULT_OTHER = (1 << 4),
} charge_control_fault_t;
/**
* Charge controller type traits list. Allows a certain type of charge control
* data to be polled at n times the normal poll rate.
*/
struct charge_control_type_traits {
/** The type of charge control data to which the traits apply */
charge_control_type_t cctt_charge_control_type;
/** Poll rate multiple */
uint16_t cctt_poll_n;
/** Polls left until the charge control type is polled */
uint16_t cctt_polls_left;
/** Next item in the traits list. The head of this list is contained
* within the charge control object
*/
SLIST_ENTRY(charge_control_type_traits) cctt_next;
};
// ---------------------- CONFIG -----------------------------------
/**
* Configuration structure, describing a specific charge controller type off of
* an existing charge controller.
*/
struct charge_control_cfg {
/** Reserved for future use */
uint8_t _reserved[4];
};
// ---------------------- INTERFACE --------------------------------
/**
* Charge control serial interface types
*/
enum charge_control_itf_type {
CHARGE_CONTROL_ITF_SPI = 0,
CHARGE_CONTROL_ITF_I2C = 1,
CHARGE_CONTROL_ITF_UART = 2,
};
/**
* Specifies a serial interface to use for communication with the charge
* controller (if applicable)
*/
struct charge_control_itf {
/* Charge control interface type */
enum charge_control_itf_type cci_type;
/* Charge control interface number (i.e. 0 for I2C0, 1 for I2C1) */
uint8_t cci_num;
/* Charge control CS pin (for SPI interface type) */
uint8_t cci_cs_pin;
/* Charge control interface address (for I2C interface type) */
uint16_t cci_addr;
/* OS lock for shared access */
struct os_mutex *cci_lock;
};
// ---------------------- LISTENER ---------------------------------
/**
* Callback for handling charge controller status.
*
* @param The charge control object for which data is being returned
* @param The argument provided to charge_control_read() function.
* @param A single charge control reading for that listener
* @param The type of charge control reading for the data function
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_data_func_t)(struct charge_control *, void *,
void *, charge_control_type_t);
/**
* Listener structure which may be registered to a charge controller. The
* listener will call the supplied charge_control_data_func_t every time it
* reads new data of the specified type.
*/
struct charge_control_listener {
/* The type of charge control data to listen for, this is interpreted as a
* mask, and this listener is called for all charge control types that
* match the mask.
*/
charge_control_type_t ccl_type;
/* Charge control data handler function, called when has data */
charge_control_data_func_t ccl_func;
/* Argument for the charge control listener */
void *ccl_arg;
/* Next item in the charge control listener list. The head of this list is
* contained within the charge control object.
*/
SLIST_ENTRY(charge_control_listener) ccl_next;
};
/* ---------------------- DRIVER FUNCTIONS ------------------------- */
/**
* Read from a charge controller, given a specific type of information to read
* (e.g. CHARGE_CONTROL_TYPE_STATUS).
*
* @param The charge controller to read from
* @param The type(s) of charge control value(s) to read, interpreted as a mask
* @param The function to call with each value read. If NULL, it calls all
* charge control listeners associated with this function.
* @param The argument to pass to the read callback.
* @param Timeout. If block until result, specify OS_TIMEOUT_NEVER, 0 returns
* immediately (no wait.)
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_read_func_t)(struct charge_control *,
charge_control_type_t, charge_control_data_func_t, void *, uint32_t);
/**
* Get the configuration of the charge controller. This includes the value
* type of the charge controller.
*
* @param The desired charge controller
* @param The type of charge control value to get configuration for
* @param A pointer to the charge control value to place the returned result
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_get_config_func_t)(struct charge_control *,
charge_control_type_t, struct charge_control_cfg *);
/**
* Reconfigure the settings of a charge controller.
*
* @param ptr to the charge controller-specific stucture
* @param ptr to the charge controller-specific configuration structure
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_set_config_func_t)(struct charge_control *,
void *);
/**
* Read the status of a charge controller.
*
* @param ptr to the charge controller-specific structure
* @param ptr to the location where the charge control status will be stored
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_get_status_func_t)(struct charge_control *, int *);
/**
* Read the fault status of a charge controller.
*
* @param ptr to the charge controller-specific structure
* @param ptr to the location where the fault status will be stored
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_get_fault_func_t)(struct charge_control *,
charge_control_fault_t *);
/**
* Enable a charge controller
*
* @param The charge controller to enable
*
* @return 0 on success, non-zero error code on failure.
*/
typedef int (*charge_control_enable_func_t)(struct charge_control *);
/**
* Disable a charge controller
*
* @param The charge controller to disable
*
* @return 0 on success, non-zero error code on failure
*/
typedef int (*charge_control_disable_func_t)(struct charge_control *);
/**
* Pointers to charge controller-specific driver functions.
*/
struct charge_control_driver {
charge_control_read_func_t ccd_read;
charge_control_get_config_func_t ccd_get_config;
charge_control_set_config_func_t ccd_set_config;
charge_control_get_status_func_t ccd_get_status;
charge_control_get_fault_func_t ccd_get_fault;
charge_control_enable_func_t ccd_enable;
charge_control_disable_func_t ccd_disable;
};
// ---------------------- POLL RATE CONTROL ------------------------
struct charge_control_timestamp {
struct os_timeval cct_ostv;
struct os_timezone cct_ostz;
uint32_t cct_cputime;
};
// ---------------------- CHARGE CONTROL OBJECT --------------------
struct charge_control {
/* The OS device this charge controller inherits from, this is typically a
* charge controller specific driver.
*/
struct os_dev *cc_dev;
/* The lock for this charge controller object */
struct os_mutex cc_lock;
/* A bit mask describing information types available from this charge
* controller. If the bit corresponding to the charge_control_type_t is
* set, then this charge controller supports that type of information.
*/
charge_control_type_t cc_types;
/* Charge control information type mask. A driver for a charge controller
* or an implementation of the controller may be written to support some or
* all of the types of information */
charge_control_type_t cc_mask;
/**
* Poll rate in MS for this charge controller.
*/
uint32_t cc_poll_rate;
/* The next time at which we will poll data from this charge controller */
os_time_t cc_next_run;
/* Charge controller driver specific functions, created by the device
* registering the charge controller.
*/
struct charge_control_driver *cc_funcs;
/* Charge controller last reading timestamp */
struct charge_control_timestamp cc_sts;
/* Charge controller interface structure */
struct charge_control_itf cc_itf;
/* A list of listeners that are registered to receive data from this
* charge controller
*/
SLIST_HEAD(, charge_control_listener) cc_listener_list;
/** A list of traits registered to the charge control data types */
SLIST_HEAD(, charge_control_type_traits) cc_type_traits_list;
/* The next charge controller in the global charge controller list. */
SLIST_ENTRY(charge_control) cc_next;
};
/* =================================================================
* ====================== CHARGE CONTROL ===========================
* =================================================================
*/
/**
* Initialize charge control structure data and mutex and associate it with an
* os_dev.
*
* @param Charge control struct to initialize
* @param os_dev to associate with the charge control struct
*
* @return 0 on success, non-zero error code on failure.
*/
int charge_control_init(struct charge_control *, struct os_dev *);
/**
* Register a charge control listener. This allows a calling application to
* receive callbacks for data from a given charge control object.
*
* For more information on the type of callbacks available, see the documentation
* for the charge control listener structure.
*
* @param The charge controller to register a listener on
* @param The listener to register onto the charge controller
*
* @return 0 on success, non-zero error code on failure.
*/
int charge_control_register_listener(struct charge_control *,
struct charge_control_listener *);
/**
* Un-register a charge control listener. This allows a calling application to
* unset callbacks for a given charge control object.
*
* @param The charge control object
* @param The listener to remove from the charge control listener list
*
* @return 0 on success, non-zero error code on failure.
*/
int charge_control_unregister_listener(struct charge_control *,
struct charge_control_listener *);
/**
* Read from a charge controller, given a specific type of information to read
* (e.g. CHARGE_CONTROL_TYPE_STATUS).
*
* @param The charge controller to read from
* @param The type(s) of charge control value(s) to read, interpreted as a mask
* @param The function to call with each value read. If NULL, it calls all
* charge control listeners associated with this function.
* @param The argument to pass to the read callback.
* @param Timeout. If block until result, specify OS_TIMEOUT_NEVER, 0 returns
* immediately (no wait.)
*
* @return 0 on success, non-zero error code on failure.
*/
int charge_control_read(struct charge_control *, charge_control_type_t,
charge_control_data_func_t, void *, uint32_t);
/**
* Set the charge controller poll rate
*
* @param The name of the charge controller
* @param The poll rate in milli seconds
*/
int
charge_control_set_poll_rate_ms(char *, uint32_t);
/**
* Set a charge control type to poll at some multiple of the poll rate
*
* @param The name of the charge controller
* @param The charge control type
* @param The multiple of the poll rate
*/
int
charge_control_set_n_poll_rate(char *, struct charge_control_type_traits *);
/**
* Set the driver functions for this charge controller, along with the type of
* data available for the given charge controller.
*
* @param The charge controller to set the driver information for
* @param The types of charge control data available
* @param The driver functions for this charge controller
*
* @return 0 on success, non-zero error code on failure
*/
static inline int
charge_control_set_driver(struct charge_control *cc, charge_control_type_t type,
struct charge_control_driver *driver)
{
cc->cc_funcs = driver;
cc->cc_types = type;
return (0);
}
/**
* Set the charge control driver mask so that the developer who configures the
* charge controller tells the charge control framework which data types to
* send back to the user
*
* @param The charge controller to set the mask for
* @param The mask
*/
static inline int
charge_control_set_type_mask(struct charge_control *cc,
charge_control_type_t mask)
{
cc->cc_mask = mask;
return (0);
}
/**
* Check if the given type is supported by the charge control device
*
* @param charge control object
* @param Type to be checked
*
* @return type bitfield, if supported, 0 if not supported
*/
static inline charge_control_type_t
charge_control_check_type(struct charge_control *cc,
charge_control_type_t type)
{
return (cc->cc_types & cc->cc_mask & type);
}
/**
* Set interface type and number
*
* @param The charge control object to set the interface for
* @param The interface type to set
* @param The interface number to set
*/
static inline int
charge_control_set_interface(struct charge_control *cc,
struct charge_control_itf *itf)
{
cc->cc_itf.cci_type = itf->cci_type;
cc->cc_itf.cci_num = itf->cci_num;
cc->cc_itf.cci_cs_pin = itf->cci_cs_pin;
cc->cc_itf.cci_addr = itf->cci_addr;
cc->cc_itf.cci_lock = itf->cci_lock;
return (0);
}
/**
* Read the configuration for the charge control type "type," and return the
* configuration into "cfg."
*
* @param The charge control to read configuration for
* @param The type of charge control configuration to read
* @param The configuration structure to point to.
*
* @return 0 on success, non-zero error code on failure.
*/
static inline int
charge_control_get_config(struct charge_control *cc,
charge_control_type_t type, struct charge_control_cfg *cfg)
{
return (cc->cc_funcs->ccd_get_config(cc, type, cfg));
}
// =================================================================
// ====================== CHARGE CONTROL MANAGER ===================
// =================================================================
/**
* @{ Charge Control Manager API
*/
/**
* Registers a charge controller with the charge control manager list. This
* makes the charge controller externally searchable.
*
* @param The charge controller to register
*
* @return 0 on success, non-zero error code on failure.
*/
int charge_control_mgr_register(struct charge_control *);
/**
* Return the charge control event queue.
*/
struct os_eventq *charge_control_mgr_evq_get(void);
typedef int (*charge_control_mgr_compare_func_t)(struct charge_control *,
void *);
/**
* The charge control manager contains a list of charge controllers, this
* function returns the next charge controller in that list, for which
* compare_func() returns successful (one). If prev_cursor is provided, the
* function starts at that point in the charge controller list.
*
* @warn This function MUST be locked by charge_control_mgr_lock/unlock() if
* the goal is to iterate through charge controllers (as opposed to just
* finding one.) As the "prev_cursor" may be resorted in the charge control
* list, in between calls.
*
* @param The comparison function to use against charge controllers in the list.
* @param The argument to provide to that comparison function
* @param The previous charge controller in the manager list, in case of
* iteration. If desire is to find first matching charge controller,
* provide a NULL value.
*
* @return A pointer to the first charge controller found from prev_cursor, or
* NULL, if none found.
*
*/
struct charge_control *charge_control_mgr_find_next(
charge_control_mgr_compare_func_t, void *, struct charge_control *);
/**
* Find the "next" charge controller available for a giventype.
*
* If the charge control parameter is present find the next entry from that
* parameter. Otherwise, return the first match.
*
* @param The type of charge controller to search for
* @param The cursor to search from, or NULL to start from the beginning.
*
* @return A pointer to the charge control object matching that type, or NULL if
* none found.
*/
struct charge_control *charge_control_mgr_find_next_bytype(
charge_control_type_t, struct charge_control *);
/**
* Search the charge control list and find the next charge controller that
* corresponds to a given device name.
*
* @param The device name to search for
* @param The previous charge controller found with this device name
*
* @return 0 on success, non-zero error code on failure
*/
struct charge_control *charge_control_mgr_find_next_bydevname(char *,
struct charge_control *);
/**
* Check if charge control type matches
*
* @param The charge control object
* @param The type to check
*
* @return 1 if matches, 0 if it doesn't match.
*/
int charge_control_mgr_match_bytype(struct charge_control *, void *);
/**
* Puts read event on the charge control manager evq
*
* @param arg
*/
void
charge_control_mgr_put_read_evt(void *);
#if MYNEWT_VAL(CHARGE_CONTROL_CLI)
char*
charge_control_ftostr(float, char *, int);
#endif
/**
* }@
*/
/* End Charge Control Manager API */
/**
* @}
*/
/* End Charge Control API */
#ifdef __cplusplus
}
#endif
#endif /* __CHARGE_CONTROL_H__ */