diff --git a/src/gdriver/gdriver_gdriver.c b/src/gdriver/gdriver_gdriver.c new file mode 100644 index 00000000..a6eb3e98 --- /dev/null +++ b/src/gdriver/gdriver_gdriver.c @@ -0,0 +1,137 @@ +/* + * 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.org/license.html + */ + +#include "gfx.h" + +#if GFX_NEED_GDRIVER + +// Some HACKS as these aren't supported yet +#ifndef GINPUT_NEED_STRING + #define GINPUT_NEED_STRING FALSE +#endif +#ifndef GFX_USE_GBLOCK + #define GFX_USE_GBLOCK FALSE +#endif + +// Define the tables to hold the driver instances. +static GDriver *dhead; + +// The system initialization. +void _gdriverInit(void) { + const GDriverAutoStart const *pa; + int cnt; + + #if GFX_USE_GDISP + #ifdef GDISP_DRIVER_LIST + { + static const struct { + const struct GDISPVMT const * vmt; + int instances; + } drivers[] = {GDISP_DRIVER_LIST}; + + for(pa = drivers; pa < &drivers[sizeof(drivers)/sizeof(drivers[0])]) { + for(cnt = pa->instances; cnt; cnt--) + gdriverRegister(pa->vmt); + } + } + #else + extern struct GDISPVMT GDISP_VMT; + gdriverRegister((GDriver *)&GDISP_VMT); + #endif + #endif +} + + +GDriver *gdriverRegister(const GDriverVMT *vmt) { + GDriver *pd; + GDriver *dtail; + int dinstance, sinstance; + + // Loop to find the driver instance and the system instance numbers + dinstance = sinstance = 0; + for(pd = dhead; pd; dtail = pd, pd = pd->driverchain) { + if (pd->vmt == vmt) + dinstance++; + if (pd->vmt->type == vmt->type) + sinstance++; + } + + // Get a new driver instance of the correct size and initialize it + pd = gfxAlloc(vmt->objsize); + if (!pd) + return 0; + pd->driverchain = 0; + pd->vmt = vmt; + if (vmt->init && !vmt->init(pd, dinstance, sinstance)) { + gfxFree(pd); + return 0; + } + + // Add it to the driver chain + if (dhead) + dtail->driverchain = pd; + else + dhead = pd; +} + +void gdriverUnRegister(GDriver *driver) { + GDriver *pd; + + // Safety + if (!driver) + return; + + // Remove it from the list of drivers + if (dhead == driver) + dhead = driver->driverchain; + else { + for(pd = dhead; pd->driverchain; pd = pd->driverchain) { + if (pd->driverchain == driver) { + pd->driverchain = driver->driverchain; + break; + } + } + } + + // Call the deinit() + if (driver->vmt->deinit) + driver->vmt->dinit(driver); + + // Cleanup + gfxFree(driver); +} + +GDriver *gdriverGetInstance(uint16_t type, int instance) { + GDriver *pd; + int sinstance; + + // Loop to find the system instance + sinstance = 0; + for(pd = dhead; pd; pd = pd->driverchain) { + if (pd->vmt->type == type) { + if (sinstance == instance) + return pd; + sinstance++; + } + } + return 0; +} + +int gdriverInstanceCount(uint16_t type) { + GDriver *pd; + int sinstance; + + // Loop to count the system instances + sinstance = 0; + for(pd = dhead; pd; pd = pd->driverchain) { + if (pd->vmt->type == type) + sinstance++; + } + return sinstance; +} + +#endif /* GFX_NEED_GDRIVER */ diff --git a/src/gdriver/sys_defs.h b/src/gdriver/sys_defs.h new file mode 100644 index 00000000..3392f73a --- /dev/null +++ b/src/gdriver/sys_defs.h @@ -0,0 +1,126 @@ +/* + * 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.org/license.html + */ + +/** + * @file src/gdriver/sys_defs.h + * + * @addtogroup GINPUT + * + * @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 sys_defs.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 TRUE in your gfxconf.h + * + * @{ + */ + +#ifndef _GDRIVER_H +#define _GDRIVER_H + +#if GFX_NEED_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 { + GDriver * driverchain; + const struct GDriverVMT * vmt; +} GDriver; + +/** + * @brief All driver VMT's start with this structure. + */ +typedef struct GDriverVMT { + uint16_t type; // @< What type of driver this is + uint16_t flags; // @< Flags for the driver. Meaning is specific to each driver type. + uint32_t objsize; // @< How big the runtime driver structure is + bool_t (*init)(void *driver, int driverinstance, int systeminstance); // @< Initialise the driver. + // driverinstance is the instance 0..n of this driver. + // systeminstance is the instance 0..n of this type of device. + void (*deinit)(void *driver); // @< De-initialise the driver +} GDriverVMT; + +/*===========================================================================*/ +/* 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 + */ + GDriver *gdriverRegister(const GDriverVMT *vmt); + + /** + * @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(uint16_t type, int 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 + */ + int gdriverInstanceCount(uint16_t type); + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_NEED_GDRIVER */ + +#endif /* _GDRIVER_H */ +/** @} */ + diff --git a/src/gdriver/sys_make.mk b/src/gdriver/sys_make.mk new file mode 100644 index 00000000..93810aa9 --- /dev/null +++ b/src/gdriver/sys_make.mk @@ -0,0 +1 @@ +GFXSRC += $(GFXLIB)/src/gdriver/gdriver_gdriver.c diff --git a/src/gdriver/sys_options.h b/src/gdriver/sys_options.h new file mode 100644 index 00000000..bef0a95a --- /dev/null +++ b/src/gdriver/sys_options.h @@ -0,0 +1,32 @@ +/* + * 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.org/license.html + */ + +/** + * @file src/gdriver/sys_options.h + * @brief GDRIVER - Driver options header file. + * + * @addtogroup GDRIVER + * @{ + */ + +#ifndef _GDRIVER_OPTIONS_H +#define _GDRIVER_OPTIONS_H + +/** + * @name GDRIVER Functionality to be included + * @{ + */ +/** + * @} + * + * @name GDRIVER Optional Parameters + * @{ + */ +/** @} */ + +#endif /* _GDRIVER_OPTIONS_H */ +/** @} */ diff --git a/src/gdriver/sys_rules.h b/src/gdriver/sys_rules.h new file mode 100644 index 00000000..596babba --- /dev/null +++ b/src/gdriver/sys_rules.h @@ -0,0 +1,23 @@ +/* + * 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.org/license.html + */ + +/** + * @file src/gdriver/sys_rules.h + * @brief GDRIVER safety rules header file. + * + * @addtogroup GFILE + * @{ + */ + +#ifndef _GDRIVER_RULES_H +#define _GDRIVER_RULES_H + +#if GFX_USE_GDRIVER +#endif + +#endif /* _GDRIVER_RULES_H */ +/** @} */