/*
* This file is subject to the terms of the GFX License. If a copy of
* the license was not distributed with this file, you can obtain one at:
*
* http://ugfx.io/license.html
*/
/**
* @file src/gdriver/gdriver.h
*
* @addtogroup GDRIVER
*
* @brief Module to support registering and unregistering of drivers
*
* @details GDRIVER provides a generalized way of defining and registering drivers.
*
* @note There are many different types of drivers and GDRIVER can handle any
* type of driver defined by the uGFX system.
*
* @note GDRIVER supports multiple drivers for one type of device. eg a SSD1289 LCD
* driver simultaneously with a framebuffer driver.
* @note GDRIVER supports multiple instances of a single driver. eg 2 SSD1289 LCD's.
* @note If there is only a single device of a particular type it will automatically
* register that device (it only needs to be included in the build, no special
* configuration is required)
* @note This module gdriver.h file is NOT included in the general gfx.h file.
* Instead it is included in each driver type's driver API.
*
* @pre GFX_USE_GDRIVER must be set to GFXON in your gfxconf.h
*
* @{
*/
#ifndef _GDRIVER_H
#define _GDRIVER_H
#if GFX_USE_GDRIVER || defined(__DOXYGEN__)
/*===========================================================================*/
/* Type definitions */
/*===========================================================================*/
#define GDRIVER_TYPE_DISPLAY 'g' // @< A graphics display
#define GDRIVER_TYPE_MOUSE 'm' // @< A mouse
#define GDRIVER_TYPE_TOUCH 'm' // @< A touch display (equivalent to a mouse)
#define GDRIVER_TYPE_TOGGLE 't' // @< A toggle device eg GPIO pins, switches etc
#define GDRIVER_TYPE_DIAL 'd' // @< A analog or digit dial (ranges in value from a minimum to a maximum)
#define GDRIVER_TYPE_KEYBOARD 'k' // @< A keyboard
#define GDRIVER_TYPE_BLOCK 'b' // @< A block device
#define GDRIVER_TYPE_STRING 's' // @< A device that returns strings of data
/**
* @brief All runtime driver structures start with this structure
*
* @note This structure (and any additional structure memory) is allocated
* dynamically by the system for each driver instance.
*/
typedef struct GDriver {
struct GDriver * driverchain;
const struct GDriverVMT * vmt;
} GDriver;
/**
* @brief All driver VMT's start with this structure.
*/
typedef struct GDriverVMT {
gU16 type; // @< What type of driver this is
gU16 flags; // @< Flags for the driver. Meaning is specific to each driver type.
gU32 objsize; // @< How big the runtime driver structure is
gBool (*init)(GDriver *driver, void *param, unsigned driverinstance, unsigned systeminstance); // @< Initialise the driver. Returns gTrue if OK.
// driverinstance is the instance 0..n of this driver.
// systeminstance is the instance 0..n of this type of device.
// The memory allocated is cleared before this call.
void (*postinit)(GDriver *driver); // @< Called once the driver is registered.
void (*deinit)(GDriver *driver); // @< De-initialise the driver
} GDriverVMT;
/**
* @brief A definition that allows getting addresses of GDriverVMT structures to put into a list.
* @note eg.
* const MyDriverVMTtype a[1] = {{...}};
* const MyDriverVMTtype b[1] = {{...}};
* ...
* \#define DRIVER_LIST a, b
* extern GDriverVMTList DRIVER_LIST; // Now treated as single element arrays of GDriverVMT
* const GDriverVMT const * mylist = { DRIVER_LIST };
*
*
* @note This could be one single typedef. However, some major compilers complain about duplicate const specifiers even though this is perfectly
* valid standard C. As this problem has become worse over time we opt for splitting this into two separate typedefs to prevent these
* compilers from throwing warnings.
* The single typedef would look like this:
*
* typedef const struct GDriverVMT const GDriverVMTList[1];
*
*/
typedef const struct GDriverVMT ConstGDriverVMT;
typedef ConstGDriverVMT const GDriverVMTList[1];
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Register a new driver instance.
* @return The runtime driver structure or NULL if it fails.
*
* @param[in] vmt The driver's vmt
* @param[in] param An arbitrary paramater passed to the driver init routine.
*/
GDriver *gdriverRegister(const GDriverVMT *vmt, void *param);
/**
* @brief UnRegister a driver instance.
*
* @param[in] driver The driver instance's runtime structure
*/
void gdriverUnRegister(GDriver *driver);
/**
* @brief Get the driver for a particular instance of a type of device
* @return The runtime driver structure or NULL if it fails.
*
* @param[in] type The type of driver to find
* @param[in] instance The instance (0..n) to find
*/
GDriver *gdriverGetInstance(gU16 type, unsigned instance);
/**
* @brief Get the count of instances of a type of device
* @return The instance count.
*
* @note Valid instance numbers are then 0 .. count-1
*
* @param[in] type The type of driver to find
*/
unsigned gdriverInstanceCount(gU16 type);
/**
* @brief Get the instance number for a device
* @return The instance number or (unsigned)-1 if it fails.
*
* @param[in] driver The driver to find the instance number for
*/
unsigned gdriverGetDriverInstanceNumber(GDriver *driver);
/**
* @brief Get the next driver for a type of device
* @return The runtime driver structure or NULL if there are no more.
*
* @param[in] type The type of driver to find
* @param[in] driver The last driver returned or NULL to start again
*/
GDriver *gdriverGetNext(gU16 type, GDriver *driver);
#ifdef __cplusplus
}
#endif
#endif /* GFX_USE_GDRIVER */
#endif /* _GDRIVER_H */
/** @} */