STMPE811 - initial

ugfx_release_2.6
Joel Bodenmann 2013-03-29 18:10:22 +01:00
parent 49550c4999
commit d6b75429b2
3 changed files with 185 additions and 166 deletions

View File

@ -55,15 +55,7 @@
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_EMBEST_DMSTF4BB)
#include "gdisp_lld_board_embest_dmstf4bb.h" #include "gdisp_lld_board_embest_dmstf4bb.h"
#else
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#endif
// Some common routines and macros // Some common routines and macros
#define write_reg(reg, data) { write_index(reg); write_data(data); } #define write_reg(reg, data) { write_index(reg); write_data(data); }

View File

@ -1,158 +1,183 @@
/* /*
ChibiOS/GFX - Copyright (C) 2012, 2013 ChibiOS/GFX - Copyright (C) 2012, 2013
Joel Bodenmann aka Tectu <joel@unormal.org> Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX. This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful, ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** /**
* @file drivers/ginput/touch/STMPE811/ginput_lld_mouse.c * @file drivers/ginput/touch/STMPE811/ginput_lld_mouse.c
* @brief GINPUT Touch low level driver source for the STMPE811. * @brief GINPUT Touch low level driver source for the STMPE811.
* *
* @defgroup Mouse Mouse * @defgroup Mouse Mouse
* @ingroup GINPUT * @ingroup GINPUT
* @{ * @{
*/ */
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "gfx.h" #include "gfx.h"
#include "stmpe811.h" #include "stmpe811.h"
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/ #if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
#include "ginput/lld/mouse.h" #include "ginput/lld/mouse.h"
#if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD #if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD
#include "ginput_lld_mouse_board.h" #include "ginput_lld_mouse_board.h"
#elif defined(BOARD_EMBEST_DMSTF4BB) #elif defined(BOARD_EMBEST_DMST4BB)
#include "ginput_lld_mouse_board_embest_dmstf4bb.h" #include "ginput_lld_mouse_board_embest_dmstf4bb.h"
#else #else
#include "ginput_lld_mouse_board_example.h" #include "ginput_lld_mouse_board_example.h"
#endif #endif
static coord_t lastx, lasty, lastz; #ifndef STMP811_NO_GPIO_IRQPIN
#define STMP811_NO_GPIO_IRQPIN FALSE
/* set the active window of the stmpe811. bl is bottom left, tr is top right */ #endif
static void setActiveWindow(uint16_t bl_x, uint16_t bl_y, uint16_t tr_x, uint16_t tr_y) #ifndef STMP811_SLOW_CPU
{ #define STMP811_SLOW_CPU FALSE
write_reg(STMPE811_REG_WDW_TR_X, 2, tr_x); #endif
write_reg(STMPE811_REG_WDW_TR_Y, 2, tr_y);
write_reg(STMPE811_REG_WDW_BL_X, 2, bl_x); static coord_t x, y, z;
write_reg(STMPE811_REG_WDW_BL_Y, 2, bl_y); static uint8_t touched;
}
/* set the active window of the stmpe811. bl is bottom left, tr is top right */
/** static void setActiveWindow(uint16_t bl_x, uint16_t bl_y, uint16_t tr_x, uint16_t tr_y)
* @brief Initialise the mouse/touch. {
* write_reg(STMPE811_REG_WDW_TR_X, 2, tr_x);
* @notapi write_reg(STMPE811_REG_WDW_TR_Y, 2, tr_y);
*/ write_reg(STMPE811_REG_WDW_BL_X, 2, bl_x);
void ginput_lld_mouse_init(void) write_reg(STMPE811_REG_WDW_BL_Y, 2, bl_y);
{ }
init_board();
/**
write_reg(STMPE811_REG_SYS_CTRL1, 1, 0x02); // Software chip reset * @brief Initialise the mouse/touch.
chThdSleepMilliseconds(10); *
* @notapi
write_reg(STMPE811_REG_SYS_CTRL2, 1, 0x0C); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on */
write_reg(STMPE811_REG_INT_EN, 1, 0x02); // Interrupt on INT pin when FIFO is equal or above threshold value OR touch is detected void ginput_lld_mouse_init(void)
write_reg(STMPE811_REG_ADC_CTRL1, 1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce {
chThdSleepMilliseconds(2); init_board();
write_reg(STMPE811_REG_ADC_CTRL2, 1, 0x01); // ADC speed 3.25MHz write_reg(STMPE811_REG_SYS_CTRL1, 1, 0x02); // Software chip reset
write_reg(STMPE811_REG_GPIO_AF, 1, 0x00); // GPIO alternate function - OFF chThdSleepMilliseconds(10);
write_reg(STMPE811_REG_TSC_CFG, 1, 0x9A); // Averaging 4, touch detect delay 500 us, panel driver settling time 500 us
write_reg(STMPE811_REG_FIFO_TH, 1, 0x01); // FIFO threshold = 1 write_reg(STMPE811_REG_SYS_CTRL2, 1, 0x0C); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on
write_reg(STMPE811_REG_FIFO_STA, 1, 0x01); // FIFO reset enable #if STMP811_NO_GPIO_IRQPIN
write_reg(STMPE811_REG_FIFO_STA, 1, 0x00); // FIFO reset disable write_reg(STMPE811_REG_INT_EN, 1, 0x00); // Interrupt on INT pin when touch is detected
write_reg(STMPE811_REG_TSC_FRACT_XYZ, 1, 0x07); // Z axis data format #else
write_reg(STMPE811_REG_TSC_I_DRIVE, 1, 0x01); // 50mA touchscreen line current write_reg(STMPE811_REG_INT_EN, 1, 0x01); // Interrupt on INT pin when touch is detected
write_reg(STMPE811_REG_TSC_CTRL, 1, 0x01); // X&Y&Z, TSC enable #endif
write_reg(STMPE811_REG_INT_STA, 1, 0xFF); // Clear all interrupts write_reg(STMPE811_REG_ADC_CTRL1, 1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce
write_reg(STMPE811_REG_INT_CTRL, 1, 0x01); // Level interrupt, enable intrrupts chThdSleepMilliseconds(2);
}
write_reg(STMPE811_REG_ADC_CTRL2, 1, 0x01); // ADC speed 3.25MHz
/** write_reg(STMPE811_REG_GPIO_AF, 1, 0x00); // GPIO alternate function - OFF
* @brief Read the mouse/touch position. write_reg(STMPE811_REG_TSC_CFG, 1, 0x9A); // Averaging 4, touch detect delay 500 us, panel driver settling time 500 us
* write_reg(STMPE811_REG_FIFO_TH, 1, 0x40); // FIFO threshold = 64
* @param[in] pt A pointer to the structure to fill write_reg(STMPE811_REG_FIFO_STA, 1, 0x01); // FIFO reset enable
* write_reg(STMPE811_REG_FIFO_STA, 1, 0x00); // FIFO reset disable
* @note For drivers that don't support returning a position write_reg(STMPE811_REG_TSC_FRACT_XYZ, 1, 0x07); // Z axis data format
* when the touch is up (most touch devices), it should write_reg(STMPE811_REG_TSC_I_DRIVE, 1, 0x01); // 50mA touchscreen line current
* return the previous position with the new Z value. write_reg(STMPE811_REG_TSC_CTRL, 1, 0x00); // X&Y&Z
* The z value is the pressure for those touch devices write_reg(STMPE811_REG_TSC_CTRL, 1, 0x01); // X&Y&Z, TSC enable
* that support it (-100 to 100 where > 0 is touched) write_reg(STMPE811_REG_INT_STA, 1, 0xFF); // Clear all interrupts
* or, 0 or 100 for those drivers that don't. #if !STMP811_NO_GPIO_IRQPIN
* touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80;
* @notapi #endif
*/ write_reg(STMPE811_REG_INT_CTRL, 1, 0x01); // Level interrupt, enable intrrupts
void ginput_lld_mouse_get_reading(MouseReading *pt) }
{
//uint16_t buf; /**
uint8_t int_status; * @brief Read the mouse/touch position.
*
// If not touched, return the previous results * @param[in] pt A pointer to the structure to fill
if (!getpin_pressed()) { *
pt->x = lastx; * @note For drivers that don't support returning a position
pt->y = lasty; * when the touch is up (most touch devices), it should
pt->z = 0; * return the previous position with the new Z value.
pt->buttons = 0; * The z value is the pressure for those touch devices
return; * that support it (-100 to 100 where > 0 is touched)
} * or, 0 or 100 for those drivers that don't.
*
// Find out what caused an interrupt * @notapi
int_status = read_reg(STMPE811_REG_INT_STA, 1); */
void ginput_lld_mouse_get_reading(MouseReading *pt)
// If it is TOUCH interrupt, clear it and go on {
if (int_status & 0x02) { bool_t clearfifo; // Do we need to clear the FIFO
uint8_t size = 0; #if STMP811_NO_GPIO_IRQPIN
size = read_reg(STMPE811_REG_FIFO_SIZE, 1); // Poll to get the touched status
uint8_t last_touched;
if (size) {
uint8_t buffer[size * 4]; last_touched = touched;
read_reg_n(STMPE811_REG_TSC_DATA_AI, size * 4, buffer); touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80;
clearfifo = (touched != last_touched);
lastx = (coord_t)((buffer[0] << 4) | (buffer[1] >> 4)); #else
lasty = (coord_t)(((buffer[1] & 0x0F) << 8) | buffer[2]); // Check if the touch controller IRQ pin has gone off
lastz = (coord_t)buffer[3]; clearfifo = false;
if(getpin_pressed()) { // please rename this to getpin_irq
/* Get the X value */ write_reg(STMPE811_REG_INT_STA, 1, 0xFF); // clear all interrupts
//buf = read_reg(STMPE811_REG_TSC_DATA_X, 2); touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80; // set the new touched status
//lastx = (coord_t)(buf); clearfifo = true; // only take the last FIFO reading
}
/* Get the Y value */ #endif
//buf = read_reg(STMPE811_REG_TSC_DATA_Y, 2);
//lasty = (coord_t)(buf); // If not touched, return the previous results
if (!touched) {
/* Get the Z value */ pt->x = x;
//buf = read_reg(STMPE811_REG_TSC_DATA_Z, 1); pt->y = y;
//lastz = (buf & 0x00FF); pt->z = 0;
pt->buttons = 0;
// Return the results. ADC gives values from 0 to 2^12 return;
pt->x = 320 - lastx / 13; }
pt->y = lasty / 17;
pt->z = lastz; #if !STMP811_SLOW_CPU
pt->buttons = GINPUT_TOUCH_PRESSED; if (!clearfifo && (read_reg(STMPE811_REG_FIFO_STA, 1) & 0xD0))
} #endif
clearfifo = true;
write_reg(STMPE811_REG_INT_STA, 1, 0x02);
} do {
} /* Get the X, Y, Z values */
/* This could be done in a single 4 byte read to STMPE811_REG_TSC_DATA_XYZ (incr or non-incr) */
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */ x = (coord_t)read_reg(STMPE811_REG_TSC_DATA_X, 2);
/** @} */ y = (coord_t)read_reg(STMPE811_REG_TSC_DATA_Y, 2);
z = (coord_t)read_reg(STMPE811_REG_TSC_DATA_Z, 1);
} while(clearfifo && !(read_reg(STMPE811_REG_FIFO_STA, 1) & 0x20));
// Rescale X,Y,Z - X & Y don't need scaling when you are using calibration!
#if !GINPUT_MOUSE_NEED_CALIBRATION
x = gdispGetWidth() - x / (4096/gdispGetWidth());
y = y / (4096/gdispGetHeight());
#endif
z = (((z&0xFF) * 100)>>8) + 1;
// Return the results. ADC gives values from 0 to 2^12 (4096)
pt->x = x;
pt->y = y;
pt->z = z;
pt->buttons = GINPUT_TOUCH_PRESSED;
/* Force another read if we have more results */
if (!clearfifo && !(read_reg(STMPE811_REG_FIFO_STA, 1) & 0x20))
ginputMouseWakeup();
}
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
/** @} */

View File

@ -39,6 +39,8 @@
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10 #define GINPUT_MOUSE_MAX_CLICK_JITTER 10
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2 #define GINPUT_MOUSE_MAX_MOVE_JITTER 2
#define GINPUT_MOUSE_CLICK_TIME 500 #define GINPUT_MOUSE_CLICK_TIME 500
#define STMP811_SLOWER_RESPONSE FALSE
#define STMP811_NO_GPIO_IRQPIN FALSE
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */ #endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
/** @} */ /** @} */