diff --git a/demos/modules/ginput/touch_driver_test/main.c b/demos/modules/ginput/touch_driver_test/main.c index 95d29d28..c7866ec3 100644 --- a/demos/modules/ginput/touch_driver_test/main.c +++ b/demos/modules/ginput/touch_driver_test/main.c @@ -201,28 +201,24 @@ StepCalibrate: gwinSetButtonText(ghNext, "Next", FALSE); gsNext = gwinGetButtonSource(ghNext); geventAttachSource(&gl, gsNext, 0); - gwinAttachButtonMouseSource(ghNext, gs); + gwinAttachButtonMouse(ghNext, 0); ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL); gwinSetButtonText(ghPrev, "Back", FALSE); gsPrev = gwinGetButtonSource(ghPrev); geventAttachSource(&gl, gsPrev, 0); - gwinAttachButtonMouseSource(ghPrev, gs); + gwinAttachButtonMouse(ghPrev, 0); #if 0 { - GSourceHandle gsButton1, gsButton2; - // Attach a couple of hardware toggle buttons to our Next and Back buttons as well. // We can always use the mouse to trigger the buttons if you don't want to use hardware toggles. // This code depends on your hardware. Turn it on only if you have // defined a board definition for your toggle driver. Then change // the next two lines to be correct for your hardware. The values // below are correct for the Win32 toggle driver. - gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1); - gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2); - gwinAttachButtonToggleSource(ghNext, gsButton2); - gwinAttachButtonToggleSource(ghPrev, gsButton1); + gwinAttachButtonToggle(ghNext, GINPUT_TOGGLE_MOMENTARY1); + gwinAttachButtonToggle(ghPrev, GINPUT_TOGGLE_MOMENTARY2); } #endif } diff --git a/demos/modules/gwin/slider/gfxconf.h b/demos/modules/gwin/slider/gfxconf.h index 477d7d29..947fc4c8 100644 --- a/demos/modules/gwin/slider/gfxconf.h +++ b/demos/modules/gwin/slider/gfxconf.h @@ -53,5 +53,6 @@ /* Features for the GINPUT sub-system. */ #define GINPUT_NEED_MOUSE TRUE +#define GINPUT_NEED_DIAL TRUE #endif /* _GFXCONF_H */ diff --git a/demos/modules/gwin/slider/main.c b/demos/modules/gwin/slider/main.c index 9a318943..19a56f6a 100644 --- a/demos/modules/gwin/slider/main.c +++ b/demos/modules/gwin/slider/main.c @@ -31,7 +31,7 @@ int main(void) { coord_t swidth, sheight; GHandle ghSliderH, ghSliderV, ghConsole; font_t fui2; - GSourceHandle gsMouse; + GEvent * pe; GEventGWinSlider * pSliderEvent; BaseSequentialStream *consout; @@ -58,10 +58,15 @@ int main(void) { gwinSetColor(ghConsole, White); gwinSetBgColor(ghConsole, Blue); - // Assign the mouse to the sliders. - gsMouse = ginputGetMouse(0); - gwinAttachSliderMouseSource(ghSliderH, gsMouse); - gwinAttachSliderMouseSource(ghSliderV, gsMouse); + // Assign the mouse and dials to the sliders. +#if GINPUT_NEED_MOUSE + gwinAttachSliderMouse(ghSliderH, 0); + gwinAttachSliderMouse(ghSliderV, 0); +#endif +#if GINPUT_NEED_DIAL + gwinAttachSliderDial(ghSliderV, 0); + gwinAttachSliderDial(ghSliderH, 1); +#endif // We want to listen for slider events geventListenerInit(&gl); @@ -75,14 +80,14 @@ int main(void) { while(1) { // Get an Event - // - we can assume it is a slider event as that is all we are listening for - pSliderEvent = (GEventGWinSlider *)geventEventWait(&gl, TIME_INFINITE); + pe = geventEventWait(&gl, TIME_INFINITE); - // Double check that assumption - if (pSliderEvent->type != GEVENT_GWIN_SLIDER) - continue; - - chprintf(consout, "%c=%d\n", pSliderEvent->slider == ghSliderH ? 'H' : 'V', pSliderEvent->position); + switch(pe->type) { + case GEVENT_GWIN_SLIDER: + pSliderEvent = (GEventGWinSlider *)pe; + chprintf(consout, "%c=%d\n", pSliderEvent->slider == ghSliderH ? 'H' : 'V', pSliderEvent->position); + break; + } } return 0; diff --git a/demos/modules/gwin/slider/readme.txt b/demos/modules/gwin/slider/readme.txt new file mode 100644 index 00000000..2864873a --- /dev/null +++ b/demos/modules/gwin/slider/readme.txt @@ -0,0 +1,6 @@ +This demo supports input from both a mouse/touch and/or a dial input. +If your platform does not support one or the other, turn it off in +gfxconf.h + +Note that you will need to include the drivers into your project +makefile for whichever inputs you decide to use. \ No newline at end of file diff --git a/drivers/ginput/dial/GADC/ginput_lld.mk b/drivers/ginput/dial/GADC/ginput_lld.mk new file mode 100644 index 00000000..763549b8 --- /dev/null +++ b/drivers/ginput/dial/GADC/ginput_lld.mk @@ -0,0 +1,5 @@ +# List the required driver. +GFXSRC += $(GFXLIB)/drivers/ginput/dial/GADC/ginput_lld_dial.c + +# Required include directories +GFXINC += $(GFXLIB)/drivers/ginput/dial/GADC diff --git a/drivers/ginput/dial/GADC/ginput_lld_dial.c b/drivers/ginput/dial/GADC/ginput_lld_dial.c new file mode 100644 index 00000000..ced71a27 --- /dev/null +++ b/drivers/ginput/dial/GADC/ginput_lld_dial.c @@ -0,0 +1,101 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file drivers/ginput/dial/GADC/ginput_lld_dial.c + * @brief GINPUT Dial low level driver source for GADC hardware. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "gfx.h" + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + +#include "ginput/lld/dial.h" + +#if GINPUT_DIAL_NUM_PORTS >= 5 + #error "GINPUT: Dial - GADC driver currently only supports 4 devices" +#endif + +static adcsample_t samplebuf[GINPUT_DIAL_NUM_PORTS]; + +#if GINPUT_DIAL_CYCLE_POLL + static uint16_t cycle; +#endif + +static void GADCCallback(adcsample_t *buffer, void *param) { + ((DialCallbackFn)param)(buffer-samplebuf, buffer[0]); +} + +void ginput_lld_dial_init(void) { + #if GINPUT_DIAL_CYCLE_POLL + cycle = 0; + #endif +} + +void ginput_lld_dial_poll(DialCallbackFn fn) { + #if GINPUT_DIAL_CYCLE_POLL + switch(cycle++) { + #if GINPUT_DIAL_NUM_PORTS >= 1 + case 0: + gadcLowSpeedStart(GINPUT_DIAL_DEVICE0, samplebuf+0, GADCCallback, (void *)fn); + break; + #endif + #if GINPUT_DIAL_NUM_PORTS >= 2 + case 1: + gadcLowSpeedStart(GINPUT_DIAL_DEVICE1, samplebuf+1, GADCCallback, (void *)fn); + break; + #endif + #if GINPUT_DIAL_NUM_PORTS >= 3 + case 2: + gadcLowSpeedStart(GINPUT_DIAL_DEVICE2, samplebuf+2, GADCCallback, (void *)fn); + break; + #endif + #if GINPUT_DIAL_NUM_PORTS >= 4 + case 3: + gadcLowSpeedStart(GINPUT_DIAL_DEVICE3, samplebuf+3, GADCCallback, (void *)fn); + break; + #endif + } + if (cycle >= GINPUT_DIAL_NUM_PORTS) + cycle = 0; + #else + #if GINPUT_DIAL_NUM_PORTS >= 1 + gadcLowSpeedStart(GINPUT_DIAL_DEVICE0, samplebuf+0, GADCCallback, (void *)fn); + #endif + #if GINPUT_DIAL_NUM_PORTS >= 2 + gadcLowSpeedStart(GINPUT_DIAL_DEVICE1, samplebuf+1, GADCCallback, (void *)fn); + #endif + #if GINPUT_DIAL_NUM_PORTS >= 3 + gadcLowSpeedStart(GINPUT_DIAL_DEVICE2, samplebuf+2, GADCCallback, (void *)fn); + #endif + #if GINPUT_DIAL_NUM_PORTS >= 4 + gadcLowSpeedStart(GINPUT_DIAL_DEVICE3, samplebuf+3, GADCCallback, (void *)fn); + #endif + #endif +} + +#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */ +/** @} */ diff --git a/drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h b/drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h new file mode 100644 index 00000000..13788188 --- /dev/null +++ b/drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h @@ -0,0 +1,48 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file drivers/ginput/dial/GADC/ginput_lld_dial_board_olimexsam7ex256.h + * @brief GINPUT Dial Driver config file. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * @{ + */ + +#ifndef _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H +#define _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + +/*===========================================================================*/ +/* Analogue devices on this board */ +/*===========================================================================*/ + +#define GINPUT_DIAL_NUM_PORTS 1 +#define GINPUT_DIAL_DEVICE0 GADC_PHYSDEV_DIAL +#define GINPUT_DIAL_POLL_PERIOD 200 +#define GINPUT_DIAL_CYCLE_POLL FALSE + +#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */ + +#endif /* _GINPUT_LLD_DIAL_BOARD_OLIMEXSAM7EX256_H */ +/** @} */ + diff --git a/drivers/ginput/dial/GADC/ginput_lld_dial_config.h b/drivers/ginput/dial/GADC/ginput_lld_dial_config.h new file mode 100644 index 00000000..535b09a6 --- /dev/null +++ b/drivers/ginput/dial/GADC/ginput_lld_dial_config.h @@ -0,0 +1,50 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file drivers/ginput/dial/GADC/ginput_lld_dial_config.h + * @brief GINPUT Dial Driver configuration header. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * @{ + */ + +#ifndef _GINPUT_LLD_DIAL_CONFIG_H +#define _GINPUT_LLD_DIAL_CONFIG_H + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + +#define GINPUT_DIAL_MAX_VALUE ((1< - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -/** - * @file include/ginput/dial.h - * @brief GINPUT GFX User Input subsystem header file. - * - * @defgroup Dial Dial - * @ingroup GINPUT - * - * @details A dial provides a powerful way to navigate through menus - * on a display. - * - * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h - * @pre GINPUT_NEED_DIAL must be set to TRUE in your gfxconf.h - * - * @{ - */ -#ifndef _GINPUT_DIAL_H -#define _GINPUT_DIAL_H - -#if GINPUT_NEED_DIAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Type definitions */ -/*===========================================================================*/ - -// Event types for various ginput sources -#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4) - -typedef struct GEventDial_t { - GEventType type; // The type of this event (GEVENT_DIAL) - uint16_t instance; // The dial instance - uint16_t value; // The dial value - } GEventDial; - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - - /** - * @brief Create a dial input instance - * - * @param[in] instance The ID of the dial input instance (from 0 to 9999) - * - * @return The soure handle of the created dial instance - */ - GSourceHandle ginputGetDial(uint16_t instance); - - /** - * @brief Reset the value back to the hardware default - * - * @param[in] instance The ID of the dial input instance - */ - void ginputResetDialRange(uint16_t instance); - - /** - * @brief Get the maximum value - * @details The readings are scaled to be 0 ... max-1. - * 0 means over the full uint16_t range. - * - * @param[in] instance The ID of the dial input instance - * - * @return The maximum value - */ - uint16_t ginputGetDialRange(uint16_t instance); - - /** - * @brief Set the maximum value - * @note This shouldn't be set higher that the hardwares possible maximum value - * - * @param[in] instance The ID of the dial input instance - * @param[in] max The maximum value to be set - */ - void ginputSetDialRange(uint16_t instance, uint16_t max); - - /** - * @brief Set the level change required before a dial even is generated (threshold) - * @note This is done after range scaling - * - * @param[in] instance The ID of the dial input instance - * @param[in] diff The amount of level changes - */ - void ginputSetDialSensitivity(uint16_t instance, uint16_t diff); - - /** - * @brief Get the current dial status - * - * @param[in] instance The ID of the dial input instance - * @param[in] pdial The dial event struct - * - * @return Returns FALSE on an error (eg invalid instance) - */ - bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial); - -#ifdef __cplusplus -} -#endif - -#endif /* GINPUT_NEED_DIAL */ - -#endif /* _GINPUT_DIAL_H */ -/** @} */ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/** + * @file include/ginput/dial.h + * @brief GINPUT GFX User Input subsystem header file. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * + * @details A dial provides a powerful way to navigate through menus + * on a display. + * + * @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h + * @pre GINPUT_NEED_DIAL must be set to TRUE in your gfxconf.h + * + * @{ + */ +#ifndef _GINPUT_DIAL_H +#define _GINPUT_DIAL_H + +#if GINPUT_NEED_DIAL || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Type definitions */ +/*===========================================================================*/ + +// Event types for various ginput sources +#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4) + +typedef struct GEventDial_t { + GEventType type; // The type of this event (GEVENT_DIAL) + uint16_t instance; // The dial instance + uint16_t value; // The dial value + } GEventDial; + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @brief Create a dial input instance + * + * @param[in] instance The ID of the dial input instance (from 0 to 9999) + * + * @return The soure handle of the created dial instance + */ + GSourceHandle ginputGetDial(uint16_t instance); + + /** + * @brief Reset the value back to the hardware default + * + * @param[in] instance The ID of the dial input instance + */ + void ginputResetDialRange(uint16_t instance); + + /** + * @brief Get the maximum value + * @details The readings are scaled to be 0 ... max. + * + * @param[in] instance The ID of the dial input instance + * + * @return The maximum value + */ + uint16_t ginputGetDialRange(uint16_t instance); + + /** + * @brief Set the maximum value + * @details The readings are scaled to be 0 ... max. + * + * @param[in] instance The ID of the dial input instance + * @param[in] max The maximum value to be set + */ + void ginputSetDialRange(uint16_t instance, uint16_t max); + + /** + * @brief Set the level change required before a dial even is generated (threshold) + * @note This is done after range scaling + * + * @param[in] instance The ID of the dial input instance + * @param[in] diff The amount of level changes + */ + void ginputSetDialSensitivity(uint16_t instance, uint16_t diff); + + /** + * @brief Get the current dial status + * + * @param[in] instance The ID of the dial input instance + * @param[in] pdial The dial event struct + * + * @return Returns FALSE on an error (eg invalid instance) + */ + bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial); + +#ifdef __cplusplus +} +#endif + +#endif /* GINPUT_NEED_DIAL */ + +#endif /* _GINPUT_DIAL_H */ +/** @} */ diff --git a/include/ginput/lld/dial.h b/include/ginput/lld/dial.h new file mode 100644 index 00000000..3efae04f --- /dev/null +++ b/include/ginput/lld/dial.h @@ -0,0 +1,57 @@ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/** + * @file include/ginput/lld/dial.h + * @brief GINPUT header file for dial drivers. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * @{ + */ + +#ifndef _LLD_GINPUT_DIAL_H +#define _LLD_GINPUT_DIAL_H + +#if GINPUT_NEED_DIAL || defined(__DOXYGEN__) + +#include "ginput_lld_dial_config.h" + +typedef void (*DialCallbackFn)(uint16_t instance, uint16_t rawvalue); + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + + void ginput_lld_dial_init(void); + void ginput_lld_dial_poll(DialCallbackFn fn); + +#ifdef __cplusplus +} +#endif + +#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */ + +#endif /* _LLD_GINPUT_TOGGLE_H */ +/** @} */ + diff --git a/include/gwin/button.h b/include/gwin/button.h index 2df540da..3d54afbb 100644 --- a/include/gwin/button.h +++ b/include/gwin/button.h @@ -180,30 +180,28 @@ void gwinSetButtonCustom(GHandle gh, GButtonDrawFunction fn, void *param); */ #define gwinGetButtonSource(gh) ((GSourceHandle)(gh)) -#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE /** - * @brief Attach a mouse source - * @details Attach a mouse source to a given button + * @brief Attach a mouse to a button * - * @param[in] gh The button handle - * @param[in] gsh The source handle + * @param[in] gh The button handle + * @param[in] instance The mouse instance * * @api */ - bool_t gwinAttachButtonMouseSource(GHandle gh, GSourceHandle gsh); + bool_t gwinAttachButtonMouse(GHandle gh, uint16_t instance); #endif -#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE +#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE /** - * @brief Attach a toggle source - * @details Attach a toggle source to this button + * @brief Attach a toggle to a button * - * @param[in] gh The button handle - * @param[in] gsh The source handle + * @param[in] gh The button handle + * @param[in] instance The toggle instance * * @api */ - bool_t gwinAttachButtonToggleSource(GHandle gh, GSourceHandle gsh); + bool_t gwinAttachButtonToggle(GHandle gh, uint16_t instance); #endif /** diff --git a/include/gwin/slider.h b/include/gwin/slider.h index 412900a5..1943729f 100644 --- a/include/gwin/slider.h +++ b/include/gwin/slider.h @@ -187,17 +187,30 @@ void gwinSetSliderCustom(GHandle gh, GSliderDrawFunction fn, void *param); */ #define gwinGetSliderSource(gh) ((GSourceHandle)(gh)) -#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE /** * @brief Attach a mouse source - * @details Attach a mouse source to a slider + * @details Attach a mouse to a slider * - * @param[in] gh The slider handle - * @param[in] gsh The source handle + * @param[in] gh The slider handle + * @param[in] instance The mouse instance * * @api */ - bool_t gwinAttachSliderMouseSource(GHandle gh, GSourceHandle gsh); + bool_t gwinAttachSliderMouse(GHandle gh, uint16_t instance); +#endif + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + /** + * @brief Attach a dial source + * @details Attach a dial to a slider + * + * @param[in] gh The dial handle + * @param[in] instance The dial instance + * + * @api + */ + bool_t gwinAttachSliderDial(GHandle gh, uint16_t instance); #endif /** diff --git a/releases.txt b/releases.txt index 2089848b..9a09b87f 100644 --- a/releases.txt +++ b/releases.txt @@ -22,6 +22,8 @@ FEATURE: SSD1963 rework by username 'fred' FEATURE: Added Picture converter tool FEATURE: Added slider widget FEATURE: Added gwinDraw() routine +FEATURE: Added GINPUT Dial support and driver using GADC +FEATURE: Simplified assigning inputs to buttons and sliders *** changes after 1.4 *** diff --git a/src/ginput/dial.c b/src/ginput/dial.c index 60bc9ae8..2f572cf8 100644 --- a/src/ginput/dial.c +++ b/src/ginput/dial.c @@ -1,36 +1,166 @@ -/* - ChibiOS/GFX - Copyright (C) 2012, 2013 - Joel Bodenmann aka Tectu - - This file is part of ChibiOS/GFX. - - ChibiOS/GFX is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/GFX is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/** - * @file src/ginput/dial.c - * @brief GINPUT dial code. - * - * @defgroup Dial Dial - * @ingroup GINPUT - * @{ - */ -#include "ch.h" -#include "hal.h" -#include "gfx.h" - -#if (GFX_USE_GINPUT && GINPUT_NEED_DIAL) || defined(__DOXYGEN__) - #error "GINPUT: GINPUT_NEED_DIAL - Not Implemented Yet" -#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */ -/** @} */ +/* + ChibiOS/GFX - Copyright (C) 2012, 2013 + Joel Bodenmann aka Tectu + + This file is part of ChibiOS/GFX. + + ChibiOS/GFX is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/GFX is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file src/ginput/dial.c + * @brief GINPUT dial code. + * + * @defgroup Dial Dial + * @ingroup GINPUT + * @{ + */ +#include "ch.h" +#include "hal.h" +#include "gfx.h" + +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + +#include "ginput/lld/dial.h" + +static GTIMER_DECL(DialTimer); +static struct DialStatus_t { + uint16_t sensitivity; + uint16_t lastvalue; + uint16_t max; +} DialStatus[GINPUT_DIAL_NUM_PORTS]; + +// The reading callback function +static void DialCallback(uint16_t instance, uint16_t rawvalue) { + struct DialStatus_t *pds; + GSourceListener *psl; + GEventDial *pe; + + /* Get the information we need */ + pds = DialStatus+instance; + + /* Range scale - if needed */ + if (pds->max != GINPUT_DIAL_MAX_VALUE) + rawvalue = (uint16_t)((uint32_t)rawvalue * pds->max / GINPUT_DIAL_MAX_VALUE); + + /* Forget about changes below our sensitivity threshold */ + if (rawvalue >= pds->lastvalue) { + if (rawvalue - pds->lastvalue < pds->sensitivity) return; + } else { + if (pds->lastvalue - rawvalue < pds->sensitivity) return; + } + + /* Save the value */ + pds->lastvalue = rawvalue; + + // Send the event to the listeners that are interested. + psl = 0; + while ((psl = geventGetSourceListener((GSourceHandle)(DialStatus+instance), psl))) { + if (!(pe = (GEventDial *)geventGetEventBuffer(psl))) + continue; + pe->type = GEVENT_DIAL; + pe->instance = instance; + pe->value = pds->lastvalue; + geventSendEvent(psl); + } +} + +GSourceHandle ginputGetDial(uint16_t instance) { + struct DialStatus_t *pds; + + if (instance >= GINPUT_DIAL_NUM_PORTS) + return 0; + + // Do we need to initialise the dial subsystem? + if (!gtimerIsActive(&DialTimer)) { + for(pds = DialStatus; pds < DialStatus+GINPUT_DIAL_NUM_PORTS; pds++) { + pds->max = GINPUT_DIAL_MAX_VALUE; +#if GINPUT_DIAL_MAX_VALUE < 100 + pds->sensitivity = 1; +#else + pds->sensitivity = GINPUT_DIAL_MAX_VALUE/100; +#endif + pds->lastvalue = 0; + } + ginput_lld_dial_init(); + gtimerStart(&DialTimer, (GTimerFunction)ginput_lld_dial_poll, DialCallback, TRUE, GINPUT_DIAL_POLL_PERIOD); + } + + // OK - return this input + return (GSourceHandle)(DialStatus+instance); +} + +void ginputResetDialRange(uint16_t instance) { + if (instance >= GINPUT_DIAL_NUM_PORTS) + return; + + ginputSetDialRange(instance, GINPUT_DIAL_MAX_VALUE); +} + +uint16_t ginputGetDialRange(uint16_t instance) { + if (instance >= GINPUT_DIAL_NUM_PORTS) + return 0; + + return DialStatus[instance].max; +} + +void ginputSetDialRange(uint16_t instance, uint16_t max) { + struct DialStatus_t *pds; + + if (instance >= GINPUT_DIAL_NUM_PORTS) + return; + + pds = DialStatus+instance; + + // Rescale the last value and the sensitivity + if (max != pds->max) { + pds->lastvalue = (uint16_t)((uint32_t)pds->lastvalue * max / pds->max); + pds->sensitivity = (uint16_t)((uint32_t)pds->sensitivity * max / pds->max); + pds->max = max; + } +} + +/** + * @brief Set the level change required before a dial even is generated (threshold) + * @note This is done after range scaling + * + * @param[in] instance The ID of the dial input instance + * @param[in] diff The amount of level changes + */ +void ginputSetDialSensitivity(uint16_t instance, uint16_t diff) { + if (instance >= GINPUT_DIAL_NUM_PORTS) + return; + + DialStatus[instance].sensitivity = diff; +} + +/** + * @brief Get the current dial status + * + * @param[in] instance The ID of the dial input instance + * @param[in] pdial The dial event struct + * + * @return Returns FALSE on an error (eg invalid instance) + */ +bool_t ginputGetDialStatus(uint16_t instance, GEventDial *pdial) { + if (instance >= GINPUT_DIAL_NUM_PORTS) + return FALSE; + pdial->type = GEVENT_DIAL; + pdial->instance = instance; + pdial->value = DialStatus[instance].lastvalue; + return TRUE; +} + +#endif /* GFX_USE_GINPUT && GINPUT_NEED_DIAL */ +/** @} */ diff --git a/src/gwin/button.c b/src/gwin/button.c index bec738b4..74fe3080 100644 --- a/src/gwin/button.c +++ b/src/gwin/button.c @@ -68,7 +68,7 @@ static void gwinButtonCallback(void *param, GEvent *pe) { #define pbe ((GEventGWinButton *)pe) switch (pe->type) { - #if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE + #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE case GEVENT_MOUSE: case GEVENT_TOUCH: // Ignore anything other than the primary mouse button going up or down @@ -108,7 +108,7 @@ static void gwinButtonCallback(void *param, GEvent *pe) { #endif #endif - #if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE + #if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE case GEVENT_TOGGLE: // State has changed - update the button gbw->state = pxe->on ? GBTN_DOWN : GBTN_UP; @@ -375,18 +375,22 @@ void gwinButtonDraw_Square(GHandle gh, bool_t isdown, const char *txt, const GBu } #endif -#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE - bool_t gwinAttachButtonMouseSource(GHandle gh, GSourceHandle gsh) { - if (gh->type != GW_BUTTON) +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE + bool_t gwinAttachButtonMouse(GHandle gh, uint16_t instance) { + GSourceHandle gsh; + + if (gh->type != GW_BUTTON || !(gsh = ginputGetMouse(instance))) return FALSE; return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA); } #endif -#if defined(GINPUT_NEED_TOGGLE) && GINPUT_NEED_TOGGLE - bool_t gwinAttachButtonToggleSource(GHandle gh, GSourceHandle gsh) { - if (gh->type != GW_BUTTON) +#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE + bool_t gwinAttachButtonToggle(GHandle gh, uint16_t instance) { + GSourceHandle gsh; + + if (gh->type != GW_BUTTON || !(gsh = ginputGetToggle(instance))) return FALSE; return geventAttachSource(&((GButtonObject *)gh)->listener, gsh, GLISTEN_TOGGLE_OFF|GLISTEN_TOGGLE_ON); diff --git a/src/gwin/slider.c b/src/gwin/slider.c index 034ba6b2..f535b35c 100644 --- a/src/gwin/slider.c +++ b/src/gwin/slider.c @@ -39,7 +39,9 @@ #define GWIN_SLIDER_DEAD_BAND 5 #endif -static void trackSliderDraw(GHandle gh, coord_t x, coord_t y); +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE + static void trackSliderDraw(GHandle gh, coord_t x, coord_t y); +#endif static const GSliderDrawStyle GSliderDefaultStyle = { HTML2COLOR(0x404040), // color_edge; @@ -55,10 +57,11 @@ static void gwinSliderCallback(void *param, GEvent *pe) { #define gsw ((GSliderObject *)param) #define gsh ((GSourceHandle)param) #define pme ((GEventMouse *)pe) + #define pde ((GEventDial *)pe) #define pse ((GEventGWinSlider *)pe) switch (pe->type) { - #if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE + #if GFX_USE_GINPUT && GINPUT_NEED_MOUSE case GEVENT_MOUSE: case GEVENT_TOUCH: // If not tracking we only only interested in a mouse down over the slider @@ -91,10 +94,10 @@ static void gwinSliderCallback(void *param, GEvent *pe) { // Set the new position if (gh->width < gh->height) gwinSetSliderPosition(gh, - (gh->height-1-pme->y+gh->y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + (uint16_t)((uint32_t)(gh->height-1-pme->y+gh->y-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->height-2*GWIN_SLIDER_DEAD_BAND) + gsw->min)); else gwinSetSliderPosition(gh, - (pme->x-gh->x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min); + (uint16_t)((uint32_t)(pme->x-gh->x-GWIN_SLIDER_DEAD_BAND)*(gsw->max-gsw->min)/(gh->width-2*GWIN_SLIDER_DEAD_BAND) + gsw->min)); // Update the display gwinSliderDraw(gh); @@ -109,6 +112,17 @@ static void gwinSliderCallback(void *param, GEvent *pe) { return; #endif + #if GFX_USE_GINPUT && GINPUT_NEED_DIAL + case GEVENT_DIAL: + // Set the new position + gwinSetSliderPosition(gh, (uint16_t)((uint32_t)pde->value*(gsw->max-gsw->min)/ginputGetDialRange(pde->instance) + gsw->min)); + + // Update the display + gwinSliderDraw(gh); + + // Generate the event + break; + #endif default: return; @@ -194,20 +208,22 @@ void gwinSetSliderStyle(GHandle gh, const GSliderDrawStyle *pStyle) { #undef gsw } -static void trackSliderDraw(GHandle gh, coord_t x, coord_t y) { - #define gsw ((GSliderObject *)gh) +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE + static void trackSliderDraw(GHandle gh, coord_t x, coord_t y) { + #define gsw ((GSliderObject *)gh) - #if GDISP_NEED_CLIP - gdispSetClip(gh->x, gh->y, gh->width, gh->height); - #endif + #if GDISP_NEED_CLIP + gdispSetClip(gh->x, gh->y, gh->width, gh->height); + #endif + + if (gh->height <= gh->width) + gsw->fn(gh, FALSE, x, &gsw->style, gsw->param); + else + gsw->fn(gh, TRUE, y, &gsw->style, gsw->param); - if (gh->height <= gh->width) - gsw->fn(gh, FALSE, x, &gsw->style, gsw->param); - else - gsw->fn(gh, TRUE, y, &gsw->style, gsw->param); - - #undef gbw -} + #undef gbw + } +#endif void gwinSliderDraw(GHandle gh) { #define gsw ((GSliderObject *)gh) @@ -267,15 +283,28 @@ void gwinSliderDraw_Std(GHandle gh, bool_t isVertical, coord_t thumbpos, const G } } -#if defined(GINPUT_NEED_MOUSE) && GINPUT_NEED_MOUSE - bool_t gwinAttachSliderMouseSource(GHandle gh, GSourceHandle gsh) { - if (gh->type != GW_SLIDER) +#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE + bool_t gwinAttachSliderMouse(GHandle gh, uint16_t instance) { + GSourceHandle gsh; + + if (gh->type != GW_SLIDER || !(gsh = ginputGetMouse(instance))) return FALSE; return geventAttachSource(&((GSliderObject *)gh)->listener, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES); } #endif +#if GFX_USE_GINPUT && GINPUT_NEED_DIAL + bool_t gwinAttachSliderDial(GHandle gh, uint16_t instance) { + GSourceHandle gsh; + + if (gh->type != GW_SLIDER || !(gsh = ginputGetDial(instance))) + return FALSE; + + return geventAttachSource(&((GSliderObject *)gh)->listener, gsh, 0); + } +#endif + #endif /* GFX_USE_GWIN && GWIN_NEED_BUTTON */ /** @} */