Merge branch 'newmouse'
This commit is contained in:
commit
d3a0606c65
@ -16,6 +16,14 @@
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_ADS7843_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_ADS7843_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_ADS7843_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_ADS7843_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_ADS7843_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_ADS7843_FINGER_MOVE_ERROR 14
|
||||
|
||||
static const SPIConfig spicfg = {
|
||||
0,
|
||||
GPIOG,
|
||||
@ -23,67 +31,49 @@ static const SPIConfig spicfg = {
|
||||
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void init_board(void) {
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_ADS7843_BOARD_DATA_SIZE 0
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
spiStart(&SPID2, &spicfg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool_t getpin_pressed(void) {
|
||||
static inline bool_t getpin_pressed(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
return (!palReadPad(GPIOG, 0));
|
||||
}
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void aquire_bus(void) {
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
spiAcquireBus(&SPID2);
|
||||
//TOUCHSCREEN_SPI_PROLOGUE();
|
||||
palClearPad(GPIOG, 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void release_bus(void) {
|
||||
static inline void release_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
palSetPad(GPIOG, 10);
|
||||
spiReleaseBus(&SPID2);
|
||||
//TOUCHSCREEN_SPI_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* params[in] port The controller port to read.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline uint16_t read_value(uint16_t port) {
|
||||
static inline uint16_t read_value(GMouse* m, uint16_t port) {
|
||||
static uint8_t txbuf[3] = {0};
|
||||
static uint8_t rxbuf[3] = {0};
|
||||
uint16_t ret;
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = port;
|
||||
|
||||
spiExchange(&SPID2, 3, txbuf, rxbuf);
|
||||
|
||||
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
|
||||
return ret;
|
||||
return ((uint16_t)rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
||||
|
@ -34,41 +34,61 @@ static const SPIConfig spicfg = {
|
||||
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
|
||||
};
|
||||
|
||||
static inline void init_board(void) {
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_ADS7843_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_ADS7843_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_ADS7843_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_ADS7843_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_ADS7843_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_ADS7843_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_ADS7843_BOARD_DATA_SIZE 0
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
palSetPadMode(GPIOB, 13, PAL_MODE_ALTERNATE(5) ); /* SCK */
|
||||
palSetPadMode(GPIOB, 14, PAL_MODE_ALTERNATE(5) ); /* MISO */
|
||||
palSetPadMode(GPIOB, 15, PAL_MODE_ALTERNATE(5) ); /* MOSI */
|
||||
palSetPadMode(GPIOC, 4, PAL_MODE_OUTPUT_PUSHPULL); /* CS */
|
||||
|
||||
spiStart(&SPID2, &spicfg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline bool_t getpin_pressed(void) {
|
||||
static inline bool_t getpin_pressed(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
return (!palReadPad(GPIOC, 5));
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void) {
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
spiAcquireBus(&SPID2);
|
||||
palClearPad(GPIOC, 4);
|
||||
}
|
||||
|
||||
static inline void release_bus(void) {
|
||||
static inline void release_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
palSetPad(GPIOC, 4);
|
||||
spiReleaseBus(&SPID2);
|
||||
}
|
||||
|
||||
static inline uint16_t read_value(uint16_t port) {
|
||||
static inline uint16_t read_value(GMouse* m, uint16_t port) {
|
||||
static uint8_t txbuf[3] = {0};
|
||||
static uint8_t rxbuf[3] = {0};
|
||||
uint16_t ret;
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = port;
|
||||
|
||||
spiExchange(&SPID2, 3, txbuf, rxbuf);
|
||||
|
||||
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
|
||||
return ret;
|
||||
return ((uint16_t)rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -16,6 +16,24 @@
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
#define ADC_MAX 1023
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_MCU_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_MCU_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_MCU_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_MCU_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_MCU_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_MCU_FINGER_MOVE_ERROR 14
|
||||
|
||||
#define GMOUSE_MCU_Z_MIN 0 // The minimum Z reading
|
||||
#define GMOUSE_MCU_Z_MAX ADC_MAX // The maximum Z reading
|
||||
#define GMOUSE_MCU_Z_TOUCHON 60 // Values between this and Z_MAX are definitely pressed
|
||||
#define GMOUSE_MCU_Z_TOUCHOFF 30 // Values between this and Z_MIN are definitely not pressed
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_MCU_BOARD_DATA_SIZE 0
|
||||
|
||||
static const ADCConfig ADCC = {
|
||||
.vref = ADC_VREF_CFG_AVDD_AVSS,
|
||||
.stime = 15,
|
||||
@ -29,10 +47,6 @@ static struct ADCDriver ADCD;
|
||||
#define XPOS 12 // L
|
||||
#define YPOS 11 // D
|
||||
|
||||
#define ADC_MAX 1023
|
||||
|
||||
#define TOUCH_THRESHOULD 50
|
||||
|
||||
static const ADCConversionGroup ADC_X_CG = {
|
||||
.circular = FALSE,
|
||||
.num_channels = 1,
|
||||
@ -45,104 +59,59 @@ static const ADCConversionGroup ADC_Y_CG = {
|
||||
.channels = 1 << YPOS,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void init_board(void) {
|
||||
adcObjectInit(&ADCD);
|
||||
adcStart(&ADCD, &ADCC);
|
||||
static bool_t init_board(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
adcObjectInit(&ADCD);
|
||||
adcStart(&ADCD, &ADCC);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the surface is currently touched
|
||||
* @return TRUE if the surface is currently touched
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool_t getpin_pressed(void) {
|
||||
adcsample_t samples[2] = {0, };
|
||||
static bool_t read_xyz(GMouse *m, GMouseReading *prd) {
|
||||
adcsample_t samples[2];
|
||||
|
||||
// Set X+ to ground
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, XPOS);
|
||||
prd->buttons = 0;
|
||||
|
||||
// Set Y- to VCC
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, YNEG);
|
||||
// Read the z value first.
|
||||
// Set X+ to ground and Y- to VCC
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, XPOS);
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, YNEG);
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
|
||||
adcConvert(&ADCD, &ADC_X_CG, &samples[0], 1);
|
||||
adcConvert(&ADCD, &ADC_Y_CG, &samples[1], 1);
|
||||
pdr->z = ADC_MAX - (samples[1] - samples[0]);
|
||||
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
|
||||
// Shortcut - no need to read X or Y if the touch is off.
|
||||
if (pdr->z < GMOUSE_MCU_Z_TOUCHON)
|
||||
return TRUE;
|
||||
|
||||
adcConvert(&ADCD, &ADC_X_CG, &samples[0], 1);
|
||||
adcConvert(&ADCD, &ADC_Y_CG, &samples[1], 1);
|
||||
// Read X
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, XPOS);
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, XNEG);
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_INPUT);
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
|
||||
adcConvert(&ADCD, &ADC_Y_CG, &samples[0], 1);
|
||||
pdr->x = ADC_MAX - samples[0];
|
||||
|
||||
return (ADC_MAX - (samples[1] - samples[0])) > TOUCH_THRESHOULD;
|
||||
}
|
||||
// Read Y
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, YNEG);
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, YPOS);
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_INPUT);
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
|
||||
adcConvert(&ADCD, &ADC_X_CG, &samples[0], 1);
|
||||
pdr->y = ADC_MAX - samples[0];
|
||||
|
||||
/**
|
||||
* @brief Aquire the bus ready for readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void aquire_bus(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Release the bus after readings
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void release_bus(void) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an x value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline uint16_t read_x_value(void) {
|
||||
adcsample_t sample;
|
||||
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, XPOS);
|
||||
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, XNEG);
|
||||
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_INPUT);
|
||||
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_INPUT_ANALOG);
|
||||
|
||||
adcConvert(&ADCD, &ADC_Y_CG, &sample, 1);
|
||||
|
||||
return ADC_MAX - sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an y value from touch controller
|
||||
* @return The value read from the controller
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline uint16_t read_y_value(void) {
|
||||
adcsample_t sample;
|
||||
|
||||
palSetPadMode(IOPORTB, YNEG, PAL_MODE_OUTPUT);
|
||||
palClearPad(IOPORTB, YNEG);
|
||||
|
||||
palSetPadMode(IOPORTB, YPOS, PAL_MODE_OUTPUT);
|
||||
palSetPad(IOPORTB, YPOS);
|
||||
|
||||
palSetPadMode(IOPORTB, XPOS, PAL_MODE_INPUT);
|
||||
|
||||
palSetPadMode(IOPORTB, XNEG, PAL_MODE_INPUT_ANALOG);
|
||||
|
||||
adcConvert(&ADCD, &ADC_X_CG, &sample, 1);
|
||||
|
||||
return ADC_MAX - sample;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static const I2CConfig i2ccfg = {
|
||||
OPMODE_I2C,
|
||||
400000,
|
||||
FAST_DUTY_CYCLE_2,
|
||||
};
|
||||
|
||||
static void init_board(void)
|
||||
{
|
||||
palSetPadMode(GPIOC, 13, PAL_MODE_INPUT | PAL_STM32_PUDR_FLOATING); /* TP IRQ */
|
||||
palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SCL */
|
||||
palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SDA */
|
||||
|
||||
i2cStart(&I2CD1, &i2ccfg);
|
||||
}
|
||||
|
||||
static inline bool_t getpin_irq(void)
|
||||
{
|
||||
return (!(palReadPad(GPIOC, 13)));
|
||||
}
|
||||
|
||||
static void write_reg(uint8_t reg, uint8_t n, uint16_t val)
|
||||
{
|
||||
uint8_t txbuf[3];
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
|
||||
txbuf[0] = reg;
|
||||
|
||||
if (n == 1) {
|
||||
txbuf[1] = val;
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 2, 0, 0, MS2ST(STMPE811_TIMEOUT));
|
||||
} else if (n == 2) {
|
||||
txbuf[1] = ((val & 0xFF00) >> 8);
|
||||
txbuf[2] = (val & 0x00FF);
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 3, 0, 0, MS2ST(STMPE811_TIMEOUT));
|
||||
}
|
||||
|
||||
i2cReleaseBus(&I2CD1);
|
||||
}
|
||||
|
||||
static uint16_t read_reg(uint8_t reg, uint8_t n)
|
||||
{
|
||||
uint8_t txbuf[1], rxbuf[2];
|
||||
uint16_t ret;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
rxbuf[1] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
|
||||
txbuf[0] = reg;
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
|
||||
|
||||
if (n == 1) {
|
||||
ret = rxbuf[0];
|
||||
} else if (n == 2) {
|
||||
ret = ((rxbuf[0] << 8) | (rxbuf[1] & 0xFF));
|
||||
}
|
||||
|
||||
i2cReleaseBus(&I2CD1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void read_reg_n(uint8_t reg, uint8_t n, uint8_t *rxbuf)
|
||||
{
|
||||
uint8_t txbuf[1];
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
|
||||
txbuf[0] = reg;
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 1, rxbuf, n, MS2ST(STMPE811_TIMEOUT));
|
||||
|
||||
i2cReleaseBus(&I2CD1);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
|
||||
#define GINPUT_MOUSE_READ_CYCLES 4
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 3
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
|
119
boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h
Normal file
119
boards/base/Embest-STM32-DMSTF4BB/gmouse_lld_STMPE811_board.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_STMPE811_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_STMPE811_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_STMPE811_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_STMPE811_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_STMPE811_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_STMPE811_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_STMPE811_BOARD_DATA_SIZE 0
|
||||
|
||||
// Options - Leave these commented to make it user configurable in the gfxconf.h
|
||||
//#define GMOUSE_STMPE811_READ_PRESSURE FALSE
|
||||
//#define GMOUSE_STMPE811_SELF_CALIBRATE FALSE
|
||||
//#define GMOUSE_STMPE811_TEST_MODE FALSE
|
||||
|
||||
// If TRUE this board has the STMPE811 IRQ pin connected to a GPIO.
|
||||
// Note: Although this board has such a pin its reliability has not been tested on this board!!!!!
|
||||
#define GMOUSE_STMPE811_GPIO_IRQPIN FALSE
|
||||
|
||||
// If TRUE this is a really slow CPU and we should always clear the FIFO between reads.
|
||||
#define GMOUSE_STMPE811_SLOW_CPU FALSE
|
||||
|
||||
// Slave address
|
||||
#define STMPE811_ADDR (0x82 >> 1)
|
||||
|
||||
// Maximum timeout
|
||||
#define STMPE811_TIMEOUT 0x3000
|
||||
|
||||
static const I2CConfig i2ccfg = {
|
||||
OPMODE_I2C,
|
||||
400000,
|
||||
FAST_DUTY_CYCLE_2,
|
||||
};
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
// This board only supports one touch panel
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
palSetPadMode(GPIOC, 13, PAL_MODE_INPUT | PAL_STM32_PUDR_FLOATING); /* TP IRQ */
|
||||
palSetPadMode(GPIOB, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SCL */
|
||||
palSetPadMode(GPIOB, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SDA */
|
||||
|
||||
i2cStart(&I2CD1, &i2ccfg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
static bool_t getpin_irq(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
return !palReadPad(GPIOC, 13);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) {
|
||||
uint8_t txbuf[2];
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = reg;
|
||||
txbuf[1] = val;
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, txbuf, 2, 0, 0, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD1);
|
||||
}
|
||||
|
||||
static uint8_t read_byte(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[1];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, ®, 1, rxbuf, 1, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD1);
|
||||
|
||||
return rxbuf[0];
|
||||
}
|
||||
|
||||
static uint16_t read_word(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[2];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
rxbuf[1] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD1);
|
||||
i2cMasterTransmitTimeout(&I2CD1, STMPE811_ADDR, ®, 1, rxbuf, 2, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD1);
|
||||
|
||||
return (((uint16_t)rxbuf[0]) << 8) | rxbuf[1];
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static const SPIConfig spicfg = {
|
||||
0,
|
||||
GPIOC,
|
||||
6,
|
||||
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
|
||||
};
|
||||
|
||||
static inline void init_board(void)
|
||||
{
|
||||
spiStart(&SPID1, &spicfg);
|
||||
}
|
||||
|
||||
static inline bool_t getpin_pressed(void)
|
||||
{
|
||||
return (!palReadPad(GPIOC, 4));
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void)
|
||||
{
|
||||
spiAcquireBus(&SPID1);
|
||||
palClearPad(GPIOC, 6);
|
||||
}
|
||||
|
||||
static inline void release_bus(void)
|
||||
{
|
||||
palSetPad(GPIOC, 6);
|
||||
spiReleaseBus(&SPID1);
|
||||
}
|
||||
|
||||
static inline uint16_t read_value(uint16_t port)
|
||||
{
|
||||
static uint8_t txbuf[3] = {0};
|
||||
static uint8_t rxbuf[3] = {0};
|
||||
uint16_t ret;
|
||||
|
||||
txbuf[0] = port;
|
||||
|
||||
spiExchange(&SPID1, 3, txbuf, rxbuf);
|
||||
|
||||
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
|
||||
#define GINPUT_MOUSE_READ_CYCLES 4
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 3
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
|
86
boards/base/FireBull-STM32F103-FB/gmouse_lld_ADS7843_board.h
Normal file
86
boards/base/FireBull-STM32F103-FB/gmouse_lld_ADS7843_board.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_ADS7843_PEN_CALIBRATE_ERROR 2
|
||||
#define GMOUSE_ADS7843_PEN_CLICK_ERROR 2
|
||||
#define GMOUSE_ADS7843_PEN_MOVE_ERROR 2
|
||||
#define GMOUSE_ADS7843_FINGER_CALIBRATE_ERROR 20
|
||||
#define GMOUSE_ADS7843_FINGER_CLICK_ERROR 4
|
||||
#define GMOUSE_ADS7843_FINGER_MOVE_ERROR 4
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_ADS7843_BOARD_DATA_SIZE 0
|
||||
|
||||
static const SPIConfig spicfg = {
|
||||
0,
|
||||
GPIOC,
|
||||
6,
|
||||
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
|
||||
};
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance)
|
||||
{
|
||||
(void)m;
|
||||
|
||||
// Only one touch interface on this board
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
// Set the GPIO modes
|
||||
palSetPadMode(GPIOC, 4, PAL_MODE_INPUT_PULLUP);
|
||||
|
||||
// Start the SPI peripheral
|
||||
spiStart(&SPID1, &spicfg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline bool_t getpin_pressed(GMouse* m)
|
||||
{
|
||||
(void) m;
|
||||
|
||||
return (!palReadPad(GPIOC, 4));
|
||||
}
|
||||
|
||||
static inline void aquire_bus(GMouse* m)
|
||||
{
|
||||
(void) m;
|
||||
|
||||
spiAcquireBus(&SPID1);
|
||||
palClearPad(GPIOC, 6);
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m)
|
||||
{
|
||||
(void) m;
|
||||
|
||||
palSetPad(GPIOC, 6);
|
||||
spiReleaseBus(&SPID1);
|
||||
}
|
||||
|
||||
static inline uint16_t read_value(GMouse* m, uint16_t port)
|
||||
{
|
||||
static uint8_t txbuf[3] = {0};
|
||||
static uint8_t rxbuf[3] = {0};
|
||||
uint16_t ret;
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = port;
|
||||
|
||||
spiExchange(&SPID1, 3, txbuf, rxbuf);
|
||||
|
||||
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* 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 drivers/ginput/touch/FT5x06/ginput_lld_mouse_board_marlin.h
|
||||
* @brief GINPUT Touch low level driver source for the FT5x06.
|
||||
*
|
||||
* @defgroup Mouse Mouse
|
||||
* @ingroup GINPUT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
/* I2C interface #2 - Touchscreen controller */
|
||||
static const I2CConfig i2ccfg2 = {
|
||||
OPMODE_I2C,
|
||||
400000,
|
||||
FAST_DUTY_CYCLE_2,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialise the board for the touch.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void init_board(void) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write a value into a certain register
|
||||
*
|
||||
* @param[in] reg The register address
|
||||
* @param[in] n The amount of bytes (one or two)
|
||||
* @param[in] val The value
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void write_reg(uint8_t reg, uint8_t n, uint16_t val) {
|
||||
uint8_t txbuf[3];
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
|
||||
txbuf[0] = reg;
|
||||
|
||||
if (n == 1) {
|
||||
txbuf[1] = val;
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, txbuf, 2, 0, 0, MS2ST(FT5x06_TIMEOUT));
|
||||
} else if (n == 2) {
|
||||
txbuf[1] = ((val & 0xFF00) >> 8);
|
||||
txbuf[2] = (val & 0x00FF);
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, txbuf, 3, 0, 0, MS2ST(FT5x06_TIMEOUT));
|
||||
}
|
||||
|
||||
i2cReleaseBus(&I2CD2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the value of a certain register
|
||||
*
|
||||
* @param[in] reg The register address
|
||||
* @param[in] n The amount of bytes (one or two)
|
||||
*
|
||||
* @return Data read from device (one byte or two depending on n param)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static uint16_t read_reg(uint8_t reg, uint8_t n) {
|
||||
uint8_t txbuf[1], rxbuf[2];
|
||||
uint16_t ret;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
rxbuf[1] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
|
||||
txbuf[0] = reg;
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, txbuf, 1, rxbuf, n, MS2ST(FT5x06_TIMEOUT));
|
||||
|
||||
if (n == 1) {
|
||||
ret = rxbuf[0];
|
||||
} else if (n == 2) {
|
||||
ret = ((rxbuf[0] << 8) | (rxbuf[1] & 0xFF));
|
||||
}
|
||||
|
||||
i2cReleaseBus(&I2CD2);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void read_reg_n(uint8_t reg, uint8_t n, uint8_t *rxbuf) {
|
||||
uint8_t txbuf[1];
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
|
||||
txbuf[0] = reg;
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, txbuf, 1, rxbuf, n, MS2ST(FT5x06_TIMEOUT));
|
||||
|
||||
i2cReleaseBus(&I2CD2);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
/** @} */
|
||||
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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 drivers/ginput/touch/STMPE811/ginput_lld_mouse_config.h
|
||||
* @brief GINPUT LLD header file for mouse/touch driver.
|
||||
*
|
||||
* @defgroup Mouse Mouse
|
||||
* @ingroup GINPUT
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 15
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 5
|
||||
#define GINPUT_MOUSE_CLICK_TIME 450
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
/** @} */
|
93
boards/base/Marlin/gmouse_lld_FT5x06_board.h
Normal file
93
boards/base/Marlin/gmouse_lld_FT5x06_board.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_FT5x06_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_FT5x06_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_FT5x06_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_FT5x06_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_FT5x06_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_FT5x06_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_FT5x06_BOARD_DATA_SIZE 0
|
||||
|
||||
// Set this to TRUE if you want self-calibration.
|
||||
// NOTE: This is not as accurate as real calibration.
|
||||
// It requires the orientation of the touch panel to match the display.
|
||||
// It requires the active area of the touch panel to exactly match the display size.
|
||||
#define GMOUSE_FT5x06_SELF_CALIBRATE FALSE
|
||||
|
||||
/* I2C interface #2 - Touchscreen controller */
|
||||
static const I2CConfig i2ccfg2 = {
|
||||
OPMODE_I2C,
|
||||
400000,
|
||||
FAST_DUTY_CYCLE_2,
|
||||
};
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
// We only support one of these on this board
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) {
|
||||
uint8_t txbuf[2];
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = reg;
|
||||
txbuf[1] = val;
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, txbuf, 2, 0, 0, MS2ST(FT5x06_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD2);
|
||||
}
|
||||
|
||||
static uint8_t read_byte(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[1];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, ®, 1, rxbuf, 1, MS2ST(FT5x06_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD2);
|
||||
|
||||
return rxbuf[0];
|
||||
}
|
||||
|
||||
static uint16_t read_word(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[2];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
rxbuf[1] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD2);
|
||||
i2cMasterTransmitTimeout(&I2CD2, FT5x06_ADDR, ®, 1, rxbuf, 2, MS2ST(FT5x06_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD2);
|
||||
|
||||
return (((uint16_t)rxbuf[0]) << 8) | rxbuf[1];
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
#define ADC_NUM_CHANNELS 2
|
||||
#define ADC_BUF_DEPTH 1
|
||||
|
||||
static const ADCConversionGroup adcgrpcfg = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
/* HW dependent part.*/
|
||||
0,
|
||||
ADC_CR2_SWSTART,
|
||||
0,
|
||||
0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN8) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN9)
|
||||
};
|
||||
|
||||
static inline void init_board(void) {
|
||||
adcStart(&ADCD1, 0);
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(void) {
|
||||
}
|
||||
|
||||
static inline void setup_x(void) {
|
||||
palSetPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
|
||||
static inline void setup_y(void) {
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palSetPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
|
||||
static inline void setup_z(void) {
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
|
||||
static inline uint16_t read_x(void) {
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
return samples[1];
|
||||
}
|
||||
|
||||
static inline uint16_t read_y(void) {
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
return samples[0];
|
||||
}
|
||||
|
||||
static inline uint16_t read_z(void) {
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
// z will go from ~200 to ~4000 when pressed
|
||||
// auto range this back to 0 to 100
|
||||
if (samples[0] > 4000)
|
||||
return 100;
|
||||
if (samples[0] < 400)
|
||||
return 0;
|
||||
return (samples[0] - 400) / ((4000-400)/100);
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GMOUSE_MCU_BOARD_H
|
||||
#define _LLD_GMOUSE_MCU_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_MCU_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_MCU_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_MCU_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_MCU_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_MCU_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_MCU_FINGER_MOVE_ERROR 14
|
||||
#define GMOUSE_MCU_Z_MIN 0
|
||||
#define GMOUSE_MCU_Z_MAX 4095
|
||||
#define GMOUSE_MCU_Z_TOUCHON 3090
|
||||
#define GMOUSE_MCU_Z_TOUCHOFF 400
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_MCU_BOARD_DATA_SIZE 0
|
||||
|
||||
#define ADC_NUM_CHANNELS 2
|
||||
#define ADC_BUF_DEPTH 1
|
||||
|
||||
static const ADCConversionGroup adcgrpcfg = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
/* HW dependent part.*/
|
||||
0,
|
||||
ADC_CR2_SWSTART,
|
||||
0,
|
||||
0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN8) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN9)
|
||||
};
|
||||
|
||||
static bool_t init_board(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
// Only one touch interface on this board
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
adcStart(&ADCD1, 0);
|
||||
|
||||
// Set up for reading Z
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(1); // Settling time
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t read_xyz(GMouse *m, GMouseReading *prd) {
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
(void) m;
|
||||
|
||||
// No buttons
|
||||
prd->buttons = 0;
|
||||
|
||||
// Get the z reading (assumes we are ready to read z)
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
prd->z = samples[0];
|
||||
|
||||
// Take a shortcut and don't read x, y if we know we are definitely not touched.
|
||||
if (prd->z >= GMOUSE_MCU_Z_TOUCHOFF) {
|
||||
|
||||
// Get the x reading
|
||||
palSetPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
prd->x = samples[1];
|
||||
|
||||
// Get the y reading
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palSetPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
adcConvert(&ADCD1, &adcgrpcfg, samples, ADC_BUF_DEPTH);
|
||||
prd->y = samples[0];
|
||||
|
||||
// Set up for reading z again. We know it will be 20ms before we get called again so don't worry about settling time
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* _LLD_GMOUSE_MCU_BOARD_H */
|
@ -1,126 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
#define ADC_NUM_CHANNELS 2
|
||||
#define ADC_BUF_DEPTH 1
|
||||
|
||||
static const ADCConversionGroup adc_y_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
|
||||
};
|
||||
|
||||
static const ADCConversionGroup adc_x_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
|
||||
};
|
||||
|
||||
static inline void init_board(void) {
|
||||
adcStart(&ADCD1, 0);
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline void setup_x(void) {
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(GPIOC, 2);
|
||||
palClearPad(GPIOC, 3);
|
||||
gfxSleepMilliseconds(1);
|
||||
}
|
||||
|
||||
static inline void setup_y(void) {
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(GPIOC, 1);
|
||||
palClearPad(GPIOC, 0);
|
||||
gfxSleepMilliseconds(1);
|
||||
}
|
||||
|
||||
static inline void setup_z(void) {
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_PULLDOWN);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT);
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_INPUT);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPad(GPIOC, 3);
|
||||
}
|
||||
|
||||
static inline uint16_t read_x(void) {
|
||||
uint16_t val1, val2;
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
palSetPad(GPIOC, 2);
|
||||
palClearPad(GPIOC, 3);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(GPIOC, 2);
|
||||
palSetPad(GPIOC, 3);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
return ((val1+((1<<12)-val2))/4);
|
||||
}
|
||||
|
||||
static inline uint16_t read_y(void) {
|
||||
uint16_t val1, val2;
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
|
||||
palSetPad(GPIOC, 1);
|
||||
palClearPad(GPIOC, 0);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(GPIOC, 1);
|
||||
palSetPad(GPIOC, 0);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
return ((val1+((1<<12)-val2))/4);
|
||||
}
|
||||
|
||||
static inline uint16_t read_z(void) {
|
||||
if (palReadPad(GPIOC, 0))
|
||||
return 100;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
||||
|
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
||||
|
136
boards/base/Olimex-STM32-LCD/gmouse_lld_MCU_board.h
Normal file
136
boards/base/Olimex-STM32-LCD/gmouse_lld_MCU_board.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GMOUSE_MCU_BOARD_H
|
||||
#define _LLD_GMOUSE_MCU_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_MCU_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_MCU_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_MCU_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_MCU_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_MCU_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_MCU_FINGER_MOVE_ERROR 14
|
||||
#define GMOUSE_MCU_Z_MIN 0
|
||||
#define GMOUSE_MCU_Z_MAX 1
|
||||
#define GMOUSE_MCU_Z_TOUCHON 1
|
||||
#define GMOUSE_MCU_Z_TOUCHOFF 0
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_MCU_BOARD_DATA_SIZE 0
|
||||
|
||||
#define ADC_NUM_CHANNELS 2
|
||||
#define ADC_BUF_DEPTH 1
|
||||
|
||||
static const ADCConversionGroup adc_y_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
|
||||
};
|
||||
|
||||
static const ADCConversionGroup adc_x_config = {
|
||||
FALSE,
|
||||
ADC_NUM_CHANNELS,
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
|
||||
0,
|
||||
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
|
||||
};
|
||||
|
||||
static inline void setup_z(void) {
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_PULLDOWN);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT);
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_INPUT);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPad(GPIOC, 3);
|
||||
}
|
||||
|
||||
static bool_t init_board(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
// Only one touch interface on this board
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
adcStart(&ADCD1, 0);
|
||||
|
||||
// Set up for reading Z
|
||||
setup_z();
|
||||
chThdSleepMilliseconds(1); // Settling time
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t read_xyz(GMouse *m, GMouseReading *prd) {
|
||||
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
|
||||
uint16_t val1, val2;
|
||||
(void) m;
|
||||
|
||||
// No buttons and assume touch off
|
||||
prd->buttons = 0;
|
||||
prd->z = 0;
|
||||
|
||||
// Get the z reading (assumes we are ready to read z)
|
||||
// Take a shortcut and don't read x, y if we know we are definitely not touched.
|
||||
if (palReadPad(GPIOC, 0)) {
|
||||
prd->z = 1;
|
||||
|
||||
// Get the x reading - Weird but it works. Optimize later.
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(GPIOC, 2);
|
||||
palClearPad(GPIOC, 3);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(GPIOC, 2);
|
||||
palSetPad(GPIOC, 3);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_x_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
prd->x = ((val1+((1<<12)-val2))/4);
|
||||
|
||||
// Get the y reading - Weird but it works. Optimize later.
|
||||
palSetPadMode(GPIOC, 2, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 3, PAL_MODE_INPUT_ANALOG);
|
||||
palSetPadMode(GPIOC, 0, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
palSetPadMode(GPIOC, 1, PAL_MODE_OUTPUT_PUSHPULL);
|
||||
|
||||
palSetPad(GPIOC, 1);
|
||||
palClearPad(GPIOC, 0);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val1 = ((samples[0] + samples[1])/2);
|
||||
|
||||
palClearPad(GPIOC, 1);
|
||||
palSetPad(GPIOC, 0);
|
||||
gfxSleepMilliseconds(1);
|
||||
adcConvert(&ADCD1, &adc_y_config, samples, ADC_BUF_DEPTH);
|
||||
val2 = ((samples[0] + samples[1])/2);
|
||||
|
||||
prd->y = ((val1+((1<<12)-val2))/4);
|
||||
|
||||
// Set up for reading z again. We know it will be 20ms before we get called again so don't worry about settling time
|
||||
setup_z();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* _LLD_GMOUSE_MCU_BOARD_H */
|
@ -4,5 +4,4 @@ GFXSRC += $(GFXLIB)/boards/base/STM32F429i-Discovery/stm32f429i_discovery_sdram
|
||||
|
||||
GFXDEFS += -DGFX_USE_OS_CHIBIOS=TRUE
|
||||
include $(GFXLIB)/drivers/gdisp/STM32F429iDiscovery/driver.mk
|
||||
#include $(GFXLIB)/drivers/ginput/touch/MCU/driver.mk
|
||||
#include $(GFXLIB)/drivers/gaudio/vs1053/driver.mk
|
||||
include $(GFXLIB)/drivers/ginput/touch/STMPE811/driver.mk
|
||||
|
@ -76,7 +76,7 @@
|
||||
* @brief Enables the I2C subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2C FALSE
|
||||
#define HAL_USE_I2C TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -138,7 +138,7 @@
|
||||
*/
|
||||
#define STM32_I2C_USE_I2C1 FALSE
|
||||
#define STM32_I2C_USE_I2C2 FALSE
|
||||
#define STM32_I2C_USE_I2C3 FALSE
|
||||
#define STM32_I2C_USE_I2C3 TRUE
|
||||
#define STM32_I2C_I2C1_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 0)
|
||||
#define STM32_I2C_I2C1_TX_DMA_STREAM STM32_DMA_STREAM_ID(1, 6)
|
||||
#define STM32_I2C_I2C2_RX_DMA_STREAM STM32_DMA_STREAM_ID(1, 2)
|
||||
|
120
boards/base/STM32F429i-Discovery/gmouse_lld_STMPE811_board.h
Normal file
120
boards/base/STM32F429i-Discovery/gmouse_lld_STMPE811_board.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_STMPE811_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_STMPE811_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_STMPE811_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_STMPE811_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_STMPE811_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_STMPE811_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_STMPE811_BOARD_DATA_SIZE 0
|
||||
|
||||
// Options - Leave these commented to make it user configurable in the gfxconf.h
|
||||
//#define GMOUSE_STMPE811_READ_PRESSURE FALSE
|
||||
//#define GMOUSE_STMPE811_SELF_CALIBRATE FALSE
|
||||
//#define GMOUSE_STMPE811_TEST_MODE FALSE
|
||||
|
||||
// Set to FALSE because it does not work properly on this board even though the pin exists.
|
||||
#define GMOUSE_STMPE811_GPIO_IRQPIN FALSE
|
||||
|
||||
// If TRUE this is a really slow CPU and we should always clear the FIFO between reads.
|
||||
#define GMOUSE_STMPE811_SLOW_CPU FALSE
|
||||
|
||||
// Slave address
|
||||
#define STMPE811_ADDR 0x41
|
||||
|
||||
// Maximum timeout
|
||||
#define STMPE811_TIMEOUT 0x3000
|
||||
|
||||
static const I2CConfig i2ccfg = {
|
||||
OPMODE_I2C,
|
||||
400000,
|
||||
FAST_DUTY_CYCLE_2,
|
||||
};
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
|
||||
// This board only supports one touch panel
|
||||
if (driverinstance)
|
||||
return FALSE;
|
||||
|
||||
// Set pin modes
|
||||
palSetPadMode(GPIOA, 15, PAL_MODE_INPUT | PAL_STM32_PUDR_FLOATING); /* TP IRQ */
|
||||
palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SCL */
|
||||
palSetPadMode(GPIOC, 9, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); /* SDA */
|
||||
|
||||
// Start the I2C
|
||||
i2cStart(&I2CD3, &i2ccfg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
static bool_t getpin_irq(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
return !palReadPad(GPIOA, 15);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
(void) m;
|
||||
|
||||
}
|
||||
|
||||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) {
|
||||
uint8_t txbuf[2];
|
||||
(void) m;
|
||||
|
||||
txbuf[0] = reg;
|
||||
txbuf[1] = val;
|
||||
|
||||
i2cAcquireBus(&I2CD3);
|
||||
i2cMasterTransmitTimeout(&I2CD3, STMPE811_ADDR, txbuf, 2, 0, 0, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD3);
|
||||
}
|
||||
|
||||
static uint8_t read_byte(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[1];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD3);
|
||||
i2cMasterTransmitTimeout(&I2CD3, STMPE811_ADDR, ®, 1, rxbuf, 1, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD3);
|
||||
|
||||
return rxbuf[0];
|
||||
}
|
||||
|
||||
static uint16_t read_word(GMouse* m, uint8_t reg) {
|
||||
uint8_t rxbuf[2];
|
||||
(void) m;
|
||||
|
||||
rxbuf[0] = 0;
|
||||
rxbuf[1] = 0;
|
||||
|
||||
i2cAcquireBus(&I2CD3);
|
||||
i2cMasterTransmitTimeout(&I2CD3, STMPE811_ADDR, ®, 1, rxbuf, 2, MS2ST(STMPE811_TIMEOUT));
|
||||
i2cReleaseBus(&I2CD3);
|
||||
|
||||
return (((uint16_t)rxbuf[0]) << 8) | rxbuf[1];
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -39,7 +39,7 @@ static void createWidgets(void) {
|
||||
gwinWidgetClearInit(&wi);
|
||||
wi.g.show = TRUE;
|
||||
|
||||
// Apply the button parameters
|
||||
// Apply the button parameters
|
||||
wi.g.width = 100;
|
||||
wi.g.height = 30;
|
||||
wi.g.y = 10;
|
||||
@ -67,9 +67,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -39,14 +39,14 @@ static void createWidgets(void) {
|
||||
gwinWidgetClearInit(&wi);
|
||||
wi.g.show = TRUE;
|
||||
|
||||
// Apply the checkbox parameters
|
||||
// Apply the checkbox parameters
|
||||
wi.g.width = 100; // includes text
|
||||
wi.g.height = 20;
|
||||
wi.g.y = 10;
|
||||
wi.g.x = 10;
|
||||
wi.text = "Checkbox";
|
||||
|
||||
// Create the actual checkbox
|
||||
// Create the actual checkbox
|
||||
ghCheckbox1 = gwinCheckboxCreate(0, &wi);
|
||||
}
|
||||
|
||||
@ -61,9 +61,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -19,7 +19,7 @@ static void createWidgets(void) {
|
||||
ghContainer = gwinContainerCreate(0, &wi, GWIN_CONTAINER_BORDER);
|
||||
wi.g.show = TRUE;
|
||||
|
||||
// Apply the button parameters
|
||||
// Apply the button parameters
|
||||
wi.g.width = 120;
|
||||
wi.g.height = 30;
|
||||
wi.g.y = 10;
|
||||
@ -37,9 +37,6 @@ int main(void) {
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// Set the widget defaults
|
||||
gwinSetDefaultFont(gdispOpenFont("*"));
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
|
@ -40,7 +40,7 @@ static void createWidgets(void) {
|
||||
wi.text = "Container 3";
|
||||
ghContainer3 = gwinContainerCreate(0, &wi, GWIN_CONTAINER_BORDER);
|
||||
|
||||
// Button 1
|
||||
// Button 1
|
||||
wi.g.width = 80;
|
||||
wi.g.height = 20;
|
||||
wi.g.y = 10;
|
||||
@ -49,7 +49,7 @@ static void createWidgets(void) {
|
||||
wi.g.parent = ghContainer2;
|
||||
ghButton1 = gwinButtonCreate(0, &wi);
|
||||
|
||||
// Button 2
|
||||
// Button 2
|
||||
wi.g.width = 80;
|
||||
wi.g.height = 20;
|
||||
wi.g.y = 40;
|
||||
@ -58,7 +58,7 @@ static void createWidgets(void) {
|
||||
wi.g.parent = ghContainer2;
|
||||
ghButton2 = gwinButtonCreate(0, &wi);
|
||||
|
||||
// Button 3
|
||||
// Button 3
|
||||
wi.g.width = 80;
|
||||
wi.g.height = 20;
|
||||
wi.g.y = 10;
|
||||
@ -67,7 +67,7 @@ static void createWidgets(void) {
|
||||
wi.g.parent = ghContainer3;
|
||||
ghButton3 = gwinButtonCreate(0, &wi);
|
||||
|
||||
// Button 4
|
||||
// Button 4
|
||||
wi.g.width = 80;
|
||||
wi.g.height = 20;
|
||||
wi.g.y = 40;
|
||||
@ -115,9 +115,6 @@ int main(void) {
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// Set the widget defaults
|
||||
gwinSetDefaultFont(gdispOpenFont("*"));
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
|
@ -33,7 +33,7 @@ static void _createWidgets(void) {
|
||||
wi.text = "Surprise!";
|
||||
gwinLabelCreate(0, &wi);
|
||||
|
||||
// Apply the frame parameters
|
||||
// Apply the frame parameters
|
||||
wi.g.width = 300;
|
||||
wi.g.height = 200;
|
||||
wi.g.y = 10;
|
||||
@ -107,7 +107,7 @@ static void _createWidgets(void) {
|
||||
wi.g.x = 10;
|
||||
wi.g.y = 90;
|
||||
ghWindow1 = gwinWindowCreate(0, &wi.g);
|
||||
|
||||
|
||||
_updateColor();
|
||||
}
|
||||
|
||||
@ -117,9 +117,6 @@ int main(void) {
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// Set the widget defaults
|
||||
gwinSetDefaultFont(gdispOpenFont("*"));
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
|
@ -63,9 +63,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -79,9 +79,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -83,9 +83,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -59,9 +59,6 @@ int main(void) {
|
||||
gwinSetDefaultStyle(&WhiteWidgetStyle, FALSE);
|
||||
gdispClear(White);
|
||||
|
||||
// Attach the mouse input
|
||||
gwinAttachMouse(0);
|
||||
|
||||
// create the widget
|
||||
createWidgets();
|
||||
|
||||
|
@ -418,11 +418,6 @@ int main(void) {
|
||||
// Initialize the display
|
||||
gfxInit();
|
||||
|
||||
// Connect the mouse
|
||||
#if GINPUT_NEED_MOUSE
|
||||
gwinAttachMouse(0);
|
||||
#endif
|
||||
|
||||
// Set the widget defaults
|
||||
font = gdispOpenFont("*"); // Get the first defined font.
|
||||
gwinSetDefaultFont(font);
|
||||
|
@ -32,6 +32,10 @@ FEATURE: Added transparent custom draws for GWIN containers and frame widgets
|
||||
FEATURE: Added image custom draws for GWIN containers and frame widgets
|
||||
FEATURE: Added GDRIVER infrastructure. Ported GDISP to use it.
|
||||
FEATURE: Added gdispDrawArcSectors() and gdispFillArcSectors().
|
||||
FEATURE: Ported GINPUT MOUSE to GDRIVER infrastructure.
|
||||
FEATURE: Mouse/Touch now support both pen and finger mode.
|
||||
DEPRECATE: gwinAttachMouse() is now handled automaticly.
|
||||
FEATURE: Added MAX11802 touch driver by user steved
|
||||
|
||||
|
||||
*** Release 2.1 ***
|
||||
|
@ -1,5 +1,2 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/ADS7843
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/ADS7843/gmouse_lld_ADS7843.c
|
||||
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
|
||||
#if defined(GINPUT_MOUSE_YX_INVERTED) && GINPUT_MOUSE_YX_INVERTED
|
||||
#define CMD_X 0x91
|
||||
#define CMD_Y 0xD1
|
||||
#else
|
||||
#define CMD_X 0xD1
|
||||
#define CMD_Y 0x91
|
||||
#endif
|
||||
|
||||
|
||||
static uint16_t sampleBuf[7];
|
||||
static coord_t lastx, lasty;
|
||||
|
||||
static void filter(void) {
|
||||
uint16_t temp;
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = i; j < 7; j++) {
|
||||
if(sampleBuf[i] > sampleBuf[j]) {
|
||||
/* Swap the values */
|
||||
temp = sampleBuf[i];
|
||||
sampleBuf[i] = sampleBuf[j];
|
||||
sampleBuf[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_init(void) {
|
||||
init_board();
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
uint16_t i;
|
||||
|
||||
// If touch-off return the previous results
|
||||
if (!getpin_pressed()) {
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 0;
|
||||
pt->buttons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the port to get the touch settings
|
||||
aquire_bus();
|
||||
|
||||
/* Get the X value
|
||||
* Discard the first conversion - very noisy and keep the ADC on hereafter
|
||||
* till we are done with the sampling. Note that PENIRQ is disabled while reading.
|
||||
* Finally switch on PENIRQ once again - perform a dummy read.
|
||||
* Once we have the readings, find the medium using our filter function
|
||||
*/
|
||||
read_value(CMD_X);
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_value(CMD_X);
|
||||
read_value(CMD_X-1);
|
||||
filter();
|
||||
lastx = (coord_t)sampleBuf[3];
|
||||
|
||||
/* Get the Y value using the same process as above */
|
||||
read_value(CMD_Y);
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_value(CMD_Y);
|
||||
read_value(CMD_Y-1);
|
||||
filter();
|
||||
lasty = (coord_t)sampleBuf[3];
|
||||
|
||||
// Release the bus
|
||||
release_bus();
|
||||
|
||||
// Return the results
|
||||
pt->x = lastx;
|
||||
pt->y = lasty;
|
||||
pt->z = 100;
|
||||
pt->buttons = GINPUT_TOUCH_PRESSED;
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static inline void init_board(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline bool_t getpin_pressed(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline uint16_t read_value(uint16_t port) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 5
|
||||
#define GINPUT_MOUSE_READ_CYCLES 4
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
80
drivers/ginput/touch/ADS7843/gmouse_lld_ADS7843.c
Normal file
80
drivers/ginput/touch/ADS7843/gmouse_lld_ADS7843.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE)
|
||||
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_ADS7843
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Get the hardware interface
|
||||
#include "gmouse_lld_ADS7843_board.h"
|
||||
|
||||
#define CMD_X 0xD1
|
||||
#define CMD_Y 0x91
|
||||
#define CMD_ENABLE_IRQ 0x80
|
||||
|
||||
static bool_t MouseXYZ(GMouse* m, GMouseReading* pdr)
|
||||
{
|
||||
(void)m;
|
||||
|
||||
// No buttons
|
||||
pdr->buttons = 0;
|
||||
pdr->z = 0;
|
||||
|
||||
if (getpin_pressed(m)) {
|
||||
pdr->z = 1; // Set to Z_MAX as we are pressed
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
read_value(m, CMD_X); // Dummy read - disable PenIRQ
|
||||
pdr->x = read_value(m, CMD_X); // Read X-Value
|
||||
|
||||
read_value(m, CMD_Y); // Dummy read - disable PenIRQ
|
||||
pdr->y = read_value(m, CMD_Y); // Read Y-Value
|
||||
|
||||
read_value(m, CMD_ENABLE_IRQ); // Enable IRQ
|
||||
|
||||
release_bus(m);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_TOUCH,
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_CALIBRATE | GMOUSE_VFLG_CAL_TEST |
|
||||
GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN,
|
||||
sizeof(GMouse)+BOARD_DATA_SIZE,
|
||||
_gmouseInitDriver,
|
||||
_gmousePostInitDriver,
|
||||
_gmouseDeInitDriver
|
||||
},
|
||||
1, // z_max - (currently?) not supported
|
||||
0, // z_min - (currently?) not supported
|
||||
1, // z_touchon
|
||||
0, // z_touchoff
|
||||
{ // pen_jitter
|
||||
GMOUSE_ADS7843_PEN_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_ADS7843_PEN_CLICK_ERROR, // click
|
||||
GMOUSE_ADS7843_PEN_MOVE_ERROR // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
GMOUSE_ADS7843_FINGER_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_ADS7843_FINGER_CLICK_ERROR, // click
|
||||
GMOUSE_ADS7843_FINGER_MOVE_ERROR // move
|
||||
},
|
||||
init_board, // init
|
||||
0, // deinit
|
||||
MouseXYZ, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
||||
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_ADS7843_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_ADS7843_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_ADS7843_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_ADS7843_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_ADS7843_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_ADS7843_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_ADS7843_BOARD_DATA_SIZE 0
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
|
||||
}
|
||||
|
||||
static inline bool_t getpin_pressed(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
static inline uint16_t read_value(GMouse* m, uint16_t port) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,5 +1,2 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/FT5x06/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/FT5x06
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/FT5x06/gmouse_lld_FT5x06.c
|
||||
|
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include "drivers/ginput/touch/FT5x06/ft5x06.h"
|
||||
|
||||
// include board abstraction
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
|
||||
static coord_t x, y, z;
|
||||
static uint8_t touched;
|
||||
|
||||
void ginput_lld_mouse_init(void) {
|
||||
init_board();
|
||||
|
||||
// Init default values. (From NHD-3.5-320240MF-ATXL-CTP-1 datasheet)
|
||||
// Valid touching detect threshold
|
||||
write_reg(FT5x06_ID_G_THGROUP, 1, 0x16);
|
||||
|
||||
// valid touching peak detect threshold
|
||||
write_reg(FT5x06_ID_G_THPEAK, 1, 0x3C);
|
||||
|
||||
// Touch focus threshold
|
||||
write_reg(FT5x06_ID_G_THCAL, 1, 0xE9);
|
||||
|
||||
// threshold when there is surface water
|
||||
write_reg(FT5x06_ID_G_THWATER, 1, 0x01);
|
||||
|
||||
// threshold of temperature compensation
|
||||
write_reg(FT5x06_ID_G_THTEMP, 1, 0x01);
|
||||
|
||||
// Touch difference threshold
|
||||
write_reg(FT5x06_ID_G_THDIFF, 1, 0xA0);
|
||||
|
||||
// Delay to enter 'Monitor' status (s)
|
||||
write_reg(FT5x06_ID_G_TIME_ENTER_MONITOR, 1, 0x0A);
|
||||
|
||||
// Period of 'Active' status (ms)
|
||||
write_reg(FT5x06_ID_G_PERIODACTIVE, 1, 0x06);
|
||||
|
||||
// Timer to enter ÔidleÕ when in 'Monitor' (ms)
|
||||
write_reg(FT5x06_ID_G_PERIODMONITOR, 1, 0x28);
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
// Poll to get the touched status
|
||||
uint8_t last_touched;
|
||||
|
||||
last_touched = touched;
|
||||
touched = (uint8_t)read_reg(FT5x06_TOUCH_POINTS, 1) & 0x07;
|
||||
|
||||
// If not touched, return the previous results
|
||||
if (touched == 0) {
|
||||
pt->x = x;
|
||||
pt->y = y;
|
||||
pt->z = 0;
|
||||
pt->buttons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the X, Y, Z values */
|
||||
x = (coord_t)(read_reg(FT5x06_TOUCH1_XH, 2) & 0x0fff);
|
||||
y = (coord_t)read_reg(FT5x06_TOUCH1_YH, 2);
|
||||
z = 100;
|
||||
|
||||
// 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
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static void init_board(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline bool_t getpin_irq(void) {
|
||||
|
||||
}
|
||||
|
||||
static void write_reg(uint8_t reg, uint8_t n, uint16_t val) {
|
||||
|
||||
}
|
||||
|
||||
static uint16_t read_reg(uint8_t reg, uint8_t n) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 15
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 5
|
||||
#define GINPUT_MOUSE_CLICK_TIME 450
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
121
drivers/ginput/touch/FT5x06/gmouse_lld_FT5x06.c
Normal file
121
drivers/ginput/touch/FT5x06/gmouse_lld_FT5x06.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_FT5x06
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Get the hardware interface
|
||||
#include "gmouse_lld_FT5x06_board.h"
|
||||
|
||||
// Hardware definitions
|
||||
#include "drivers/ginput/touch/FT5x06/ft5x06.h"
|
||||
|
||||
static bool_t MouseInit(GMouse* m, unsigned driverinstance) {
|
||||
if (!init_board(m, driverinstance))
|
||||
return FALSE;
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
// Init default values. (From NHD-3.5-320240MF-ATXL-CTP-1 datasheet)
|
||||
// Valid touching detect threshold
|
||||
write_reg(m, FT5x06_ID_G_THGROUP, 0x16);
|
||||
|
||||
// valid touching peak detect threshold
|
||||
write_reg(m, FT5x06_ID_G_THPEAK, 0x3C);
|
||||
|
||||
// Touch focus threshold
|
||||
write_reg(m, FT5x06_ID_G_THCAL, 0xE9);
|
||||
|
||||
// threshold when there is surface water
|
||||
write_reg(m, FT5x06_ID_G_THWATER, 0x01);
|
||||
|
||||
// threshold of temperature compensation
|
||||
write_reg(m, FT5x06_ID_G_THTEMP, 0x01);
|
||||
|
||||
// Touch difference threshold
|
||||
write_reg(m, FT5x06_ID_G_THDIFF, 0xA0);
|
||||
|
||||
// Delay to enter 'Monitor' status (s)
|
||||
write_reg(m, FT5x06_ID_G_TIME_ENTER_MONITOR, 0x0A);
|
||||
|
||||
// Period of 'Active' status (ms)
|
||||
write_reg(m, FT5x06_ID_G_PERIODACTIVE, 0x06);
|
||||
|
||||
// Timer to enter 'idle' when in 'Monitor' (ms)
|
||||
write_reg(m, FT5x06_ID_G_PERIODMONITOR, 0x28);
|
||||
|
||||
release_bus(m);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t MouseXYZ(GMouse* m, GMouseReading* pdr)
|
||||
{
|
||||
// Assume not touched.
|
||||
pdr->buttons = 0;
|
||||
pdr->z = 0;
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
// Only take a reading if we are touched.
|
||||
if ((read_byte(m, FT5x06_TOUCH_POINTS) & 0x07)) {
|
||||
|
||||
/* Get the X, Y, Z values */
|
||||
pdr->x = (coord_t)(read_word(m, FT5x06_TOUCH1_XH) & 0x0fff);
|
||||
pdr->y = (coord_t)read_word(m, FT5x06_TOUCH1_YH);
|
||||
pdr->z = 1;
|
||||
|
||||
#if GMOUSE_FT5x06_SELF_CALIBRATE
|
||||
// Rescale X,Y,Z - If we are using self-calibration
|
||||
pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
|
||||
pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
|
||||
#endif
|
||||
}
|
||||
|
||||
release_bus(m);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_TOUCH,
|
||||
#if GMOUSE_FT5x06_SELF_CALIBRATE
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN,
|
||||
#else
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN | GMOUSE_VFLG_CALIBRATE | GMOUSE_VFLG_CAL_TEST,
|
||||
#endif
|
||||
sizeof(GMouse) + GMOUSE_FT5x06_BOARD_DATA_SIZE,
|
||||
_gmouseInitDriver,
|
||||
_gmousePostInitDriver,
|
||||
_gmouseDeInitDriver
|
||||
},
|
||||
1, // z_max - (currently?) not supported
|
||||
0, // z_min - (currently?) not supported
|
||||
1, // z_touchon
|
||||
0, // z_touchoff
|
||||
{ // pen_jitter
|
||||
GMOUSE_FT5x06_PEN_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_FT5x06_PEN_CLICK_ERROR, // click
|
||||
GMOUSE_FT5x06_PEN_MOVE_ERROR // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
GMOUSE_FT5x06_FINGER_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_FT5x06_FINGER_CLICK_ERROR, // click
|
||||
GMOUSE_FT5x06_FINGER_MOVE_ERROR // move
|
||||
},
|
||||
MouseInit, // init
|
||||
0, // deinit
|
||||
read_xyz, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_FT5x06_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_FT5x06_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_FT5x06_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_FT5x06_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_FT5x06_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_FT5x06_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_FT5x06_BOARD_DATA_SIZE 0
|
||||
|
||||
// Set this to TRUE if you want self-calibration.
|
||||
// NOTE: This is not as accurate as real calibration.
|
||||
// It requires the orientation of the touch panel to match the display.
|
||||
// It requires the active area of the touch panel to exactly match the display size.
|
||||
#define GMOUSE_FT5x06_SELF_CALIBRATE FALSE
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
}
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
}
|
||||
|
||||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) {
|
||||
}
|
||||
|
||||
static uint8_t read_byte(GMouse* m, uint8_t reg) {
|
||||
}
|
||||
|
||||
static uint16_t read_word(GMouse* m, uint8_t reg) {
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
2
drivers/ginput/touch/MAX11802/driver.mk
Normal file
2
drivers/ginput/touch/MAX11802/driver.mk
Normal file
@ -0,0 +1,2 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/MAX11802/gmouse_lld_MAX11802.c
|
189
drivers/ginput/touch/MAX11802/gmouse_lld_MAX11802.c
Normal file
189
drivers/ginput/touch/MAX11802/gmouse_lld_MAX11802.c
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_MAX11802
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Hardware definitions
|
||||
#include "drivers/ginput/touch/MAX11802/max11802.h"
|
||||
|
||||
// Get the hardware interface
|
||||
#include "gmouse_lld_MAX11802_board.h"
|
||||
|
||||
// Register values to set
|
||||
#define MAX11802_MODE 0x0E // Direct conversion with averaging
|
||||
#define MAX11802_AVG 0x55
|
||||
#define MAX11802_TIMING 0x77
|
||||
#define MAX11802_DELAY 0x55
|
||||
|
||||
#define Z_MIN 0
|
||||
#define Z_MAX 1
|
||||
|
||||
static bool_t MouseInit(GMouse* m, unsigned driverinstance)
|
||||
{
|
||||
uint8_t *p;
|
||||
|
||||
static const uint8_t commandList[] = {
|
||||
MAX11802_CMD_GEN_WR, 0xf0, // General config - leave TIRQ enabled, even though we ignore it ATM
|
||||
MAX11802_CMD_RES_WR, 0x00, // A-D resolution, hardware config - rewriting default; all 12-bit resolution
|
||||
MAX11802_CMD_AVG_WR, MAX11802_AVG, // A-D averaging - 8 samples, average four median samples
|
||||
MAX11802_CMD_SAMPLE_WR, 0x00, // A-D sample time - use default
|
||||
MAX11802_CMD_TIMING_WR, MAX11802_TIMING, // Setup timing
|
||||
MAX11802_CMD_DELAY_WR, MAX11802_DELAY, // Conversion delays
|
||||
MAX11802_CMD_TDPULL_WR, 0x00, // A-D resolution, hardware config - rewrite default
|
||||
// MAX11802_CMD_MDTIM_WR, 0x00, // Autonomous mode timing - write default - only for MAX11800, MAX11801
|
||||
// MAX11802_CMD_APCONF_WR, 0x00, // Aperture config register - rewrite default - only for MAX11800, MAX11801
|
||||
// Ignore aux config register - not used
|
||||
MAX11802_CMD_MODE_WR, MAX11802_MODE // Set mode last
|
||||
};
|
||||
|
||||
if (!init_board(m, driverinstance))
|
||||
return FALSE;
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
for (p = commandList; p < commandList+sizeof(commandList); p += 2)
|
||||
write_command(m, p[0], p[1]);
|
||||
|
||||
// Read something as a test
|
||||
if (write_command(m, MAX11802_CMD_MODE_RD, 0) != MAX11802_MODE) {
|
||||
release_bus(m);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
release_bus(m);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||
{
|
||||
uint8_t readyCount;
|
||||
uint8_t notReadyCount;
|
||||
|
||||
// Assume not touched.
|
||||
pdr->buttons = 0;
|
||||
pdr->z = 0;
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
// Start the conversion
|
||||
gfintWriteCommand(m, MAX11802_CMD_MEASUREXY); // just write command
|
||||
|
||||
/**
|
||||
* put a delay in here, since conversion will take a finite time - longer if reading Z as well
|
||||
* Potentially 1msec for 3 axes with 8us conversion time per sample, 8 samples per average
|
||||
* Note Maxim AN5435-software to do calculation (www.maximintegrated.com/design/tools/appnotes/5435/AN5435-software.zip)
|
||||
*
|
||||
* We'll just use a fixed delay to avoid too much polling/bus activity
|
||||
*/
|
||||
gfxSleepMilliseconds(2); // Was 1 - try 2
|
||||
|
||||
/* Wait for data ready
|
||||
* Note: MAX11802 signals the readiness of the results using the lowest 4 bits of the result. However, these are the
|
||||
* last bits to be read out of the device. It is possible for the hardware value to change in the middle of the read,
|
||||
* causing the analog value to still be invalid even though the tags indicate a valid result.
|
||||
*
|
||||
* We work around this by reading the registers once more after the tags indicate they are ready.
|
||||
* There's also a separate counter to guard against never getting valid readings.
|
||||
*
|
||||
* Read the two or three readings required in a single burst, swapping x and y order if necessary
|
||||
*
|
||||
* Reading Z is possible but complicated requiring two z readings, multiplication and division, various constant ratio's,
|
||||
* and interpolation in relation to the X and Y readings. It is not a simple pressure reading.
|
||||
* In other words, don't bother trying.
|
||||
*/
|
||||
|
||||
readyCount = notReadyCount = 0;
|
||||
do {
|
||||
// Get a set of readings
|
||||
gfintWriteCommand(m, MAX11802_CMD_XPOSITION);
|
||||
#if defined(GINPUT_MOUSE_YX_INVERTED) && GINPUT_MOUSE_YX_INVERTED
|
||||
pdr->y = read_value(m);
|
||||
pdr->x = read_value(m);
|
||||
#else
|
||||
pdr->x = read_value(m);
|
||||
pdr->y = read_value(m);
|
||||
#endif
|
||||
|
||||
// Test the result validity
|
||||
if (((pdr->x | pdr->y) & 0x03) == 0x03) {
|
||||
|
||||
// Has it been too long? If so give up
|
||||
if (++notReadyCount >= 5) {
|
||||
release_bus(m);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Give up the time slice to someone else and then try again
|
||||
gfxYield();
|
||||
continue;
|
||||
}
|
||||
|
||||
// We have a result but we need two valid results to believe it
|
||||
readyCount++;
|
||||
|
||||
} while (readyCount < 2);
|
||||
|
||||
release_bus(m);
|
||||
|
||||
/**
|
||||
* format of each value returned by MAX11802:
|
||||
* Bits 15..4 - analog value
|
||||
* Bits 3..2 - tag value - measurement type (X, Y, Z1, Z2)
|
||||
* Bits 1..0 - tag value - event type (00 = valid touch, 10 - no touch, 11 - measurement in progress)
|
||||
*/
|
||||
|
||||
// Was there a valid touch?
|
||||
if ((pt->x & 0x03) == 0x02) {
|
||||
pdr->z = Z_MIN;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Strip the tags
|
||||
pt->x >>= 4;
|
||||
pt->y >>= 4;
|
||||
pdr->z = Z_MAX;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_TOUCH,
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN | GMOUSE_VFLG_CALIBRATE | GMOUSE_VFLG_CAL_TEST,
|
||||
sizeof(GMouse) + GMOUSE_MAX11802_BOARD_DATA_SIZE,
|
||||
_gmouseInitDriver,
|
||||
_gmousePostInitDriver,
|
||||
_gmouseDeInitDriver
|
||||
},
|
||||
Z_MAX, // z_max
|
||||
Z_MIN, // z_min
|
||||
Z_MIN, // z_touchoff
|
||||
Z_MAX, // z_touchon
|
||||
{ // pen_jitter
|
||||
GMOUSE_MAX11802_PEN_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_MAX11802_PEN_CLICK_ERROR, // click
|
||||
GMOUSE_MAX11802_PEN_MOVE_ERROR // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
GMOUSE_MAX11802_FINGER_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_MAX11802_FINGER_CLICK_ERROR, // click
|
||||
GMOUSE_MAX11802_FINGER_MOVE_ERROR // move
|
||||
},
|
||||
MouseInit, // init
|
||||
0, // deinit
|
||||
read_xyz, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_MAX11802_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_MAX11802_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_MAX11802_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_MAX11802_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_MAX11802_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_MAX11802_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_MAX11802_BOARD_DATA_SIZE 0
|
||||
|
||||
/**
|
||||
* Init the board
|
||||
*
|
||||
* Returns TRUE on success, FALSE on failure
|
||||
*/
|
||||
static inline bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire the bus
|
||||
*/
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the bus
|
||||
*/
|
||||
static inline void release_bus(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command (with parameter) to the MAX11802
|
||||
*
|
||||
* Return the second byte read in case of interest
|
||||
*/
|
||||
static inline uint8_t write_command(GMouse* m, uint8_t command, uint8_t value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send command (no parameter) to the MAX11802
|
||||
*
|
||||
* Return the byte read in case of interest
|
||||
*/
|
||||
static inline uint8_t gfintWriteCommand(GMouse* m, uint8_t command) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Read 2 bytes as 16-bit value (command to read must have been sent previously)
|
||||
* Note: Analog value is in bits 15..4, tags (reading status) in bits 3..0
|
||||
*/
|
||||
static inline uint16_t read_value(GMouse* m) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
31
drivers/ginput/touch/MAX11802/max11802.h
Normal file
31
drivers/ginput/touch/MAX11802/max11802.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _MAX11802_H
|
||||
#define _MAX11802_H
|
||||
|
||||
#define MAX11802_CMD_XPOSITION ((0x52 << 1) | 1)
|
||||
#define MAX11802_CMD_YPOSITION ((0x54 << 1) | 1)
|
||||
#define MAX11802_CMD_ZPOSITION ((0x56 << 1) | 1)
|
||||
|
||||
// LSB of register addresses specifies read (1) or write (0)
|
||||
#define MAX11802_CMD_MEASUREXY (0x70 << 1)
|
||||
#define MAX11802_CMD_MEASUREXYZ (0x72 << 1)
|
||||
#define MAX11802_CMD_GEN_WR (0x01 << 1) // General config register
|
||||
#define MAX11802_CMD_RES_WR (0x02 << 1)
|
||||
#define MAX11802_CMD_AVG_WR (0x03 << 1)
|
||||
#define MAX11802_CMD_SAMPLE_WR (0x04 << 1)
|
||||
#define MAX11802_CMD_TIMING_WR (0x05 << 1)
|
||||
#define MAX11802_CMD_DELAY_WR (0x06 << 1)
|
||||
#define MAX11802_CMD_TDPULL_WR (0x07 << 1)
|
||||
#define MAX11802_CMD_MDTIM_WR (0x08 << 1)
|
||||
#define MAX11802_CMD_APCONF_WR (0x09 << 1)
|
||||
#define MAX11802_CMD_MODE_WR (0x0B << 1)
|
||||
#define MAX11802_CMD_MODE_RD ((0x0B << 1) | 1)
|
||||
#define MAX11802_CMD_GSR_RD ((0x00 << 1) | 1) // General status register - read-only
|
||||
|
||||
#endif /* _MAX11802_H */
|
@ -1,5 +1,2 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/MCU
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/MCU/gmouse_lld_MCU.c
|
||||
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
|
||||
static uint16_t sampleBuf[7];
|
||||
|
||||
static void filter(void) {
|
||||
uint16_t temp;
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(j = i; j < 7; j++) {
|
||||
if(sampleBuf[i] > sampleBuf[j]) {
|
||||
/* Swap the values */
|
||||
temp = sampleBuf[i];
|
||||
sampleBuf[i] = sampleBuf[j];
|
||||
sampleBuf[j] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_init(void) {
|
||||
init_board();
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
uint16_t i;
|
||||
|
||||
// Obtain access to the bus
|
||||
aquire_bus();
|
||||
|
||||
// Read the ADC for z, x, y and then z again
|
||||
while(1) {
|
||||
setup_z();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_z();
|
||||
filter();
|
||||
pt->z = (coord_t)sampleBuf[3];
|
||||
|
||||
setup_x();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_x();
|
||||
filter();
|
||||
pt->x = (coord_t)sampleBuf[3];
|
||||
|
||||
setup_y();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_y();
|
||||
filter();
|
||||
pt->y = (coord_t)sampleBuf[3];
|
||||
|
||||
pt->buttons = pt->z >= 80 ? GINPUT_TOUCH_PRESSED : 0;
|
||||
|
||||
setup_z();
|
||||
for(i = 0; i < 7; i++)
|
||||
sampleBuf[i] = read_z();
|
||||
filter();
|
||||
i = (coord_t)sampleBuf[3] >= 80 ? GINPUT_TOUCH_PRESSED : 0;
|
||||
|
||||
if (pt->buttons == i)
|
||||
break;
|
||||
}
|
||||
|
||||
// Release the bus
|
||||
release_bus();
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static inline void init_board(void) {
|
||||
}
|
||||
|
||||
static inline void aquire_bus(void) {
|
||||
}
|
||||
|
||||
static inline void release_bus(void) {
|
||||
}
|
||||
|
||||
static inline void setup_x(void) {
|
||||
}
|
||||
|
||||
static inline void setup_y(void) {
|
||||
}
|
||||
|
||||
static inline void setup_z(void) {
|
||||
palClearPad(GPIOB, GPIOB_DRIVEA);
|
||||
palClearPad(GPIOB, GPIOB_DRIVEB);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
|
||||
static inline uint16_t read_x(void) {
|
||||
}
|
||||
|
||||
static inline uint16_t read_y(void) {
|
||||
}
|
||||
|
||||
static inline uint16_t read_z(void) {
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 12
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#define GINPUT_MOUSE_CLICK_TIME 500
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
50
drivers/ginput/touch/MCU/gmouse_lld_MCU.c
Normal file
50
drivers/ginput/touch/MCU/gmouse_lld_MCU.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_MCU
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Get the hardware interface
|
||||
#include "gmouse_lld_MCU_board.h"
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_TOUCH,
|
||||
GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_TEST
|
||||
|GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN,
|
||||
// Extra flags for testing only
|
||||
//GMOUSE_VFLG_DEFAULTFINGER|GMOUSE_VFLG_CAL_EXTREMES - Possible
|
||||
//GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_CAL_LOADFREE - unlikely
|
||||
sizeof(GMouse) + GMOUSE_MCU_BOARD_DATA_SIZE,
|
||||
_gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
|
||||
},
|
||||
GMOUSE_MCU_Z_MAX, // z_max
|
||||
GMOUSE_MCU_Z_MIN, // z_min
|
||||
GMOUSE_MCU_Z_TOUCHON, // z_touchon
|
||||
GMOUSE_MCU_Z_TOUCHOFF, // z_touchoff
|
||||
{ // pen_jitter
|
||||
GMOUSE_MCU_PEN_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_MCU_PEN_CLICK_ERROR, // click
|
||||
GMOUSE_MCU_PEN_MOVE_ERROR // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
GMOUSE_MCU_FINGER_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_MCU_FINGER_CLICK_ERROR, // click
|
||||
GMOUSE_MCU_FINGER_MOVE_ERROR // move
|
||||
},
|
||||
init_board, // init
|
||||
0, // deinit
|
||||
read_xyz, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
32
drivers/ginput/touch/MCU/gmouse_lld_MCU_board_template.h
Normal file
32
drivers/ginput/touch/MCU/gmouse_lld_MCU_board_template.h
Normal file
@ -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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GMOUSE_MCU_BOARD_H
|
||||
#define _LLD_GMOUSE_MCU_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_MCU_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_MCU_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_MCU_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_MCU_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_MCU_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_MCU_FINGER_MOVE_ERROR 14
|
||||
#define GMOUSE_MCU_Z_MIN 0 // The minimum Z reading
|
||||
#define GMOUSE_MCU_Z_MAX 100 // The maximum Z reading
|
||||
#define GMOUSE_MCU_Z_TOUCHON 80 // Values between this and Z_MAX are definitely pressed
|
||||
#define GMOUSE_MCU_Z_TOUCHOFF 70 // Values between this and Z_MIN are definitely not pressed
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_MCU_BOARD_DATA_SIZE 0
|
||||
|
||||
static bool_t init_board(GMouse *m, unsigned driverinstance) {
|
||||
}
|
||||
|
||||
static bool_t read_xyz(GMouse *m, GMouseReading *prd) {
|
||||
}
|
||||
|
||||
#endif /* _LLD_GMOUSE_MCU_BOARD_H */
|
@ -1,5 +1,2 @@
|
||||
# List the required driver.
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/STMPE811/ginput_lld_mouse.c
|
||||
|
||||
# Required include directories
|
||||
GFXINC += $(GFXLIB)/drivers/ginput/touch/STMPE811
|
||||
GFXSRC += $(GFXLIB)/drivers/ginput/touch/STMPE811/gmouse_lld_STMPE811.c
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
|
||||
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include "drivers/ginput/touch/STMPE811/stmpe811.h"
|
||||
|
||||
#include "ginput_lld_mouse_board.h"
|
||||
|
||||
#ifndef STMP811_NO_GPIO_IRQPIN
|
||||
#define STMP811_NO_GPIO_IRQPIN FALSE
|
||||
#endif
|
||||
#ifndef STMP811_SLOW_CPU
|
||||
#define STMP811_SLOW_CPU FALSE
|
||||
#endif
|
||||
|
||||
static coord_t x, y, z;
|
||||
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)
|
||||
{
|
||||
write_reg(STMPE811_REG_WDW_TR_X, 2, tr_x);
|
||||
write_reg(STMPE811_REG_WDW_TR_Y, 2, tr_y);
|
||||
write_reg(STMPE811_REG_WDW_BL_X, 2, bl_x);
|
||||
write_reg(STMPE811_REG_WDW_BL_Y, 2, bl_y);
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_init(void)
|
||||
{
|
||||
init_board();
|
||||
|
||||
write_reg(STMPE811_REG_SYS_CTRL1, 1, 0x02); // Software chip reset
|
||||
gfxSleepMilliseconds(10);
|
||||
|
||||
write_reg(STMPE811_REG_SYS_CTRL2, 1, 0x0C); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on
|
||||
#if STMP811_NO_GPIO_IRQPIN
|
||||
write_reg(STMPE811_REG_INT_EN, 1, 0x00); // Interrupt on INT pin when touch is detected
|
||||
#else
|
||||
write_reg(STMPE811_REG_INT_EN, 1, 0x01); // Interrupt on INT pin when touch is detected
|
||||
#endif
|
||||
write_reg(STMPE811_REG_ADC_CTRL1, 1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce
|
||||
gfxSleepMilliseconds(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
|
||||
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
|
||||
write_reg(STMPE811_REG_FIFO_STA, 1, 0x01); // FIFO reset enable
|
||||
write_reg(STMPE811_REG_FIFO_STA, 1, 0x00); // FIFO reset disable
|
||||
write_reg(STMPE811_REG_TSC_FRACT_XYZ, 1, 0x07); // Z axis data format
|
||||
write_reg(STMPE811_REG_TSC_I_DRIVE, 1, 0x01); // 50mA touchscreen line current
|
||||
write_reg(STMPE811_REG_TSC_CTRL, 1, 0x00); // X&Y&Z
|
||||
write_reg(STMPE811_REG_TSC_CTRL, 1, 0x01); // X&Y&Z, TSC enable
|
||||
write_reg(STMPE811_REG_INT_STA, 1, 0xFF); // Clear all interrupts
|
||||
#if !STMP811_NO_GPIO_IRQPIN
|
||||
touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80;
|
||||
#endif
|
||||
write_reg(STMPE811_REG_INT_CTRL, 1, 0x01); // Level interrupt, enable intrrupts
|
||||
}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt)
|
||||
{
|
||||
bool_t clearfifo; // Do we need to clear the FIFO
|
||||
|
||||
#if STMP811_NO_GPIO_IRQPIN
|
||||
// Poll to get the touched status
|
||||
uint8_t last_touched;
|
||||
|
||||
last_touched = touched;
|
||||
touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80;
|
||||
clearfifo = (touched != last_touched);
|
||||
#else
|
||||
// Check if the touch controller IRQ pin has gone off
|
||||
clearfifo = false;
|
||||
if(getpin_irq()) { // please rename this to getpin_irq
|
||||
write_reg(STMPE811_REG_INT_STA, 1, 0xFF); // clear all interrupts
|
||||
touched = (uint8_t)read_reg(STMPE811_REG_TSC_CTRL, 1) & 0x80; // set the new touched status
|
||||
clearfifo = true; // only take the last FIFO reading
|
||||
}
|
||||
#endif
|
||||
|
||||
// If not touched, return the previous results
|
||||
if (!touched) {
|
||||
pt->x = x;
|
||||
pt->y = y;
|
||||
pt->z = 0;
|
||||
pt->buttons = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#if !STMP811_SLOW_CPU
|
||||
if (!clearfifo && (read_reg(STMPE811_REG_FIFO_STA, 1) & 0xD0))
|
||||
#endif
|
||||
clearfifo = true;
|
||||
|
||||
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) */
|
||||
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 */
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
static void init_board(void) {
|
||||
|
||||
}
|
||||
|
||||
static inline bool_t getpin_irq(void) {
|
||||
|
||||
}
|
||||
|
||||
static void write_reg(uint8_t reg, uint8_t n, uint16_t val) {
|
||||
|
||||
}
|
||||
|
||||
static uint16_t read_reg(uint8_t reg, uint8_t n) {
|
||||
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 5
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 5
|
||||
#define GINPUT_MOUSE_CLICK_TIME 450
|
||||
|
||||
/* default values - over write these in your boad files */
|
||||
#define STMP811_SLOWER_RESPONSE FALSE
|
||||
#define STMP811_NO_GPIO_IRQPIN FALSE
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
253
drivers/ginput/touch/STMPE811/gmouse_lld_STMPE811.c
Normal file
253
drivers/ginput/touch/STMPE811/gmouse_lld_STMPE811.c
Normal file
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* 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_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_STMPE811
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Hardware definitions
|
||||
#include "drivers/ginput/touch/STMPE811/stmpe811.h"
|
||||
|
||||
// Get the hardware interface
|
||||
#include "gmouse_lld_STMPE811_board.h"
|
||||
|
||||
// Extra settings for the users gfxconf.h file. See readme.txt
|
||||
#ifndef GMOUSE_STMPE811_SELF_CALIBRATE
|
||||
#define GMOUSE_STMPE811_SELF_CALIBRATE FALSE
|
||||
#endif
|
||||
#ifndef GMOUSE_STMPE811_READ_PRESSURE
|
||||
#define GMOUSE_STMPE811_READ_PRESSURE FALSE
|
||||
#endif
|
||||
#ifndef GMOUSE_STMPE811_TEST_MODE
|
||||
#define GMOUSE_STMPE811_TEST_MODE FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
*
|
||||
* This chip has some problems which required careful coding to overcome.
|
||||
*
|
||||
* The interrupt pin seems to be unreliable, at least on some boards, so we at most
|
||||
* use the pin for filtering results to reduce cpu load.
|
||||
* The symptoms are that readings will just stop due to the irq not being asserted
|
||||
* even though there are items in the fifo. Another interrupt source such as a
|
||||
* touch transition will restart the irq.
|
||||
*
|
||||
* There is no fifo entry created when a touch up event occurs. We must therefore
|
||||
* generate a pseudo result on touch up. Fortunately the touch detection appears
|
||||
* reliable and so we turn off the driver GMOUSE_VFLG_POORUPDOWN setting. In practice
|
||||
* if touch is up we always return a pseudo event as this saves having to remember the
|
||||
* previous touch state.
|
||||
*
|
||||
* Z readings range from around 90 (fully touched) to around 150 (on the verge of non-touched).
|
||||
* Note the above is on the STM32F429i-Discovery board. Other boards may be different.
|
||||
* To be conservative we use 255 as touch off, anything else is a touch on.
|
||||
*
|
||||
* GMOUSE_STMPE811_TEST_MODE is designed to be used with the "touch_raw_readings" tool which shows
|
||||
* a steady stream of raw readings.
|
||||
*
|
||||
* Settings that may need tweaking on other hardware:
|
||||
* The settling times. We have set these conservatively at 1ms.
|
||||
* The reading window. We set this to 16 just to reduce noise. High-res panels may need a lower value.
|
||||
*/
|
||||
static bool_t MouseInit(GMouse* m, unsigned driverinstance) {
|
||||
if (!init_board(m, driverinstance))
|
||||
return FALSE;
|
||||
|
||||
aquire_bus(m);
|
||||
|
||||
write_reg(m, STMPE811_REG_SYS_CTRL1, 0x02); // Software chip reset
|
||||
gfxSleepMilliseconds(10);
|
||||
|
||||
write_reg(m, STMPE811_REG_SYS_CTRL2, 0x0C); // Temperature sensor clock off, GPIO clock off, touch clock on, ADC clock on
|
||||
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
write_reg(m, STMPE811_REG_INT_EN, 0x03); // Interrupt on INT pin when there is a sample or a touch transition.
|
||||
#else
|
||||
write_reg(m, STMPE811_REG_INT_EN, 0x00); // Don't Interrupt on INT pin
|
||||
#endif
|
||||
|
||||
write_reg(m, STMPE811_REG_ADC_CTRL1, 0x48); // ADC conversion time = 80 clock ticks, 12-bit ADC, internal voltage refernce
|
||||
gfxSleepMilliseconds(2);
|
||||
write_reg(m, STMPE811_REG_ADC_CTRL2, 0x01); // ADC speed 3.25MHz
|
||||
write_reg(m, STMPE811_REG_GPIO_AF, 0x00); // GPIO alternate function - OFF
|
||||
write_reg(m, STMPE811_REG_TSC_CFG, 0xA3); // Averaging 4, touch detect delay 1ms, panel driver settling time 1ms
|
||||
write_reg(m, STMPE811_REG_FIFO_TH, 0x01); // FIFO threshold = 1
|
||||
write_reg(m, STMPE811_REG_FIFO_STA, 0x01); // FIFO reset enable
|
||||
write_reg(m, STMPE811_REG_FIFO_STA, 0x00); // FIFO reset disable
|
||||
write_reg(m, STMPE811_REG_TSC_FRACT_XYZ, 0x07); // Z axis data format
|
||||
write_reg(m, STMPE811_REG_TSC_I_DRIVE, 0x01); // max 50mA touchscreen line current
|
||||
#if GMOUSE_STMPE811_READ_PRESSURE
|
||||
write_reg(m, STMPE811_REG_TSC_CTRL, 0x30); // X&Y&Z, 16 reading window
|
||||
write_reg(m, STMPE811_REG_TSC_CTRL, 0x31); // X&Y&Z, 16 reading window, TSC enable
|
||||
#else
|
||||
write_reg(m, STMPE811_REG_TSC_CTRL, 0x32); // X&Y, 16 reading window
|
||||
write_reg(m, STMPE811_REG_TSC_CTRL, 0x33); // X&Y, 16 reading window, TSC enable
|
||||
#endif
|
||||
write_reg(m, STMPE811_REG_INT_STA, 0xFF); // Clear all interrupts
|
||||
write_reg(m, STMPE811_REG_INT_CTRL, 0x01); // Level interrupt, enable interrupts
|
||||
|
||||
release_bus(m);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t read_xyz(GMouse* m, GMouseReading* pdr)
|
||||
{
|
||||
#if GMOUSE_STMPE811_TEST_MODE
|
||||
static GMouseReading n;
|
||||
#endif
|
||||
uint8_t status;
|
||||
|
||||
// Button information will be regenerated
|
||||
pdr->buttons = 0;
|
||||
|
||||
#if GMOUSE_STMPE811_TEST_MODE
|
||||
aquire_bus(m);
|
||||
|
||||
// Set the buttons to match various touch signals
|
||||
if ((read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80))
|
||||
pdr->buttons |= 0x02;
|
||||
|
||||
status = read_byte(m, STMPE811_REG_FIFO_STA);
|
||||
if (!(status & 0x20))
|
||||
pdr->buttons |= 0x04;
|
||||
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
if (getpin_irq(m))
|
||||
pdr->buttons |= 0x08;
|
||||
#endif
|
||||
|
||||
if ((status & 0x20)) {
|
||||
// Nothing in the fifo - just return the last position and pressure
|
||||
pdr->x = n.x;
|
||||
pdr->y = n.y;
|
||||
pdr->z = n.z;
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
write_reg(m, STMPE811_REG_INT_STA, 0xFF);
|
||||
#endif
|
||||
release_bus(m);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else
|
||||
// Is there a new sample or a touch transition
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
if(!getpin_irq(m))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
// Is there something in the fifo
|
||||
status = read_byte(m, STMPE811_REG_FIFO_STA);
|
||||
if ((status & 0x20)) {
|
||||
|
||||
// Nothing in the fifo.
|
||||
|
||||
// If not touched return the pseudo result
|
||||
if (!(read_byte(m, STMPE811_REG_TSC_CTRL) & 0x80)) {
|
||||
|
||||
pdr->z = gmvmt(m)->z_min;
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
write_reg(m, STMPE811_REG_INT_STA, 0xFF);
|
||||
#endif
|
||||
release_bus(m);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// No new result
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
write_reg(m, STMPE811_REG_INT_STA, 0xFF);
|
||||
#endif
|
||||
release_bus(m);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Time to get some readings
|
||||
pdr->x = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_X);
|
||||
pdr->y = (coord_t)read_word(m, STMPE811_REG_TSC_DATA_Y);
|
||||
#if GMOUSE_STMPE811_READ_PRESSURE
|
||||
pdr->z = (coord_t)read_byte(m, STMPE811_REG_TSC_DATA_Z);
|
||||
#else
|
||||
pdr->z = gmvmt(m)->z_max;
|
||||
#endif
|
||||
|
||||
#if !GMOUSE_STMPE811_SLOW_CPU
|
||||
if (!(status & 0xC0)) {
|
||||
// Is there more data to come
|
||||
if (!(read_byte(m, STMPE811_REG_FIFO_STA) & 0x20))
|
||||
_gmouseWakeup(m);
|
||||
} else
|
||||
#endif
|
||||
|
||||
// Clear the rest of the fifo
|
||||
{
|
||||
write_reg(m, STMPE811_REG_FIFO_STA, 0x01); // FIFO reset enable
|
||||
write_reg(m, STMPE811_REG_FIFO_STA, 0x00); // FIFO reset disable
|
||||
}
|
||||
|
||||
// All done
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
write_reg(m, STMPE811_REG_INT_STA, 0xFF);
|
||||
#endif
|
||||
release_bus(m);
|
||||
|
||||
#if GMOUSE_STMPE811_TEST_MODE
|
||||
// Save the result for later
|
||||
n.x = pdr->x;
|
||||
n.y = pdr->y;
|
||||
n.z = pdr->z;
|
||||
#endif
|
||||
|
||||
// Rescale X,Y if we are using self-calibration
|
||||
#if GMOUSE_STMPE811_SELF_CALIBRATE
|
||||
pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
|
||||
pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_TOUCH,
|
||||
#if GMOUSE_STMPE811_SELF_CALIBRATE
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN,
|
||||
#else
|
||||
GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_CALIBRATE | GMOUSE_VFLG_CAL_TEST,
|
||||
#endif
|
||||
sizeof(GMouse) + GMOUSE_STMPE811_BOARD_DATA_SIZE,
|
||||
_gmouseInitDriver,
|
||||
_gmousePostInitDriver,
|
||||
_gmouseDeInitDriver
|
||||
},
|
||||
0, // z_max - 0 indicates full touch
|
||||
255, // z_min
|
||||
150, // z_touchon
|
||||
255, // z_touchoff
|
||||
{ // pen_jitter
|
||||
GMOUSE_STMPE811_PEN_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_STMPE811_PEN_CLICK_ERROR, // click
|
||||
GMOUSE_STMPE811_PEN_MOVE_ERROR // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
GMOUSE_STMPE811_FINGER_CALIBRATE_ERROR, // calibrate
|
||||
GMOUSE_STMPE811_FINGER_CLICK_ERROR, // click
|
||||
GMOUSE_STMPE811_FINGER_MOVE_ERROR // move
|
||||
},
|
||||
MouseInit, // init
|
||||
0, // deinit
|
||||
read_xyz, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
|
||||
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
|
||||
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
|
||||
#define _GINPUT_LLD_MOUSE_BOARD_H
|
||||
|
||||
// Resolution and Accuracy Settings
|
||||
#define GMOUSE_STMPE811_PEN_CALIBRATE_ERROR 8
|
||||
#define GMOUSE_STMPE811_PEN_CLICK_ERROR 6
|
||||
#define GMOUSE_STMPE811_PEN_MOVE_ERROR 4
|
||||
#define GMOUSE_STMPE811_FINGER_CALIBRATE_ERROR 14
|
||||
#define GMOUSE_STMPE811_FINGER_CLICK_ERROR 18
|
||||
#define GMOUSE_STMPE811_FINGER_MOVE_ERROR 14
|
||||
|
||||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
||||
#define GMOUSE_STMPE811_BOARD_DATA_SIZE 0
|
||||
|
||||
// Options - Leave these commented to make it user configurable in the gfxconf.h
|
||||
//#define GMOUSE_STMPE811_READ_PRESSURE FALSE
|
||||
//#define GMOUSE_STMPE811_SELF_CALIBRATE FALSE
|
||||
//#define GMOUSE_STMPE811_TEST_MODE FALSE
|
||||
|
||||
// If TRUE this board has the STMPE811 IRQ pin connected to a GPIO.
|
||||
// Note: For tested hardware this is unreliable and should be set to FALSE until tested.
|
||||
// Symptoms are that mouse readings just appear to stop for a bit. Lifting the touch
|
||||
// and re-applying the touch cause readings to start again.
|
||||
#define GMOUSE_STMPE811_GPIO_IRQPIN FALSE
|
||||
|
||||
// If TRUE this is a really slow CPU and we should always clear the FIFO between reads.
|
||||
#define GMOUSE_STMPE811_SLOW_CPU FALSE
|
||||
|
||||
static bool_t init_board(GMouse* m, unsigned driverinstance) {
|
||||
}
|
||||
|
||||
#if GMOUSE_STMPE811_GPIO_IRQPIN
|
||||
static bool_t getpin_irq(GMouse* m) {
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void aquire_bus(GMouse* m) {
|
||||
}
|
||||
|
||||
static inline void release_bus(GMouse* m) {
|
||||
}
|
||||
|
||||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) {
|
||||
}
|
||||
|
||||
static uint8_t read_byte(GMouse* m, uint8_t reg) {
|
||||
}
|
||||
|
||||
static uint16_t read_word(GMouse* m, uint8_t reg) {
|
||||
}
|
||||
|
||||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
|
11
drivers/ginput/touch/STMPE811/readme.txt
Normal file
11
drivers/ginput/touch/STMPE811/readme.txt
Normal file
@ -0,0 +1,11 @@
|
||||
This driver has a number of optional settings which can be specified in gfxconf.h:
|
||||
|
||||
#define GMOUSE_STMPE811_READ_PRESSURE TRUE
|
||||
Returns pressure values when the touch is down. On tested boards this ranges from 90 to 150. 255 is touch off.
|
||||
|
||||
#define GMOUSE_STMPE811_SELF_CALIBRATE TRUE
|
||||
Scale the touch readings to avoid calibration. This is not as accurate as real calibration.
|
||||
|
||||
#define GMOUSE_STMPE811_TEST_MODE TRUE
|
||||
Return raw readings for diagnostic use with the "touch_raw_readings" tool.
|
||||
|
@ -8,12 +8,6 @@
|
||||
#ifndef _STMPE811_H
|
||||
#define _STMPE811_H
|
||||
|
||||
// Slave address
|
||||
#define STMPE811_ADDR (0x82 >> 1)
|
||||
|
||||
// Maximum timeout
|
||||
#define STMPE811_TIMEOUT 0x3000
|
||||
|
||||
// Identification registers
|
||||
#define STMPE811_REG_CHP_ID 0x00 // 16-bit
|
||||
#define STMPE811_REG_ID_VER 0x02
|
||||
|
@ -10,7 +10,7 @@
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
#define GDISP_DRIVER_VMT GDISPVMT_Win32
|
||||
#include "drivers/multiple/Win32/gdisp_lld_config.h"
|
||||
#include "gdisp_lld_config.h"
|
||||
#include "src/gdisp/driver.h"
|
||||
|
||||
#ifndef GDISP_SCREEN_WIDTH
|
||||
@ -52,7 +52,6 @@
|
||||
|
||||
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_HASTOGGLE (GDISP_FLG_DRIVER<<1)
|
||||
#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<2)
|
||||
#if GDISP_HARDWARE_STREAM_WRITE || GDISP_HARDWARE_STREAM_READ
|
||||
#define GDISP_FLG_WSTREAM (GDISP_FLG_DRIVER<<3)
|
||||
#define GDISP_FLG_WRAPPED (GDISP_FLG_DRIVER<<4)
|
||||
@ -64,16 +63,50 @@
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
/* Include mouse support code */
|
||||
// Include mouse support code
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_Win32
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Forward definitions
|
||||
static bool_t Win32MouseInit(GMouse *m, unsigned driverinstance);
|
||||
static bool_t Win32MouseRead(GMouse *m, GMouseReading *prd);
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_MOUSE,
|
||||
GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY,
|
||||
// Extra flags for testing only
|
||||
//GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER
|
||||
//GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE
|
||||
//GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN
|
||||
sizeof(GMouse),
|
||||
_gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
|
||||
},
|
||||
1, // z_max
|
||||
0, // z_min
|
||||
1, // z_touchon
|
||||
0, // z_touchoff
|
||||
{ // pen_jitter
|
||||
0, // calibrate
|
||||
0, // click
|
||||
0 // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
0, // calibrate
|
||||
2, // click
|
||||
2 // move
|
||||
},
|
||||
Win32MouseInit, // init
|
||||
0, // deinit
|
||||
Win32MouseRead, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
#endif
|
||||
|
||||
static DWORD winThreadId;
|
||||
static volatile bool_t QReady;
|
||||
static HANDLE drawMutex;
|
||||
#if GINPUT_NEED_MOUSE
|
||||
static GDisplay * mouseDisplay;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local routines . */
|
||||
@ -95,6 +128,7 @@ typedef struct winPriv {
|
||||
#if GINPUT_NEED_MOUSE
|
||||
coord_t mousex, mousey;
|
||||
uint16_t mousebuttons;
|
||||
GMouse *mouse;
|
||||
#endif
|
||||
#if GINPUT_NEED_TOGGLE
|
||||
uint8_t toggles;
|
||||
@ -149,7 +183,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
// Handle mouse down on the window
|
||||
#if GINPUT_NEED_MOUSE
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -198,7 +232,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
// Handle mouse up on the window
|
||||
#if GINPUT_NEED_MOUSE
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -210,7 +244,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_MBUTTONDOWN:
|
||||
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
priv = (winPriv *)g->priv;
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -218,7 +252,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_MBUTTONUP:
|
||||
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
priv = (winPriv *)g->priv;
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -226,7 +260,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_RBUTTONDOWN:
|
||||
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
priv = (winPriv *)g->priv;
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -234,7 +268,7 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_RBUTTONUP:
|
||||
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
priv = (winPriv *)g->priv;
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASMOUSE)) {
|
||||
if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
|
||||
priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
|
||||
goto mousemove;
|
||||
}
|
||||
@ -242,14 +276,13 @@ static LRESULT myWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_MOUSEMOVE:
|
||||
g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
priv = (winPriv *)g->priv;
|
||||
if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT || !(g->flags & GDISP_FLG_HASMOUSE))
|
||||
if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT)
|
||||
break;
|
||||
mousemove:
|
||||
priv->mousex = (coord_t)LOWORD(lParam);
|
||||
priv->mousey = (coord_t)HIWORD(lParam);
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL)) // For normal setup this is always TRUE
|
||||
_gmouseWakeup(priv->mouse);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@ -445,14 +478,6 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
g->flags |= GDISP_FLG_HASTOGGLE;
|
||||
#endif
|
||||
|
||||
// Only turn on mouse on the first window for now
|
||||
#if GINPUT_NEED_MOUSE
|
||||
if (!g->controllerdisplay) {
|
||||
mouseDisplay = g;
|
||||
g->flags |= GDISP_FLG_HASMOUSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a private area for this window
|
||||
priv = gfxAlloc(sizeof(winPriv));
|
||||
assert(priv != 0);
|
||||
@ -471,6 +496,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
while(!(((volatile GDisplay *)g)->flags & GDISP_FLG_READY))
|
||||
Sleep(1);
|
||||
|
||||
// Create the associated mouse
|
||||
#if GINPUT_NEED_MOUSE
|
||||
priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
|
||||
#endif
|
||||
|
||||
sprintf(buf, APP_NAME " - %u", g->systemdisplay+1);
|
||||
SetWindowText(priv->hwnd, buf);
|
||||
ShowWindow(priv->hwnd, SW_SHOW);
|
||||
@ -686,10 +716,10 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
winPriv * priv;
|
||||
int x, y;
|
||||
COLORREF color;
|
||||
|
||||
|
||||
priv = g->priv;
|
||||
color = gdispColor2Native(g->p.color);
|
||||
|
||||
|
||||
#if GDISP_NEED_CONTROL
|
||||
switch(g->g.Orientation) {
|
||||
case GDISP_ROTATE_0:
|
||||
@ -818,7 +848,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
sz = (size_t)g->p.cx * (size_t)g->p.cy;
|
||||
if (!(dstbuf = (pixel_t *)malloc(sz * sizeof(pixel_t))))
|
||||
return 0;
|
||||
|
||||
|
||||
// Copy the bits we need
|
||||
switch(g->g.Orientation) {
|
||||
case GDISP_ROTATE_0:
|
||||
@ -847,7 +877,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
return dstbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if GDISP_HARDWARE_BITFILLS
|
||||
#if COLOR_SYSTEM != GDISP_COLORSYSTEM_TRUECOLOR || COLOR_TYPE_BITS <= 8
|
||||
#error "GDISP Win32: This driver's bitblit currently only supports true-color with bit depths > 8 bits."
|
||||
@ -863,7 +893,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
priv = g->priv;
|
||||
buffer = g->p.ptr;
|
||||
buffer += g->p.x2*g->p.y1;
|
||||
|
||||
|
||||
memset(&bmpInfo, 0, sizeof(bmpInfo));
|
||||
bmpInfo.bV4Size = sizeof(bmpInfo);
|
||||
bmpInfo.bV4Planes = 1;
|
||||
@ -982,7 +1012,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
color = GetPixel(priv->dcBuffer, g->p.x, g->p.y);
|
||||
#endif
|
||||
ReleaseMutex(drawMutex);
|
||||
|
||||
|
||||
return gdispNative2Color(color);
|
||||
}
|
||||
#endif
|
||||
@ -992,7 +1022,7 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
winPriv * priv;
|
||||
RECT rect;
|
||||
coord_t lines;
|
||||
|
||||
|
||||
priv = g->priv;
|
||||
|
||||
#if GDISP_NEED_CONTROL
|
||||
@ -1134,18 +1164,51 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
void ginput_lld_mouse_init(void) {}
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
static bool_t Win32MouseInit(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
(void) driverinstance;
|
||||
return TRUE;
|
||||
}
|
||||
static bool_t Win32MouseRead(GMouse *m, GMouseReading *pt) {
|
||||
GDisplay * g;
|
||||
winPriv * priv;
|
||||
|
||||
g = mouseDisplay;
|
||||
g = m->display;
|
||||
priv = g->priv;
|
||||
|
||||
pt->x = priv->mousex;
|
||||
pt->y = priv->mousey > g->g.Height ? g->g.Height : priv->mousey;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
|
||||
pt->y = priv->mousey;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
|
||||
pt->buttons = priv->mousebuttons;
|
||||
|
||||
#if GDISP_NEED_CONTROL
|
||||
// If the self-rotation has been set in the VMT then do that here (TESTING ONLY)
|
||||
if ((gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) { // For normal setup this is always False
|
||||
coord_t t;
|
||||
|
||||
switch(gdispGGetOrientation(m->display)) {
|
||||
case GDISP_ROTATE_0:
|
||||
default:
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
t = pt->x;
|
||||
pt->x = g->g.Width - 1 - pt->y;
|
||||
pt->y = t;
|
||||
break;
|
||||
case GDISP_ROTATE_180:
|
||||
pt->x = g->g.Width - 1 - pt->x;
|
||||
pt->y = g->g.Height - 1 - pt->y;
|
||||
break;
|
||||
case GDISP_ROTATE_270:
|
||||
t = pt->y;
|
||||
pt->y = g->g.Height - 1 - pt->x;
|
||||
pt->x = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
// This driver supports being both a mouse or a touch device (we don't actually know which it really is)
|
||||
// When operating in mouse mode a long left button click does not generate a context click.
|
||||
// When operating in touch mode we allow sloppier clicks etc
|
||||
#if 1
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
|
||||
#define GINPUT_MOUSE_CLICK_TIME TIME_INFINITE // Long click != Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 0
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 0
|
||||
#else
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700 // Long click = Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE // Can be set to TRUE just for testing
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#endif
|
||||
|
||||
// This driver supports both an "interrupt" mode, and a polled mode
|
||||
#define GINPUT_MOUSE_POLL_PERIOD TIME_INFINITE // Interrupt driven by the Window thread
|
||||
//#define GINPUT_MOUSE_POLL_PERIOD 25 // Poll driven
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
@ -10,7 +10,7 @@
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
#define GDISP_DRIVER_VMT GDISPVMT_X11
|
||||
#include "drivers/multiple/X/gdisp_lld_config.h"
|
||||
#include "gdisp_lld_config.h"
|
||||
#include "src/gdisp/driver.h"
|
||||
|
||||
#ifndef GDISP_FORCE_24BIT
|
||||
@ -27,8 +27,45 @@
|
||||
#define GDISP_FLG_READY (GDISP_FLG_DRIVER<<0)
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
/* Include mouse support code */
|
||||
// Include mouse support code
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_X11
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Forward definitions
|
||||
static bool_t XMouseInit(GMouse *m, unsigned driverinstance);
|
||||
static bool_t XMouseRead(GMouse *m, GMouseReading *prd);
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_MOUSE,
|
||||
GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY,
|
||||
// Extra flags for testing only
|
||||
//GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER
|
||||
//GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE
|
||||
//GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN
|
||||
sizeof(GMouse),
|
||||
_gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
|
||||
},
|
||||
1, // z_max
|
||||
0, // z_min
|
||||
1, // z_touchon
|
||||
0, // z_touchoff
|
||||
{ // pen_jitter
|
||||
0, // calibrate
|
||||
0, // click
|
||||
0 // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
0, // calibrate
|
||||
2, // click
|
||||
2 // move
|
||||
},
|
||||
XMouseInit, // init
|
||||
0, // deinit
|
||||
XMouseRead, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
@ -45,15 +82,16 @@ static Colormap cmap;
|
||||
static XVisualInfo vis;
|
||||
static XContext cxt;
|
||||
static Atom wmDelete;
|
||||
#if GINPUT_NEED_MOUSE
|
||||
static coord_t mousex, mousey;
|
||||
static uint16_t mousebuttons;
|
||||
#endif
|
||||
|
||||
typedef struct xPriv {
|
||||
Pixmap pix;
|
||||
GC gc;
|
||||
Window win;
|
||||
#if GINPUT_NEED_MOUSE
|
||||
coord_t mousex, mousey;
|
||||
uint16_t buttons;
|
||||
GMouse * mouse;
|
||||
#endif
|
||||
} xPriv;
|
||||
|
||||
static void ProcessEvent(GDisplay *g, xPriv *priv) {
|
||||
@ -80,37 +118,31 @@ static void ProcessEvent(GDisplay *g, xPriv *priv) {
|
||||
break;
|
||||
#if GINPUT_NEED_MOUSE
|
||||
case ButtonPress:
|
||||
mousex = evt.xbutton.x;
|
||||
mousey = evt.xbutton.y;
|
||||
priv->mousex = evt.xbutton.x;
|
||||
priv->mousey = evt.xbutton.y;
|
||||
switch(evt.xbutton.button){
|
||||
case 1: mousebuttons |= GINPUT_MOUSE_BTN_LEFT; break;
|
||||
case 2: mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE; break;
|
||||
case 3: mousebuttons |= GINPUT_MOUSE_BTN_RIGHT; break;
|
||||
case 4: mousebuttons |= GINPUT_MOUSE_BTN_4; break;
|
||||
case 1: priv->buttons |= GINPUT_MOUSE_BTN_LEFT; break;
|
||||
case 2: priv->buttons |= GINPUT_MOUSE_BTN_MIDDLE; break;
|
||||
case 3: priv->buttons |= GINPUT_MOUSE_BTN_RIGHT; break;
|
||||
case 4: priv->buttons |= GINPUT_MOUSE_BTN_4; break;
|
||||
}
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
_gmouseWakeup(priv->mouse);
|
||||
break;
|
||||
case ButtonRelease:
|
||||
mousex = evt.xbutton.x;
|
||||
mousey = evt.xbutton.y;
|
||||
priv->mousex = evt.xbutton.x;
|
||||
priv->mousey = evt.xbutton.y;
|
||||
switch(evt.xbutton.button){
|
||||
case 1: mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT; break;
|
||||
case 2: mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE; break;
|
||||
case 3: mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT; break;
|
||||
case 4: mousebuttons &= ~GINPUT_MOUSE_BTN_4; break;
|
||||
case 1: priv->buttons &= ~GINPUT_MOUSE_BTN_LEFT; break;
|
||||
case 2: priv->buttons &= ~GINPUT_MOUSE_BTN_MIDDLE; break;
|
||||
case 3: priv->buttons &= ~GINPUT_MOUSE_BTN_RIGHT; break;
|
||||
case 4: priv->buttons &= ~GINPUT_MOUSE_BTN_4; break;
|
||||
}
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
_gmouseWakeup(priv->mouse);
|
||||
break;
|
||||
case MotionNotify:
|
||||
mousex = evt.xmotion.x;
|
||||
mousey = evt.xmotion.y;
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
priv->mousex = evt.xmotion.x;
|
||||
priv->mousey = evt.xmotion.y;
|
||||
_gmouseWakeup(priv->mouse);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
@ -231,6 +263,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
XSetBackground(dis, priv->gc, BlackPixel(dis, scr));
|
||||
XSync(dis, TRUE);
|
||||
|
||||
// Create the associated mouse before the map
|
||||
#if GINPUT_NEED_MOUSE
|
||||
priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
|
||||
#endif
|
||||
|
||||
XSelectInput(dis, priv->win, StructureNotifyMask);
|
||||
XMapWindow(dis, priv->win);
|
||||
|
||||
@ -322,16 +359,21 @@ LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g)
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
|
||||
void ginput_lld_mouse_init(void) {}
|
||||
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
pt->x = mousex;
|
||||
pt->y = mousey;
|
||||
pt->z = (mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
|
||||
pt->buttons = mousebuttons;
|
||||
static bool_t XMouseInit(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
(void) driverinstance;
|
||||
return TRUE;
|
||||
}
|
||||
static bool_t XMouseRead(GMouse *m, GMouseReading *pt) {
|
||||
xPriv * priv;
|
||||
|
||||
priv = m->display->priv;
|
||||
pt->x = priv->mousex;
|
||||
pt->y = priv->mousey;
|
||||
pt->z = (priv->buttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
|
||||
pt->buttons = priv->buttons;
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
#define _LLD_GINPUT_MOUSE_CONFIG_H
|
||||
|
||||
// This driver supports being both a mouse or a touch device (we don't actually know which it really is)
|
||||
// When operating in mouse mode a long left button click does not generate a context click.
|
||||
// When operating in touch mode we allow sloppier clicks etc
|
||||
#if 1
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
|
||||
#define GINPUT_MOUSE_CLICK_TIME TIME_INFINITE // Long click != Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 0
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 0
|
||||
#else
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700 // Long click = Context Click
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE // Can be set to TRUE just for testing
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 2
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 2
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
|
||||
#endif
|
||||
|
||||
// This driver supports both an "interrupt" mode, and a polled mode
|
||||
#define GINPUT_MOUSE_POLL_PERIOD TIME_INFINITE // Interrupt driven by the Window thread
|
||||
//#define GINPUT_MOUSE_POLL_PERIOD 25 // Poll driven
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
@ -10,7 +10,7 @@
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
#define GDISP_DRIVER_VMT GDISPVMT_uGFXnet
|
||||
#include "drivers/multiple/uGFXnet/gdisp_lld_config.h"
|
||||
#include "gdisp_lld_config.h"
|
||||
#include "src/gdisp/driver.h"
|
||||
#include "uGFXnetProtocol.h"
|
||||
|
||||
@ -33,6 +33,48 @@
|
||||
#define GDISP_GFXNET_BROKEN_LWIP_ACCEPT FALSE
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
// Include mouse support code
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_uGFXnet
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
// Forward definitions
|
||||
static bool_t NMouseInit(GMouse *m, unsigned driverinstance);
|
||||
static bool_t NMouseRead(GMouse *m, GMouseReading *prd);
|
||||
|
||||
const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
|
||||
{
|
||||
GDRIVER_TYPE_MOUSE,
|
||||
GMOUSE_VFLG_NOPOLL|GMOUSE_VFLG_DYNAMICONLY,
|
||||
// Extra flags for testing only
|
||||
//GMOUSE_VFLG_TOUCH|GMOUSE_VFLG_SELFROTATION|GMOUSE_VFLG_DEFAULTFINGER
|
||||
//GMOUSE_VFLG_CALIBRATE|GMOUSE_VFLG_CAL_EXTREMES|GMOUSE_VFLG_CAL_TEST|GMOUSE_VFLG_CAL_LOADFREE
|
||||
//GMOUSE_VFLG_ONLY_DOWN|GMOUSE_VFLG_POORUPDOWN
|
||||
sizeof(GMouse),
|
||||
_gmouseInitDriver, _gmousePostInitDriver, _gmouseDeInitDriver
|
||||
},
|
||||
1, // z_max
|
||||
0, // z_min
|
||||
1, // z_touchon
|
||||
0, // z_touchoff
|
||||
{ // pen_jitter
|
||||
0, // calibrate
|
||||
0, // click
|
||||
0 // move
|
||||
},
|
||||
{ // finger_jitter
|
||||
0, // calibrate
|
||||
2, // click
|
||||
2 // move
|
||||
},
|
||||
NMouseInit, // init
|
||||
0, // deinit
|
||||
NMouseRead, // get
|
||||
0, // calsave
|
||||
0 // calload
|
||||
}};
|
||||
#endif
|
||||
|
||||
#if GNETCODE_VERSION != GNETCODE_VERSION_1_0
|
||||
#error "GDISP: uGFXnet - This driver only support protocol V1.0"
|
||||
#endif
|
||||
@ -98,14 +140,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define GDISP_FLG_HASMOUSE (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<1)
|
||||
#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<2)
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
/* Include mouse support code */
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
#endif
|
||||
#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<1)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local routines . */
|
||||
@ -118,15 +154,12 @@ typedef struct netPriv {
|
||||
#if GINPUT_NEED_MOUSE
|
||||
coord_t mousex, mousey;
|
||||
uint16_t mousebuttons;
|
||||
GMouse * mouse;
|
||||
#endif
|
||||
} netPriv;
|
||||
|
||||
static gfxThreadHandle hThread;
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
static GDisplay * mouseDisplay;
|
||||
#endif
|
||||
|
||||
#if GDISP_GFXNET_UNSAFE_SOCKETS
|
||||
static gfxMutex uGFXnetMutex;
|
||||
#define MUTEX_INIT gfxMutexInit(&uGFXnetMutex)
|
||||
@ -156,15 +189,134 @@ static bool_t sendpkt(SOCKET_TYPE netfd, uint16_t *pkt, int len) {
|
||||
return send(netfd, (const char *)pkt, len, 0) == len;
|
||||
}
|
||||
|
||||
static bool_t newconnection(SOCKET_TYPE clientfd) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
|
||||
// Look for a display that isn't connected
|
||||
for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
|
||||
// Ignore displays for other controllers
|
||||
#ifdef GDISP_DRIVER_LIST
|
||||
if (gvmt(g) != &GDISPVMT_uGFXnet)
|
||||
continue;
|
||||
#endif
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
break;
|
||||
}
|
||||
|
||||
// Was anything found?
|
||||
if (!g)
|
||||
return FALSE;
|
||||
|
||||
// Reset the priv area
|
||||
priv = g->priv;
|
||||
priv->netfd = clientfd;
|
||||
priv->databytes = 0;
|
||||
priv->mousebuttons = 0;
|
||||
|
||||
// Send the initialisation data (2 words at a time)
|
||||
priv->data[0] = GNETCODE_INIT;
|
||||
priv->data[1] = GNETCODE_VERSION;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_SCREEN_WIDTH;
|
||||
priv->data[1] = GDISP_SCREEN_HEIGHT;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_LLD_PIXELFORMAT;
|
||||
priv->data[1] = 1; // We have a mouse
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
MUTEX_EXIT;
|
||||
|
||||
// The display is now working
|
||||
g->flags |= GDISP_FLG_CONNECTED;
|
||||
|
||||
// Send a redraw all
|
||||
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
|
||||
gdispGClear(g, gwinGetDefaultBgColor());
|
||||
gwinRedrawDisplay(g, FALSE);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool_t rxdata(SOCKET_TYPE fd) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
int len;
|
||||
|
||||
// Look for a display that is connected and the socket descriptor matches
|
||||
for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
|
||||
// Ignore displays for other controllers
|
||||
#ifdef GDISP_DRIVER_LIST
|
||||
if (gvmt(g) != &GDISPVMT_uGFXnet)
|
||||
continue;
|
||||
#endif
|
||||
priv = g->priv;
|
||||
if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == fd)
|
||||
break;
|
||||
}
|
||||
if (!g)
|
||||
gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");
|
||||
|
||||
if ((g->flags & GDISP_FLG_HAVEDATA)) {
|
||||
// The higher level is still processing the previous data.
|
||||
// Give it a chance to run by coming back to this data.
|
||||
gfxSleepMilliseconds(1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* handle data from a client */
|
||||
MUTEX_ENTER;
|
||||
if ((len = recv(fd, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
|
||||
// Socket closed or in error state
|
||||
MUTEX_EXIT;
|
||||
g->flags &= ~GDISP_FLG_CONNECTED;
|
||||
return FALSE;
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Do we have a full reply yet
|
||||
priv->databytes += len;
|
||||
if (priv->databytes < sizeof(priv->data))
|
||||
return TRUE;
|
||||
priv->databytes = 0;
|
||||
|
||||
// Convert network byte or to host byte order
|
||||
priv->data[0] = ntohs(priv->data[0]);
|
||||
priv->data[1] = ntohs(priv->data[1]);
|
||||
|
||||
// Process the data received
|
||||
switch(priv->data[0]) {
|
||||
#if GINPUT_NEED_MOUSE
|
||||
case GNETCODE_MOUSE_X: priv->mousex = priv->data[1]; break;
|
||||
case GNETCODE_MOUSE_Y: priv->mousey = priv->data[1]; break;
|
||||
case GNETCODE_MOUSE_B:
|
||||
priv->mousebuttons = priv->data[1];
|
||||
// Treat the button event as the sync signal
|
||||
_gmouseWakeup(priv->mouse);
|
||||
break;
|
||||
#endif
|
||||
case GNETCODE_CONTROL:
|
||||
case GNETCODE_READ:
|
||||
g->flags |= GDISP_FLG_HAVEDATA;
|
||||
break;
|
||||
case GNETCODE_KILL:
|
||||
gfxHalt("GDISP: uGFXnet - Display sent KILL command");
|
||||
break;
|
||||
|
||||
default:
|
||||
// Just ignore unrecognised data
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static DECLARE_THREAD_STACK(waNetThread, 512);
|
||||
static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
||||
SOCKET_TYPE listenfd, fdmax, i, clientfd;
|
||||
socklen_t len;
|
||||
int leni;
|
||||
fd_set master, read_fds;
|
||||
struct sockaddr_in addr;
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
(void)param;
|
||||
|
||||
// Start the sockets layer
|
||||
@ -197,25 +349,13 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
||||
fdmax = listenfd; /* so far, it's this one*/
|
||||
|
||||
#if GDISP_GFXNET_BROKEN_LWIP_ACCEPT
|
||||
{
|
||||
#warning "Using GDISP_GFXNET_BROKEN_LWIP_ACCEPT limits the number of displays and the use of GFXNET. Avoid if possible!"
|
||||
len = sizeof(addr);
|
||||
if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
|
||||
gfxHalt("GDISP: uGFXnet - Accept failed");
|
||||
//printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
// Look for a display that isn't connected
|
||||
for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
|
||||
// Ignore displays for other controllers
|
||||
#ifdef GDISP_DRIVER_LIST
|
||||
if (gvmt(g) != &GDISPVMT_uGFXnet)
|
||||
continue;
|
||||
#endif
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
break;
|
||||
}
|
||||
|
||||
// Was anything found?
|
||||
if (!g) {
|
||||
if (!newconnection(clientfd)) {
|
||||
// No Just close the connection
|
||||
closesocket(clientfd);
|
||||
gfxHalt("GDISP: uGFXnet - Can't find display for connection");
|
||||
@ -225,33 +365,6 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
||||
// Save the descriptor
|
||||
FD_SET(clientfd, &master);
|
||||
if (clientfd > fdmax) fdmax = clientfd;
|
||||
priv = g->priv;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
priv->netfd = clientfd;
|
||||
//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);
|
||||
|
||||
// Send the initialisation data (2 words at a time)
|
||||
priv->data[0] = GNETCODE_INIT;
|
||||
priv->data[1] = GNETCODE_VERSION;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_SCREEN_WIDTH;
|
||||
priv->data[1] = GDISP_SCREEN_HEIGHT;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_LLD_PIXELFORMAT;
|
||||
priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
MUTEX_EXIT;
|
||||
|
||||
// The display is now working
|
||||
g->flags |= GDISP_FLG_CONNECTED;
|
||||
|
||||
// Send a redraw all
|
||||
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
|
||||
gdispGClear(g, gwinGetDefaultBgColor());
|
||||
gwinRedrawDisplay(g, FALSE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* loop */
|
||||
@ -268,132 +381,33 @@ static DECLARE_THREAD_FUNCTION(NetThread, param) {
|
||||
|
||||
// Handle new connections
|
||||
if(i == listenfd) {
|
||||
|
||||
// Accept the connection
|
||||
len = sizeof(addr);
|
||||
if((clientfd = accept(listenfd, (struct sockaddr *)&addr, &len)) == (SOCKET_TYPE)-1)
|
||||
gfxHalt("GDISP: uGFXnet - Accept failed");
|
||||
//printf("New connection from %s on socket %d\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
// Look for a display that isn't connected
|
||||
for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
|
||||
// Ignore displays for other controllers
|
||||
#ifdef GDISP_DRIVER_LIST
|
||||
if (gvmt(g) != &GDISPVMT_uGFXnet)
|
||||
continue;
|
||||
#endif
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
break;
|
||||
}
|
||||
// Can we handle it?
|
||||
if (!newconnection(clientfd)) {
|
||||
|
||||
// Was anything found?
|
||||
if (!g) {
|
||||
// No Just close the connection
|
||||
// No - Just close the connection
|
||||
closesocket(clientfd);
|
||||
//printf(New connection from %s on socket %d rejected as all displays are already connected\n", inet_ntoa(addr.sin_addr), clientfd);
|
||||
|
||||
//printf("Rejected connection as all displays are already connected\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Save the descriptor
|
||||
FD_SET(clientfd, &master);
|
||||
if (clientfd > fdmax) fdmax = clientfd;
|
||||
priv = g->priv;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
priv->netfd = clientfd;
|
||||
//printf(New connection from %s on socket %d allocated to display %u\n", inet_ntoa(addr.sin_addr), clientfd, disp+1);
|
||||
|
||||
// Send the initialisation data (2 words at a time)
|
||||
priv->data[0] = GNETCODE_INIT;
|
||||
priv->data[1] = GNETCODE_VERSION;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_SCREEN_WIDTH;
|
||||
priv->data[1] = GDISP_SCREEN_HEIGHT;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
priv->data[0] = GDISP_LLD_PIXELFORMAT;
|
||||
priv->data[1] = (g->flags & GDISP_FLG_HASMOUSE) ? 1 : 0;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, priv->data, 2);
|
||||
MUTEX_EXIT;
|
||||
|
||||
// The display is now working
|
||||
g->flags |= GDISP_FLG_CONNECTED;
|
||||
|
||||
// Send a redraw all
|
||||
#if GFX_USE_GWIN && GWIN_NEED_WINDOWMANAGER
|
||||
gdispGClear(g, gwinGetDefaultBgColor());
|
||||
gwinRedrawDisplay(g, FALSE);
|
||||
#endif
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle data from a client
|
||||
|
||||
// Look for a display that is connected and the socket descriptor matches
|
||||
for(g = 0; (g = (GDisplay *)gdriverGetNext(GDRIVER_TYPE_DISPLAY, (GDriver *)g));) {
|
||||
// Ignore displays for other controllers
|
||||
#ifdef GDISP_DRIVER_LIST
|
||||
if (gvmt(g) != &GDISPVMT_uGFXnet)
|
||||
continue;
|
||||
#endif
|
||||
priv = g->priv;
|
||||
if ((g->flags & GDISP_FLG_CONNECTED) && priv->netfd == i)
|
||||
break;
|
||||
}
|
||||
if (!g)
|
||||
gfxHalt("GDISP: uGFXnet - Got data from unrecognized connection");
|
||||
|
||||
if ((g->flags & GDISP_FLG_HAVEDATA)) {
|
||||
// The higher level is still processing the previous data.
|
||||
// Give it a chance to run by coming back to this data.
|
||||
gfxSleepMilliseconds(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* handle data from a client */
|
||||
MUTEX_ENTER;
|
||||
if ((leni = recv(i, ((char *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
|
||||
// Socket closed or in error state
|
||||
MUTEX_EXIT;
|
||||
g->flags &= ~GDISP_FLG_CONNECTED;
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
if (!rxdata(i)) {
|
||||
closesocket(i);
|
||||
FD_CLR(i, &master);
|
||||
continue;
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Do we have a full reply yet
|
||||
priv->databytes += leni;
|
||||
if (priv->databytes < sizeof(priv->data))
|
||||
continue;
|
||||
priv->databytes = 0;
|
||||
|
||||
// Convert network byte or to host byte order
|
||||
priv->data[0] = ntohs(priv->data[0]);
|
||||
priv->data[1] = ntohs(priv->data[1]);
|
||||
|
||||
// Process the data received
|
||||
switch(priv->data[0]) {
|
||||
#if GINPUT_NEED_MOUSE
|
||||
case GNETCODE_MOUSE_X: priv->mousex = priv->data[1]; break;
|
||||
case GNETCODE_MOUSE_Y: priv->mousey = priv->data[1]; break;
|
||||
case GNETCODE_MOUSE_B:
|
||||
priv->mousebuttons = priv->data[1];
|
||||
// Treat the button event as the sync signal
|
||||
#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
|
||||
ginputMouseWakeup();
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
case GNETCODE_CONTROL:
|
||||
case GNETCODE_READ:
|
||||
g->flags |= GDISP_FLG_HAVEDATA;
|
||||
break;
|
||||
case GNETCODE_KILL:
|
||||
gfxHalt("GDISP: uGFXnet - Display sent KILL command");
|
||||
break;
|
||||
|
||||
default:
|
||||
// Just ignore unrecognised data
|
||||
break;
|
||||
FD_CLR(clientfd, &master);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -414,14 +428,6 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
gfxThreadClose(hThread);
|
||||
}
|
||||
|
||||
// Only turn on mouse on the first window for now
|
||||
#if GINPUT_NEED_MOUSE
|
||||
if (!g->controllerdisplay) {
|
||||
mouseDisplay = g;
|
||||
g->flags |= GDISP_FLG_HASMOUSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a private area for this window
|
||||
if (!(priv = gfxAlloc(sizeof(netPriv))))
|
||||
gfxHalt("GDISP: uGFXnet - Memory allocation failed");
|
||||
@ -429,6 +435,11 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
g->priv = priv;
|
||||
g->board = 0; // no board interface for this controller
|
||||
|
||||
// Create the associated mouse
|
||||
#if GINPUT_NEED_MOUSE
|
||||
priv->mouse = (GMouse *)gdriverRegister((const GDriverVMT const *)GMOUSE_DRIVER_VMT, g);
|
||||
#endif
|
||||
|
||||
// Initialise the GDISP structure
|
||||
g->g.Orientation = GDISP_ROTATE_0;
|
||||
g->g.Powermode = powerOn;
|
||||
@ -694,18 +705,23 @@ LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
void ginput_lld_mouse_init(void) {}
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt) {
|
||||
static bool_t NMouseInit(GMouse *m, unsigned driverinstance) {
|
||||
(void) m;
|
||||
(void) driverinstance;
|
||||
return TRUE;
|
||||
}
|
||||
static bool_t NMouseRead(GMouse *m, GMouseReading *pt) {
|
||||
GDisplay * g;
|
||||
netPriv * priv;
|
||||
|
||||
g = mouseDisplay;
|
||||
g = m->display;
|
||||
priv = g->priv;
|
||||
|
||||
pt->x = priv->mousex;
|
||||
pt->y = priv->mousey;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 100 : 0;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
|
||||
pt->buttons = priv->mousebuttons;
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
|
@ -211,6 +211,16 @@
|
||||
//#define GFX_USE_GINPUT FALSE
|
||||
|
||||
//#define GINPUT_NEED_MOUSE FALSE
|
||||
// #define GINPUT_TOUCH_STARTRAW FALSE
|
||||
// #define GINPUT_TOUCH_NOTOUCH FALSE
|
||||
// #define GINPUT_TOUCH_NOCALIBRATE FALSE
|
||||
// #define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE
|
||||
// #define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
// #define GINPUT_MOUSE_CLICK_TIME 300
|
||||
// #define GINPUT_TOUCH_CXTCLICK_TIME 700
|
||||
// #define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE
|
||||
// #define GINPUT_TOUCH_USER_CALIBRATION_FREE FALSE
|
||||
// #define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE
|
||||
//#define GINPUT_NEED_KEYBOARD FALSE
|
||||
//#define GINPUT_NEED_TOGGLE FALSE
|
||||
//#define GINPUT_NEED_DIAL FALSE
|
||||
|
@ -17,162 +17,159 @@
|
||||
#ifndef _LLD_GINPUT_MOUSE_H
|
||||
#define _LLD_GINPUT_MOUSE_H
|
||||
|
||||
#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
|
||||
#if GINPUT_NEED_MOUSE //|| defined(__DOXYGEN__)
|
||||
|
||||
#include "ginput_lld_mouse_config.h"
|
||||
// Include the GDRIVER infrastructure
|
||||
#include "src/gdriver/sys_defs.h"
|
||||
|
||||
// GEVENT_MOUSE or GEVENT_TOUCH - What type of device is this.
|
||||
#ifndef GINPUT_MOUSE_EVENT_TYPE
|
||||
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
|
||||
#endif
|
||||
|
||||
// TRUE/FALSE - Does the mouse/touch driver require calibration?
|
||||
#ifndef GINPUT_MOUSE_NEED_CALIBRATION
|
||||
#define GINPUT_MOUSE_NEED_CALIBRATION FALSE
|
||||
#endif
|
||||
|
||||
// TRUE/FALSE - Should the calibration happen at the extremes of the panel?
|
||||
#ifndef GINPUT_MOUSE_CALIBRATE_EXTREMES
|
||||
#define GINPUT_MOUSE_CALIBRATE_EXTREMES FALSE
|
||||
#endif
|
||||
|
||||
// TRUE/FALSE - Can the mouse/touch driver itself save calibration data?
|
||||
#ifndef GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
|
||||
#endif
|
||||
|
||||
// n or -1 - n means to test calibration result (+/- pixels), -1 means not to.
|
||||
#ifndef GINPUT_MOUSE_MAX_CALIBRATION_ERROR
|
||||
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
|
||||
#endif
|
||||
|
||||
// n - How many times to read (and average) per poll
|
||||
#ifndef GINPUT_MOUSE_READ_CYCLES
|
||||
#define GINPUT_MOUSE_READ_CYCLES 1
|
||||
#endif
|
||||
|
||||
// n - Millisecs between poll's
|
||||
#ifndef GINPUT_MOUSE_POLL_PERIOD
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#endif
|
||||
|
||||
// n - Movement allowed without discarding the CLICK or CLICKCXT event (+/- pixels)
|
||||
#ifndef GINPUT_MOUSE_MAX_CLICK_JITTER
|
||||
#define GINPUT_MOUSE_MAX_CLICK_JITTER 1
|
||||
#endif
|
||||
|
||||
// n - Movement allowed without discarding the MOVE event (+/- pixels)
|
||||
#ifndef GINPUT_MOUSE_MAX_MOVE_JITTER
|
||||
#define GINPUT_MOUSE_MAX_MOVE_JITTER 0
|
||||
#endif
|
||||
|
||||
// ms - Millisecs seperating a CLICK from a CXTCLICK
|
||||
#ifndef GINPUT_MOUSE_CLICK_TIME
|
||||
#define GINPUT_MOUSE_CLICK_TIME 700
|
||||
#endif
|
||||
|
||||
// true/false - Whether the mouse driver internally handles screen rotation
|
||||
#ifndef GINPUT_MOUSE_NO_ROTATION
|
||||
#define GINPUT_MOUSE_NO_ROTATION FALSE
|
||||
#endif
|
||||
|
||||
typedef struct MouseReading_t {
|
||||
typedef struct GMouseReading {
|
||||
coord_t x, y, z;
|
||||
uint16_t buttons;
|
||||
} MouseReading;
|
||||
} GMouseReading;
|
||||
|
||||
#if !GINPUT_TOUCH_NOCALIBRATE
|
||||
typedef struct GMouseCalibration {
|
||||
float ax;
|
||||
float bx;
|
||||
float cx;
|
||||
float ay;
|
||||
float by;
|
||||
float cy;
|
||||
} GMouseCalibration;
|
||||
#endif
|
||||
|
||||
typedef struct GMouse {
|
||||
GDriver d; // The driver overheads and vmt
|
||||
GMouseReading r; // The current position and state
|
||||
uint16_t flags; // Flags
|
||||
#define GMOUSE_FLG_CLICK_TIMER 0x0001 // Currently timing a click
|
||||
#define GMOUSE_FLG_INDELTA 0x0002 // Currently in a up/down transition test
|
||||
#define GMOUSE_FLG_CLIP 0x0004 // Clip reading to the display
|
||||
#define GMOUSE_FLG_CALIBRATE 0x0008 // Calibrate readings
|
||||
#define GMOUSE_FLG_IN_CAL 0x0010 // Currently in calibration routine
|
||||
#define GMOUSE_FLG_FINGERMODE 0x0020 // Mouse is currently in finger mode
|
||||
#define GMOUSE_FLG_NEEDREAD 0x0040 // The mouse needs reading
|
||||
#define GMOUSE_FLG_DRIVER_FIRST 0x0100 // The first flag available for the driver
|
||||
point clickpos; // The position of the last click event
|
||||
systemticks_t clicktime; // The time of the last click event
|
||||
GDisplay * display; // The display the mouse is associated with
|
||||
#if !GINPUT_TOUCH_NOCALIBRATE
|
||||
GMouseCalibration caldata; // The calibration data
|
||||
#endif
|
||||
// Other driver specific fields may follow.
|
||||
} GMouse;
|
||||
|
||||
typedef struct GMouseJitter {
|
||||
coord_t calibrate; // Maximum error for a calibration to succeed
|
||||
coord_t click; // Movement allowed without discarding the CLICK or CLICKCXT event
|
||||
coord_t move; // Movement allowed without discarding the MOVE event
|
||||
} GMouseJitter;
|
||||
|
||||
typedef struct GMouseVMT {
|
||||
GDriverVMT d; // Device flags are part of the general vmt
|
||||
#define GMOUSE_VFLG_TOUCH 0x0001 // This is a touch device (rather than a mouse). Button 1 is calculated from z value.
|
||||
#define GMOUSE_VFLG_NOPOLL 0x0002 // Do not poll this device - it is purely interrupt driven
|
||||
#define GMOUSE_VFLG_SELFROTATION 0x0004 // This device returns readings that are aligned with the display orientation
|
||||
#define GMOUSE_VFLG_DEFAULTFINGER 0x0008 // Default to finger mode
|
||||
#define GMOUSE_VFLG_CALIBRATE 0x0010 // This device requires calibration
|
||||
#define GMOUSE_VFLG_CAL_EXTREMES 0x0020 // Use edge to edge calibration
|
||||
#define GMOUSE_VFLG_CAL_TEST 0x0040 // Test the results of the calibration
|
||||
#define GMOUSE_VFLG_CAL_LOADFREE 0x0080 // Call gfxFree on the buffer returned by the VMT calload() routine.
|
||||
#define GMOUSE_VFLG_ONLY_DOWN 0x0100 // This device returns a valid position only when the mouse is down
|
||||
#define GMOUSE_VFLG_POORUPDOWN 0x0200 // Position readings during up/down are unreliable
|
||||
#define GMOUSE_VFLG_DYNAMICONLY 0x8000 // This mouse driver should not be statically initialized eg Win32
|
||||
coord_t z_max; // TOUCH: Maximum possible z value (fully touched)
|
||||
coord_t z_min; // TOUCH: Minimum possible z value (touch off screen). Note may also be > z_max
|
||||
coord_t z_touchon; // TOUCH: z values between z_max and this are a solid touch on
|
||||
coord_t z_touchoff; // TOUCH: z values between z_min and this are a solid touch off
|
||||
|
||||
GMouseJitter pen_jitter; // PEN MODE: Jitter settings
|
||||
GMouseJitter finger_jitter; // FINGER MODE: Jitter settings
|
||||
|
||||
bool_t (*init)(GMouse *m, unsigned driverinstance); // Required
|
||||
void (*deinit)(GMouse *m); // Optional
|
||||
bool_t (*get)(GMouse *m, GMouseReading *prd); // Required
|
||||
void (*calsave)(GMouse *m, void *buf, size_t sz); // Optional
|
||||
const char *(*calload)(GMouse *m, size_t sz); // Optional: Can return NULL if no data is saved.
|
||||
} GMouseVMT;
|
||||
|
||||
#define gmvmt(m) ((const GMouseVMT const *)((m)->d.vmt))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
// If we are not using multiple mice then hard-code the VMT name
|
||||
#if !defined(GINPUT_MOUSE_DRIVER_LIST)
|
||||
#undef GMOUSE_DRIVER_VMT
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_OnlyOne
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialise the mouse/touch.
|
||||
* @brief Initialize a mouse driver
|
||||
*
|
||||
* @param[in] g The mouse driver
|
||||
* @param[in] display The display to which the mouse shall be assigned
|
||||
* @param[in] driverinstance The driver instance ToDo: Add some more details
|
||||
* @param[in] systeminstance The mouse instance ToDo: Add some more details
|
||||
*
|
||||
* @return TRUE on success, FALSE otherwise
|
||||
* @note This routine is provided by the high level code for
|
||||
* use in the driver VMT's GMouseVMT.d structure.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_init(void);
|
||||
bool_t _gmouseInitDriver(GDriver *g, void *display, unsigned driverinstance, unsigned systeminstance);
|
||||
|
||||
/**
|
||||
* @brief Read the mouse/touch position.
|
||||
* @brief Routine that is called after initialization
|
||||
*
|
||||
* @param[in] pt A pointer to the structure to fill
|
||||
*
|
||||
* @note For drivers that don't support returning a position
|
||||
* when the touch is up (most touch devices), it should
|
||||
* return the previous position with the new Z value.
|
||||
* The z value is the pressure for those touch devices
|
||||
* that support it (-100 to 100 where > 0 is touched)
|
||||
* or, 0 or 100 for those drivers that don't.
|
||||
* @param[in] g The mouse driver
|
||||
* @note This routine is provided by the high level code for
|
||||
* use in the driver VMT's GMouseVMT.d structure.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_get_reading(MouseReading *pt);
|
||||
void _gmousePostInitDriver(GDriver *g);
|
||||
|
||||
#if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
|
||||
/**
|
||||
* @brief Load calibration data from a storage area on the touch controller.
|
||||
*
|
||||
* @param[in] instance The mouse instance number
|
||||
*
|
||||
* @note The instance parameter is currently always 0 as we only support
|
||||
* one mouse/touch device at a time.
|
||||
* @note This routine should only be provided if the driver has its own
|
||||
* storage area where calibration data can be stored. The drivers
|
||||
* option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
|
||||
* if it supports this.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
const char *ginput_lld_mouse_calibration_load(uint16_t instance);
|
||||
/**
|
||||
* @brief Save calibration data to a storage area on the touch controller.
|
||||
*
|
||||
* @param[in] instance The mouse instance number
|
||||
* @param[in] calbuf The calibration data to be saved
|
||||
* @param[in] sz The size of the calibration data
|
||||
*
|
||||
* @note The instance parameter is currently always 0 as we only support
|
||||
* one mouse/touch device at a time.
|
||||
* @note This routine should only be provided if the driver has its own
|
||||
* storage area where calibration data can be stored. The drivers
|
||||
* option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
|
||||
* if it supports this.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginput_lld_mouse_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz);
|
||||
#endif
|
||||
/**
|
||||
* @brief Deinitialize a mouse driver
|
||||
*
|
||||
* @param[in] g The mouse driver
|
||||
* @note This routine is provided by the high level code for
|
||||
* use in the driver VMT's GMouseVMT.d structure.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _gmouseDeInitDriver(GDriver *g);
|
||||
|
||||
/**
|
||||
* @brief Wakeup the high level code so that it attempts another read
|
||||
*
|
||||
* @note This routine is provided to low level drivers by the high level code
|
||||
* @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ginputMouseWakeup(void);
|
||||
void _gmouseWakeup(GMouse *m);
|
||||
|
||||
/**
|
||||
* @brief Wakeup the high level code so that it attempts another read
|
||||
*
|
||||
* @note This routine is provided to low level drivers by the high level code
|
||||
* @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
|
||||
*
|
||||
* @iclass
|
||||
* @notapi
|
||||
*/
|
||||
void ginputMouseWakeupI(void);
|
||||
void _gmouseWakeupI(GMouse *m);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH */
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_H */
|
||||
/** @} */
|
||||
|
@ -16,10 +16,16 @@
|
||||
|
||||
#if GFX_USE_GINPUT
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
extern void _gmouseInit(void);
|
||||
extern void _gmouseDeinit(void);
|
||||
#endif
|
||||
|
||||
void _ginputInit(void)
|
||||
{
|
||||
/* ToDo */
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
_gmouseInit();
|
||||
#endif
|
||||
/**
|
||||
* This should really call an init routine for each ginput sub-system.
|
||||
* Maybe we'll do this later.
|
||||
@ -28,7 +34,9 @@ void _ginputInit(void)
|
||||
|
||||
void _ginputDeinit(void)
|
||||
{
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
_gmouseDeinit();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* GFX_USE_GINPUT */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -17,7 +17,7 @@
|
||||
*
|
||||
* @pre GFX_USE_GINPUT must be set to TRUE in your gfxconf.h
|
||||
* @pre GINPUT_NEED_MOUSE must be set to TRUE in your gfxconf.h
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@ -32,32 +32,29 @@
|
||||
|
||||
/* This type definition is also used by touch */
|
||||
typedef struct GEventMouse_t {
|
||||
GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
|
||||
uint16_t instance; // The mouse/touch instance
|
||||
coord_t x, y, z; // The position of the mouse.
|
||||
// - For touch devices, Z is the current pressure if supported (otherwise 0)
|
||||
// - For mice, Z is the 3rd dimension if supported (otherwise 0)
|
||||
uint16_t current_buttons; // A bit is set if the button is down.
|
||||
// - For touch only bit 0 is relevant
|
||||
// - For mice the order of the buttons is (from 0 to n) left, right, middle, any other buttons
|
||||
// - Bit 15 being set indicates that an important mouse event has been missed.
|
||||
#define GINPUT_MOUSE_BTN_LEFT 0x0001
|
||||
#define GINPUT_MOUSE_BTN_RIGHT 0x0002
|
||||
#define GINPUT_MOUSE_BTN_MIDDLE 0x0004
|
||||
#define GINPUT_MOUSE_BTN_4 0x0008
|
||||
#define GINPUT_MISSED_MOUSE_EVENT 0x8000
|
||||
#define GINPUT_TOUCH_PRESSED GINPUT_MOUSE_BTN_LEFT
|
||||
uint16_t last_buttons; // The value of current_buttons on the last event
|
||||
enum GMouseMeta_e {
|
||||
GMETA_NONE = 0, // There is no meta event currently happening
|
||||
GMETA_MOUSE_DOWN = 1, // Button 0 has just gone down
|
||||
GMETA_MOUSE_UP = 2, // Button 0 has just gone up
|
||||
GMETA_MOUSE_CLICK = 4, // Button 0 has just gone through a short down - up cycle
|
||||
GMETA_MOUSE_CXTCLICK = 8 // For mice - The right button has just been depressed
|
||||
// For touch - a long press has just occurred
|
||||
} meta;
|
||||
GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
|
||||
coord_t x, y, z; // The position of the mouse.
|
||||
// - For touch devices, Z is the current pressure if supported (values are device specific)
|
||||
// - For mice, Z is the 3rd dimension if supported (values are device specific)
|
||||
uint16_t buttons; // A bit is set if the button is down or a meta event has occurred.
|
||||
#define GINPUT_MOUSE_BTN_MASK 0x000F // The "button is down" mask
|
||||
#define GINPUT_MOUSE_BTN_LEFT 0x0001 // The left mouse button is currently down
|
||||
#define GINPUT_MOUSE_BTN_RIGHT 0x0002 // The right mouse button is currently down
|
||||
#define GINPUT_MOUSE_BTN_MIDDLE 0x0004 // The middle mouse button is currently down
|
||||
#define GINPUT_MOUSE_BTN_4 0x0008 // The 4th mouse button is currently down
|
||||
#define GINPUT_TOUCH_PRESSED 0x0001 // The touch surface is currently touched
|
||||
|
||||
#define GMETA_MASK 0x00F0 // The "button transition" mask
|
||||
#define GMETA_NONE 0x0000 // No "button transition" events
|
||||
#define GMETA_MOUSE_DOWN 0x0010 // Left mouse/touch has just gone down
|
||||
#define GMETA_MOUSE_UP 0x0020 // Left mouse/touch has just gone up
|
||||
#define GMETA_MOUSE_CLICK 0x0040 // Left mouse/touch has just gone through a click (short down - up cycle)
|
||||
#define GMETA_MOUSE_CXTCLICK 0x0080 // Right mouse has just been depressed or touch has gone through a long click
|
||||
|
||||
#define GINPUT_MISSED_MOUSE_EVENT 0x8000 // Oops - a mouse event has previously been missed
|
||||
|
||||
GDisplay * display; // The display this mouse is currently associated with.
|
||||
} GEventMouse;
|
||||
} GEventMouse;
|
||||
|
||||
// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
|
||||
#define GLISTEN_MOUSEMETA 0x0001 // Create events for meta events such as CLICK and CXTCLICK
|
||||
@ -69,12 +66,13 @@ typedef struct GEventMouse_t {
|
||||
#define GLISTEN_TOUCHUPMOVES GLISTEN_MOUSEUPMOVES
|
||||
#define GLISTEN_TOUCHNOFILTER GLISTEN_MOUSENOFILTER
|
||||
|
||||
#define GINPUT_MOUSE_NUM_PORTS 1 // The total number of mouse/touch inputs supported
|
||||
|
||||
// Event types for the mouse ginput source
|
||||
#define GEVENT_MOUSE (GEVENT_GINPUT_FIRST+0)
|
||||
#define GEVENT_TOUCH (GEVENT_GINPUT_FIRST+1)
|
||||
|
||||
// All mice
|
||||
#define GMOUSE_ALL_INSTANCES ((unsigned)-1)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
@ -84,16 +82,32 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Creates an instance of a mouse and returns the Source handler
|
||||
* @note HACK: if the instance is 9999, it is treated as instance 0 except
|
||||
* that no calibration will be performed!
|
||||
* @brief Get the Source handler for a mouse using the instance number
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance (from 0 to 9999)
|
||||
* @param[in] instance The mouse instance number
|
||||
*
|
||||
* @return The source handle of the created instance
|
||||
* @return The source handle of the mouse or NULL
|
||||
* @note You can use the special value of GMOUSE_ALL_INSTANCES to
|
||||
* get a source handle that returns events for all mice rather
|
||||
* than a specific mouse. Using GMOUSE_ALL_INSTANCES will always
|
||||
* return a valid spurce handle even if there are currently no mice
|
||||
* in the system.
|
||||
*/
|
||||
GSourceHandle ginputGetMouse(uint16_t instance);
|
||||
|
||||
GSourceHandle ginputGetMouse(unsigned instance);
|
||||
|
||||
/**
|
||||
* @brief Should this device be in Pen mode or Finger mode
|
||||
* @note A touch device (and even theoritically a mouse) can operate
|
||||
* in either pen or finger mode. In finger mode typically a
|
||||
* touch device will be far more tolerant of movement and other
|
||||
* inaccuracies. Each driver specifies its own tolerances for
|
||||
* pen versus finger mode.
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
* @param[in] on If true then finger mode is turned on.
|
||||
*/
|
||||
void ginputSetFingerMode(unsigned instance, bool_t on);
|
||||
|
||||
/**
|
||||
* @brief Assign the display associated with the mouse
|
||||
* @note This only needs to be called if the mouse is associated with a display
|
||||
@ -105,7 +119,7 @@ extern "C" {
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
* @param[in] g The GDisplay to which this mouse belongs
|
||||
*/
|
||||
void ginputSetMouseDisplay(uint16_t instance, GDisplay *g);
|
||||
void ginputSetMouseDisplay(unsigned instance, GDisplay *g);
|
||||
|
||||
/**
|
||||
* @brief Get the display currently associated with the mouse
|
||||
@ -113,7 +127,7 @@ extern "C" {
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
*/
|
||||
GDisplay *ginputGetMouseDisplay(uint16_t instance);
|
||||
GDisplay *ginputGetMouseDisplay(unsigned instance);
|
||||
|
||||
/**
|
||||
* @brief Get the current mouse position and button status
|
||||
@ -125,51 +139,47 @@ extern "C" {
|
||||
*
|
||||
* @return FALSE on an error (eg. invalid instance)
|
||||
*/
|
||||
bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pmouse);
|
||||
bool_t ginputGetMouseStatus(unsigned instance, GEventMouse *pmouse);
|
||||
|
||||
/**
|
||||
* @brief Performs a calibration
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
*
|
||||
* @return FALSE if the driver dosen't support a calibration of if the handle is invalid
|
||||
* @return The calibration error squared if calibration fails, or 0 on success or if the driver dosen't need calibration.
|
||||
* @note An invalid instance will also return 0.
|
||||
*/
|
||||
bool_t ginputCalibrateMouse(uint16_t instance);
|
||||
uint32_t ginputCalibrateMouse(unsigned instance);
|
||||
|
||||
/* Set the routines to save and fetch calibration data.
|
||||
* This function should be called before first calling ginputGetMouse() for a particular instance
|
||||
* as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
|
||||
* If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
|
||||
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
|
||||
*/
|
||||
typedef void (*GMouseCalibrationSaveRoutine)(uint16_t instance, const uint8_t *calbuf, size_t sz); // Save calibration data
|
||||
typedef const char * (*GMouseCalibrationLoadRoutine)(uint16_t instance); // Load calibration data (returns NULL if not data saved)
|
||||
/**
|
||||
* @brief Load a set of mouse calibration data
|
||||
* @return A pointer to the data or NULL on failure
|
||||
*
|
||||
* @param[in] instance The mouse input instance number
|
||||
* @param[in] sz The size in bytes of the data to retrieve.
|
||||
*
|
||||
* @note This routine is provided by the user application. It is only
|
||||
* called if GINPUT_TOUCH_USER_CALIBRATION_LOAD has been set to TRUE in the
|
||||
* users gfxconf.h file.
|
||||
* @note If GINPUT_TOUCH_USER_CALIBRATION_FREE has been set to TRUE in the users
|
||||
* gfxconf.h file then the buffer returned will be free'd using gfxFree().
|
||||
*/
|
||||
void *LoadMouseCalibration(unsigned instance, size_t sz);
|
||||
|
||||
/**
|
||||
* @brief Set the routines to store and restore calibration data
|
||||
/**
|
||||
* @brief Save a set of mouse calibration data
|
||||
* @return TRUE if the save operation was successful.
|
||||
*
|
||||
* @param[in] instance The mouse input instance number
|
||||
* @param[in] data The data to save
|
||||
* @param[in] sz The size in bytes of the data to retrieve.
|
||||
*
|
||||
* @details This function should be called before first calling ginputGetMouse() for a particular instance
|
||||
* as the gdispGetMouse() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
|
||||
* If this is called after gdispGetMouse() has been called and the driver requires calibration storage, it will immediately save the
|
||||
* data is has already obtained.
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
* @param[in] fnsave The routine to save the data
|
||||
* @param[in] fnload The routine to restore the data
|
||||
* @param[in] requireFree TRUE if the buffer returned by the load function must be freed by the mouse code.
|
||||
*/
|
||||
void ginputSetMouseCalibrationRoutines(uint16_t instance, GMouseCalibrationSaveRoutine fnsave, GMouseCalibrationLoadRoutine fnload, bool_t requireFree);
|
||||
* @note This routine is provided by the user application. It is only
|
||||
* called if GINPUT_TOUCH_USER_CALIBRATION_SAVE has been set to TRUE in the
|
||||
* users gfxconf.h file.
|
||||
*/
|
||||
bool_t SaveMouseCalibration(unsigned instance, const void *data, size_t sz);
|
||||
|
||||
/**
|
||||
* @brief Test if a particular mouse/touch instance requires routines to save it's alibration data
|
||||
* @note Not implemented yet
|
||||
*
|
||||
* @param[in] instance The ID of the mouse input instance
|
||||
*
|
||||
* @return TRUE if needed
|
||||
*/
|
||||
bool_t ginputRequireMouseCalibrationStorage(uint16_t instance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -73,40 +73,97 @@
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Use a custom board definition for the mouse/touch driver even if a board definition exists.
|
||||
* @brief Start touch devices without loading or running calibration.
|
||||
* @details Defaults to FALSE
|
||||
* @details If TRUE, add ginput_lld_mouse_board.h to your project directory and customise it.
|
||||
* @note Not all GINPUT mouse/touch low level drivers use board definition files.
|
||||
* @note This is used if you want to manually control the initial calibration
|
||||
* process. In practice this is only useful for a touch driver test program.
|
||||
*/
|
||||
#ifndef GINPUT_MOUSE_USE_CUSTOM_BOARD
|
||||
#define GINPUT_MOUSE_USE_CUSTOM_BOARD FALSE
|
||||
#ifndef GINPUT_TOUCH_STARTRAW
|
||||
#define GINPUT_TOUCH_STARTRAW FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Turn off the touch calibration GUI.
|
||||
* @details Defaults to FALSE
|
||||
* @note Turning off the calibration GUI just turns off the manual calibration
|
||||
* process. Readings may still be calibrated if calibration data
|
||||
* can be loaded.
|
||||
* @note Calibration requires a lot of code. If your device doesn't require it
|
||||
* using this option can save a lot of space.
|
||||
*/
|
||||
#ifndef GINPUT_TOUCH_NOCALIBRATE_GUI
|
||||
#define GINPUT_TOUCH_NOCALIBRATE_GUI FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Use a custom board definition for the keyboard driver even if a board definition exists.
|
||||
* @brief Turn off all touch calibration support.
|
||||
* @details Defaults to FALSE
|
||||
* @details If TRUE, add ginput_lld_keyboard_board.h to your project directory and customise it.
|
||||
* @note Not all GINPUT keyboard low level drivers use board definition files.
|
||||
* @note With this set to TRUE touch readings will not be calibrated.
|
||||
* @note This automatically turns off the calibration GUI too!
|
||||
* @note Calibration requires a lot of code. If your device doesn't require it
|
||||
* using this option can save a lot of space.
|
||||
*/
|
||||
#ifndef GINPUT_KEYBOARD_USE_CUSTOM_BOARD
|
||||
#define GINPUT_KEYBOARD_USE_CUSTOM_BOARD FALSE
|
||||
#ifndef GINPUT_TOUCH_NOCALIBRATE
|
||||
#define GINPUT_TOUCH_NOCALIBRATE FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Use a custom board definition for the toggle driver even if a board definition exists.
|
||||
* @brief Turn off all touch support.
|
||||
* @details Defaults to FALSE
|
||||
* @details If TRUE, add ginput_lld_toggle_board.h to your project directory and customise it.
|
||||
* @note Not all GINPUT toggle low level drivers use board definition files.
|
||||
* @note This automatically turns off all calibration and the calibration GUI too!
|
||||
* @note Touch device handling requires a lot of code. If your device doesn't require it
|
||||
* using this option can save a lot of space.
|
||||
*/
|
||||
#ifndef GINPUT_TOGGLE_USE_CUSTOM_BOARD
|
||||
#define GINPUT_TOGGLE_USE_CUSTOM_BOARD FALSE
|
||||
#ifndef GINPUT_TOUCH_NOTOUCH
|
||||
#define GINPUT_TOUCH_NOTOUCH FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief Use a custom board definition for the dial driver even if a board definition exists.
|
||||
* @details Defaults to FALSE
|
||||
* @details If TRUE, add ginput_lld_dial_board.h to your project directory and customise it.
|
||||
* @note Not all GINPUT dial low level drivers use board definition files.
|
||||
* @brief Milliseconds between mouse polls.
|
||||
* @details Defaults to 25 millseconds
|
||||
* @note How often mice should be polled. More often leads to smoother mouse movement
|
||||
* but increases CPU usage.
|
||||
*/
|
||||
#ifndef GINPUT_DIAL_USE_CUSTOM_BOARD
|
||||
#define GINPUT_DIAL_USE_CUSTOM_BOARD FALSE
|
||||
#ifndef GINPUT_MOUSE_POLL_PERIOD
|
||||
#define GINPUT_MOUSE_POLL_PERIOD 25
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum length of CLICK in milliseconds
|
||||
* @details Defaults to 300 millseconds
|
||||
* @note Mouse down to Mouse up times greater than this are not clicks.
|
||||
*/
|
||||
#ifndef GINPUT_MOUSE_CLICK_TIME
|
||||
#define GINPUT_MOUSE_CLICK_TIME 300
|
||||
#endif
|
||||
/**
|
||||
* @brief Milliseconds to generate a CXTCLICK on a touch device.
|
||||
* @details Defaults to 700 millseconds
|
||||
* @note If you hold the touch down for longer than this a CXTCLICK is generated
|
||||
* but only on a touch device.
|
||||
*/
|
||||
#ifndef GINPUT_TOUCH_CXTCLICK_TIME
|
||||
#define GINPUT_TOUCH_CXTCLICK_TIME 700
|
||||
#endif
|
||||
/**
|
||||
* @brief There is a user supplied routine to load mouse calibration data
|
||||
* @details Defaults to FALSE
|
||||
* @note If TRUE the user must supply the @p LoadMouseCalibration() routine.
|
||||
*/
|
||||
#ifndef GINPUT_TOUCH_USER_CALIBRATION_LOAD
|
||||
#define GINPUT_TOUCH_USER_CALIBRATION_LOAD FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief The buffer returned by the users @p LoadMouseCalibration() routine must be gfxFree()'d
|
||||
* by the mouse code.
|
||||
* @details Defaults to FALSE
|
||||
*/
|
||||
#ifndef GINPUT_TOUCH_USER_CALIBRATION_FREE
|
||||
#define GINPUT_TOUCH_USER_CALIBRATION_FREE FALSE
|
||||
#endif
|
||||
/**
|
||||
* @brief There is a user supplied routine to save mouse calibration data
|
||||
* @details Defaults to FALSE
|
||||
* @note If TRUE the user must supply the @p SaveMouseCalibration() routine.
|
||||
*/
|
||||
#ifndef GINPUT_TOUCH_USER_CALIBRATION_SAVE
|
||||
#define GINPUT_TOUCH_USER_CALIBRATION_SAVE FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
|
@ -31,6 +31,21 @@
|
||||
#undef GFX_USE_GTIMER
|
||||
#define GFX_USE_GTIMER TRUE
|
||||
#endif
|
||||
#if GINPUT_NEED_MOUSE
|
||||
#if GINPUT_TOUCH_NOTOUCH
|
||||
// No warning needed for this
|
||||
#undef GINPUT_TOUCH_NOCALIBRATE
|
||||
#define GINPUT_TOUCH_NOCALIBRATE TRUE
|
||||
#endif
|
||||
#if GINPUT_TOUCH_NOCALIBRATE
|
||||
// No warning needed for this
|
||||
#undef GINPUT_TOUCH_NOCALIBRATE_GUI
|
||||
#define GINPUT_TOUCH_NOCALIBRATE_GUI TRUE
|
||||
#endif
|
||||
#if !GINPUT_TOUCH_NOTOUCH && GINPUT_MOUSE_CLICK_TIME > GINPUT_TOUCH_CXTCLICK_TIME
|
||||
#error "GINPUT MOUSE: The GINPUT_MOUSE_CLICK_TIME must be <= GINPUT_TOUCH_CXTCLICK_TIME"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _GINPUT_RULES_H */
|
||||
|
@ -114,7 +114,7 @@ static void gwidgetEvent(void *param, GEvent *pe) {
|
||||
// Is the mouse currently captured by this widget?
|
||||
if ((h->flags & (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) == (GWIN_FLG_WIDGET|GWIN_FLG_MOUSECAPTURE)) {
|
||||
gh = h;
|
||||
if ((pme->last_buttons & ~pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) {
|
||||
if ((pme->buttons & GMETA_MOUSE_UP)) {
|
||||
gh->flags &= ~GWIN_FLG_MOUSECAPTURE;
|
||||
if (wvmt->MouseUp)
|
||||
wvmt->MouseUp(gw, pme->x - gh->x, pme->y - gh->y);
|
||||
@ -133,7 +133,7 @@ static void gwidgetEvent(void *param, GEvent *pe) {
|
||||
|
||||
// Process any mouse down over the highest order window if it is an enabled widget
|
||||
if (gh && (gh->flags & (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) == (GWIN_FLG_WIDGET|GWIN_FLG_SYSENABLED)) {
|
||||
if ((~pme->last_buttons & pme->current_buttons & GINPUT_MOUSE_BTN_LEFT)) {
|
||||
if ((pme->buttons & GMETA_MOUSE_DOWN)) {
|
||||
gh->flags |= GWIN_FLG_MOUSECAPTURE;
|
||||
if (wvmt->MouseDown)
|
||||
wvmt->MouseDown(gw, pme->x - gh->x, pme->y - gh->y);
|
||||
@ -234,6 +234,7 @@ void _gwidgetInit(void)
|
||||
{
|
||||
geventListenerInit(&gl);
|
||||
geventRegisterCallback(&gl, gwidgetEvent, 0);
|
||||
geventAttachSource(&gl, ginputGetMouse(GMOUSE_ALL_INSTANCES), GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);
|
||||
}
|
||||
|
||||
void _gwidgetDeinit(void)
|
||||
@ -427,13 +428,10 @@ bool_t gwinAttachListener(GListener *pl) {
|
||||
}
|
||||
|
||||
#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
|
||||
bool_t gwinAttachMouse(uint16_t instance) {
|
||||
GSourceHandle gsh;
|
||||
|
||||
if (!(gsh = ginputGetMouse(instance)))
|
||||
return FALSE;
|
||||
|
||||
return geventAttachSource(&gl, gsh, GLISTEN_MOUSEMETA|GLISTEN_MOUSEDOWNMOVES);
|
||||
bool_t DEPRECATED("This call can now be removed. Attaching the mouse to GWIN is now automatic.") gwinAttachMouse(uint16_t instance) {
|
||||
// This is now a NULL event because we automatically attach to all mice in the system.
|
||||
(void) instance;
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -199,7 +199,7 @@ void gwinSetDefaultStyle(const GWidgetStyle *pstyle, bool_t updateAll);
|
||||
* @brief Get the current default style.
|
||||
*
|
||||
* @return The current default style.
|
||||
*
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
const GWidgetStyle *gwinGetDefaultStyle(void);
|
||||
@ -305,17 +305,7 @@ void gwinSetCustomDraw(GHandle gh, CustomWidgetDrawFunction fn, void *param);
|
||||
bool_t gwinAttachListener(GListener *pl);
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Set the mouse to be used to control the widgets
|
||||
* @return TRUE on success
|
||||
*
|
||||
* @param[in] instance The mouse instance
|
||||
*
|
||||
* @note Every widget uses the same mouse.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
bool_t gwinAttachMouse(uint16_t instance);
|
||||
bool_t DEPRECATED("This call can now be removed. Attaching the mouse to GWIN is now automatic.") gwinAttachMouse(uint16_t instance);
|
||||
#endif
|
||||
|
||||
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) || defined(__DOXYGEN__)
|
||||
|
@ -57,5 +57,6 @@
|
||||
|
||||
/* Features for the GINPUT sub-system. */
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
#define GINPUT_TOUCH_STARTRAW TRUE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
||||
|
@ -29,9 +29,57 @@
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
// We get nasty and look at some internal structures - get the relevant information
|
||||
#include "src/gdriver/sys_defs.h"
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static GConsoleObject gc;
|
||||
static GListener gl;
|
||||
static font_t font;
|
||||
static coord_t bWidth, bWidth2, bHeight;
|
||||
static GHandle ghc;
|
||||
static coord_t swidth, sheight;
|
||||
|
||||
static void DrawHeader(const char *title, bool_t btnNext, bool_t btnPrev, bool_t btnPlusMinus) {
|
||||
#if GDISP_NEED_CLIP
|
||||
gdispSetClip(0, 0, swidth, sheight);
|
||||
#endif
|
||||
gdispFillStringBox(0, 0, swidth, bHeight, "Touch Calibration", font, Red, White, justifyLeft);
|
||||
if (btnNext)
|
||||
gdispFillStringBox(swidth-1*bWidth, 0, bWidth , bHeight, "Next", font, Black, Gray, justifyCenter);
|
||||
if (btnPrev)
|
||||
gdispFillStringBox(swidth-2*bWidth, 0, bWidth-1, bHeight, "Prev", font, Black, Gray, justifyCenter);
|
||||
if (btnPlusMinus) {
|
||||
gdispFillStringBox(swidth-2*bWidth-1*bWidth2, 0, bWidth2-1, bHeight, "+", font, Black, Gray, justifyCenter);
|
||||
gdispFillStringBox(swidth-2*bWidth-2*bWidth2, 0, bWidth2-1, bHeight, "-", font, Black, Gray, justifyCenter);
|
||||
}
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n%s\n\n", title);
|
||||
gwinSetColor(ghc, White);
|
||||
}
|
||||
|
||||
#define BTN_NONE 0
|
||||
#define BTN_NEXT 1
|
||||
#define BTN_PREV 2
|
||||
#define BTN_PLUS 3
|
||||
#define BTN_MINUS 4
|
||||
|
||||
static int CheckButtons(GEventMouse *pem) {
|
||||
if (pem->y < bHeight && (pem->buttons & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-1*bWidth)
|
||||
return BTN_NEXT;
|
||||
if (pem->x >= swidth-2*bWidth)
|
||||
return BTN_PREV;
|
||||
if (pem->x >= swidth-2*bWidth-1*bWidth2)
|
||||
return BTN_PLUS;
|
||||
if (pem->x >= swidth-2*bWidth-2*bWidth2)
|
||||
return BTN_MINUS;
|
||||
}
|
||||
return BTN_NONE;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* GINPUT Touch Driver Calibrator. *
|
||||
@ -39,18 +87,22 @@ static font_t font;
|
||||
int main(void) {
|
||||
GSourceHandle gs;
|
||||
GEventMouse *pem;
|
||||
coord_t swidth, sheight;
|
||||
GHandle ghc;
|
||||
GEventType deviceType;
|
||||
bool_t calibrated;
|
||||
coord_t bWidth, bHeight;
|
||||
bool_t isFirstTime;
|
||||
bool_t isCalibrated;
|
||||
bool_t isTouch;
|
||||
bool_t isFinger;
|
||||
const char * isFingerText;
|
||||
const char * deviceText;
|
||||
GMouse * m;
|
||||
GMouseVMT * vmt;
|
||||
GMouseJitter * pjit;
|
||||
uint32_t calerr;
|
||||
|
||||
gfxInit(); // Initialize the display
|
||||
|
||||
// Get the display dimensions
|
||||
swidth = gdispGetWidth();
|
||||
sheight = gdispGetHeight();
|
||||
calibrated = FALSE;
|
||||
|
||||
// Create our title
|
||||
font = gdispOpenFont("UI2");
|
||||
@ -59,8 +111,11 @@ int main(void) {
|
||||
bHeight = gdispGetStringWidth("Prev", font);
|
||||
if (bHeight > bWidth) bWidth = bHeight;
|
||||
bWidth += 4;
|
||||
bHeight = gdispGetFontMetric(font, fontHeight)+2;
|
||||
gdispFillStringBox(0, 0, swidth, bHeight, "Touch Calibration", font, Red, White, justifyLeft);
|
||||
bWidth2 = gdispGetStringWidth("+", font)*2;
|
||||
bHeight = gdispGetStringWidth("-", font)*2;
|
||||
if (bHeight > bWidth2) bWidth2 = bHeight;
|
||||
bWidth2 += 4;
|
||||
bHeight = gdispGetFontMetric(font, fontHeight)*2+2;
|
||||
|
||||
// Create our main display window
|
||||
{
|
||||
@ -70,75 +125,98 @@ int main(void) {
|
||||
wi.show = TRUE; wi.x = 0; wi.y = bHeight; wi.width = swidth; wi.height = sheight-bHeight;
|
||||
ghc = gwinConsoleCreate(&gc, &wi);
|
||||
}
|
||||
gwinClear(ghc);
|
||||
|
||||
// Initialize the mouse in our special no calibration mode.
|
||||
// Initialize the listener
|
||||
geventListenerInit(&gl);
|
||||
gs = ginputGetMouse(9999);
|
||||
|
||||
// Copy the current mouse's VMT so we can play with it.
|
||||
m = (GMouse *)gdriverGetInstance(GDRIVER_TYPE_MOUSE, 0);
|
||||
if (!m) gfxHalt("No mouse instance 0");
|
||||
vmt = gfxAlloc(sizeof(GMouseVMT));
|
||||
if (!vmt) gfxHalt("Could not allocate memory for mouse VMT");
|
||||
memcpy(vmt, m->d.vmt, sizeof(GMouseVMT));
|
||||
|
||||
// Swap VMT's on the current mouse to our RAM copy
|
||||
m->d.vmt = (const GDriverVMT *)vmt;
|
||||
|
||||
// Listen for events
|
||||
gs = ginputGetMouse(0);
|
||||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
|
||||
|
||||
// Get initial display settings for buttons
|
||||
isFirstTime = TRUE;
|
||||
isCalibrated = (vmt->d.flags & GMOUSE_VFLG_CALIBRATE) ? FALSE : TRUE;
|
||||
calerr = 0;
|
||||
|
||||
/*
|
||||
* Test: Device Type
|
||||
*/
|
||||
|
||||
StepDeviceType:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n1. DEVICE TYPE\n\n");
|
||||
DrawHeader("1. Device Type", isCalibrated, isCalibrated && !isFirstTime, isCalibrated);
|
||||
|
||||
pem = (GEventMouse *)&gl.event;
|
||||
ginputGetMouseStatus(0, pem);
|
||||
deviceType = pem->type;
|
||||
// Get the type of device and the current mode
|
||||
isTouch = (vmt->d.flags & GMOUSE_VFLG_TOUCH) ? TRUE : FALSE;
|
||||
isFinger = (m->flags & GMOUSE_FLG_FINGERMODE) ? TRUE : FALSE;
|
||||
pjit = isFinger ? &vmt->finger_jitter : &vmt->pen_jitter;
|
||||
isFingerText = isFinger ? "finger" : "pen";
|
||||
deviceText = isTouch ? isFingerText : "mouse";
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
gwinPrintf(ghc, "This is detected as a %s device\n\n",
|
||||
deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
|
||||
gwinPrintf(ghc, "This is detected as a %s device\n\n", isTouch ? "TOUCH" : "MOUSE");
|
||||
gwinPrintf(ghc, "It is currently in %s mode\n\n", isFinger ? "FINGER" : "PEN");
|
||||
|
||||
if (calibrated)
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n");
|
||||
else if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Click the mouse button to move on to the next test.\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Press and release your finger to move on to the next test.\n");
|
||||
if (!isCalibrated)
|
||||
gwinPrintf(ghc, "Press and release your %s to move on to the next test.\n", deviceText);
|
||||
else {
|
||||
gwinPrintf(ghc, "Press + for pen or - for finger.\n");
|
||||
if (isFirstTime)
|
||||
gwinPrintf(ghc, "Press Next to continue.\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n");
|
||||
}
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (calibrated) {
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepClickJitter;
|
||||
}
|
||||
if (isCalibrated) {
|
||||
switch (CheckButtons(pem)) {
|
||||
case BTN_NEXT:
|
||||
break;
|
||||
case BTN_PREV:
|
||||
if (!isFirstTime)
|
||||
goto StepDrawing;
|
||||
continue;
|
||||
case BTN_PLUS:
|
||||
m->flags &= ~GMOUSE_FLG_FINGERMODE;
|
||||
goto StepDeviceType;
|
||||
case BTN_MINUS:
|
||||
m->flags |= GMOUSE_FLG_FINGERMODE;
|
||||
goto StepDeviceType;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
} else if ((pem->meta & GMETA_MOUSE_UP))
|
||||
break;
|
||||
}
|
||||
if ((pem->buttons & GMETA_MOUSE_UP))
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test: Mouse raw reading jitter
|
||||
* Test: Mouse raw reading
|
||||
*/
|
||||
|
||||
StepRawJitter:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Press and hold the mouse button.\n\n");
|
||||
else
|
||||
StepRawReading:
|
||||
DrawHeader("2. Raw Mouse Output", FALSE, FALSE, FALSE);
|
||||
if (isTouch)
|
||||
gwinPrintf(ghc, "Press and hold on the surface.\n\n");
|
||||
gwinPrintf(ghc, "Numbers will display in this window.\n"
|
||||
"Ensure that values don't jump around very much when your finger is stationary.\n\n"
|
||||
"Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n");
|
||||
|
||||
if (calibrated)
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n");
|
||||
else if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Release the mouse button to move on to the next test.\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Release your finger to move on to the next test.\n");
|
||||
gwinPrintf(ghc, "Press and hold the mouse button.\n\n");
|
||||
gwinPrintf(ghc, "The raw values coming from your mouse driver will display.\n\n");
|
||||
gwinPrintf(ghc, "Make sure the x and y values change as you move.\n\n");
|
||||
|
||||
gwinPrintf(ghc, "Release your %s to move on to the next test.\n", deviceText);
|
||||
|
||||
// Make sure we are in uncalibrated mode
|
||||
m->flags &= ~(GMOUSE_FLG_CALIBRATE|GMOUSE_FLG_CLIP);
|
||||
|
||||
// For this test turn on ALL mouse movement events
|
||||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEUPMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
|
||||
@ -148,17 +226,16 @@ StepRawJitter:
|
||||
// mind missing events for this test.
|
||||
gfxSleepMilliseconds(100);
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (calibrated) {
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepDeviceType;
|
||||
}
|
||||
}
|
||||
} else if ((pem->meta & GMETA_MOUSE_UP))
|
||||
gwinPrintf(ghc, "%u, %u z=%u b=0x%04x\n", pem->x, pem->y, pem->z, pem->buttons & ~GINPUT_MISSED_MOUSE_EVENT);
|
||||
if ((pem->buttons & GMETA_MOUSE_UP))
|
||||
break;
|
||||
gwinPrintf(ghc, "%u:%u z=%u b=0x%04x m=%04x\n", pem->x, pem->y, pem->z, pem->current_buttons, pem->meta);
|
||||
}
|
||||
|
||||
// Reset to calibrated condition
|
||||
if (isCalibrated) {
|
||||
m->flags |= GMOUSE_FLG_CLIP;
|
||||
if ((vmt->d.flags & GMOUSE_VFLG_CALIBRATE))
|
||||
m->flags |= GMOUSE_FLG_CALIBRATE;
|
||||
}
|
||||
|
||||
// Reset to just changed movements.
|
||||
@ -169,62 +246,68 @@ StepRawJitter:
|
||||
*/
|
||||
|
||||
StepCalibrate:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n");
|
||||
gwinSetColor(ghc, Gray);
|
||||
gwinPrintf(ghc, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n");
|
||||
gwinSetColor(ghc, White);
|
||||
gwinPrintf(ghc, "You will be presented with a number of points to touch.\nPress them in turn.\n\n"
|
||||
"If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n");
|
||||
|
||||
if (calibrated)
|
||||
gwinPrintf(ghc, "Press Next to start the calibration.\n");
|
||||
else if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Click the mouse button to start the calibration.\n");
|
||||
DrawHeader("3. Calibration Jitter", isCalibrated, isCalibrated, isCalibrated);
|
||||
if ((vmt->d.flags & GMOUSE_VFLG_CALIBRATE)) {
|
||||
gwinPrintf(ghc, "You will be presented with a number of points to touch.\nPress them in turn.\n\n"
|
||||
"If the calibration repeatedly fails, increase the jitter for %s calibration and try again.\n\n", isFingerText);
|
||||
gwinPrintf(ghc, "Pressing the surface for longer gives more accurate results.\n\n");
|
||||
if (calerr)
|
||||
gwinPrintf(ghc, "Last calibration error ^ 2 = %u\n", calerr);
|
||||
gwinPrintf(ghc, "Calibration jitter (%s) = %u\n", isFingerText, pjit->calibrate);
|
||||
if (isCalibrated)
|
||||
gwinPrintf(ghc, "Press + or - to adjust.\n");
|
||||
} else {
|
||||
gwinPrintf(ghc, "This device does not need calibration.\n\n");
|
||||
}
|
||||
if (isCalibrated)
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Press and release your finger to start the calibration.\n");
|
||||
gwinPrintf(ghc, "Press and release your %s to move on to start calibration.\n", deviceText);
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (calibrated) {
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepRawJitter;
|
||||
}
|
||||
if (isCalibrated) {
|
||||
switch (CheckButtons(pem)) {
|
||||
case BTN_NEXT:
|
||||
break;
|
||||
case BTN_PREV:
|
||||
goto StepRawReading;
|
||||
case BTN_PLUS:
|
||||
gwinPrintf(ghc, "Calibration jitter (%s) = %u", isFingerText, ++pjit->calibrate);
|
||||
continue;
|
||||
case BTN_MINUS:
|
||||
gwinPrintf(ghc, "Calibration jitter (%s) = %u", isFingerText, --pjit->calibrate);
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
} else if ((pem->meta & GMETA_MOUSE_UP))
|
||||
break;
|
||||
}
|
||||
if ((pem->buttons & GMETA_MOUSE_UP))
|
||||
break;
|
||||
}
|
||||
|
||||
// Calibrate
|
||||
ginputCalibrateMouse(0);
|
||||
calibrated = TRUE;
|
||||
|
||||
// Calibration used the whole screen - re-establish our title and Next and Previous Buttons
|
||||
gdispFillStringBox(0, 0, swidth, bHeight, "Touch Calibration", font, Green, White, justifyLeft);
|
||||
gdispFillStringBox(swidth-2*bWidth, 0, bWidth-1, bHeight, "Prev", font, Black, Gray, justifyCenter);
|
||||
gdispFillStringBox(swidth-1*bWidth, 0, bWidth , bHeight, "Next", font, Black, Gray, justifyCenter);
|
||||
if ((vmt->d.flags & GMOUSE_VFLG_CALIBRATE)) {
|
||||
calerr = ginputCalibrateMouse(0);
|
||||
if (calerr)
|
||||
goto StepCalibrate;
|
||||
isCalibrated = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test: Mouse coords
|
||||
*/
|
||||
|
||||
StepMouseCoords:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n4. Show Mouse Coordinates\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Press and hold the mouse button.\n\n");
|
||||
else
|
||||
DrawHeader("4. Show Mouse Coordinates", TRUE, TRUE, TRUE);
|
||||
if (isTouch)
|
||||
gwinPrintf(ghc, "Press and hold on the surface.\n\n");
|
||||
gwinPrintf(ghc, "Numbers will display in this window.\n"
|
||||
"Check the coordinates against where it should be on the screen.\n\n");
|
||||
|
||||
else
|
||||
gwinPrintf(ghc, "Press and hold the mouse button.\n\n");
|
||||
gwinPrintf(ghc, "Check the coordinates against where it should be on the screen.\n\n");
|
||||
gwinPrintf(ghc, "X should be 0 to %u\nY should be 0 to %u\n\n", swidth-1, sheight-1);
|
||||
gwinPrintf(ghc, "Press + to retry using extremes or - for normal calibration.\n");
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n");
|
||||
|
||||
// For this test normal mouse movement events
|
||||
@ -235,15 +318,23 @@ StepMouseCoords:
|
||||
// mind missing events for this test.
|
||||
gfxSleepMilliseconds(100);
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepCalibrate;
|
||||
}
|
||||
|
||||
switch (CheckButtons(pem)) {
|
||||
case BTN_NEXT:
|
||||
break;
|
||||
case BTN_PREV:
|
||||
goto StepCalibrate;
|
||||
case BTN_PLUS:
|
||||
vmt->d.flags |= GMOUSE_VFLG_CAL_EXTREMES;
|
||||
goto StepCalibrate;
|
||||
case BTN_MINUS:
|
||||
vmt->d.flags &= ~GMOUSE_VFLG_CAL_EXTREMES;
|
||||
goto StepCalibrate;
|
||||
default:
|
||||
gwinPrintf(ghc, "%u, %u\n", pem->x, pem->y);
|
||||
continue;
|
||||
}
|
||||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
gwinPrintf(ghc, "%u:%u z=%u\n", pem->x, pem->y, pem->z);
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset to just changed movements.
|
||||
@ -253,66 +344,41 @@ StepMouseCoords:
|
||||
* Test: Mouse movement jitter
|
||||
*/
|
||||
|
||||
StepJitter:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
if (deviceType == GEVENT_MOUSE)
|
||||
gwinPrintf(ghc, "Press and hold the mouse button and move around as if to draw.\n\n");
|
||||
else
|
||||
StepMovementJitter:
|
||||
DrawHeader("5. Movement Jitter", TRUE, TRUE, TRUE);
|
||||
if (isTouch)
|
||||
gwinPrintf(ghc, "Press firmly on the surface and move around as if to draw.\n\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Press and hold the mouse button and move around as if to draw.\n\n");
|
||||
|
||||
gwinPrintf(ghc, "Dots will display in this window. Ensure that when you stop moving your finger that "
|
||||
"new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n"
|
||||
"Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n");
|
||||
gwinPrintf(ghc, "Dots will display in this window. Ensure that when you stop moving your %s that "
|
||||
"new dots stop displaying.\nNew dots should only display when your %s is moving.\n\n"
|
||||
"Adjust %s movement jitter to the smallest value that this reliably works for.\n\n", deviceText, deviceText, isFingerText);
|
||||
gwinPrintf(ghc, "Movement jitter (%s) = %u\n", isFingerText, pjit->move);
|
||||
gwinPrintf(ghc, "Press + or - to adjust.\n");
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n\n");
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepMouseCoords;
|
||||
}
|
||||
switch (CheckButtons(pem)) {
|
||||
case BTN_NEXT:
|
||||
break;
|
||||
case BTN_PREV:
|
||||
goto StepMouseCoords;
|
||||
case BTN_PLUS:
|
||||
gwinPrintf(ghc, "Movement jitter (%s) = %u", isFingerText, ++pjit->move);
|
||||
continue;
|
||||
case BTN_MINUS:
|
||||
gwinPrintf(ghc, "Movement jitter (%s) = %u", isFingerText, --pjit->move);
|
||||
continue;
|
||||
default:
|
||||
if ((pem->buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
gwinPrintf(ghc, ".");
|
||||
continue;
|
||||
}
|
||||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
gwinPrintf(ghc, ".");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test: Polling frequency
|
||||
*/
|
||||
|
||||
StepPolling:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
gwinPrintf(ghc, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
|
||||
gwinPrintf(ghc, "A green line will follow your finger.\n"
|
||||
"Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without "
|
||||
"gaps that are too big.\nDecreasing the value increases CPU usage.\n"
|
||||
"About 25 (millisecs) normally produces good results."
|
||||
"This test can be ignored for interrupt driven drivers.\n\n");
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n\n");
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepJitter;
|
||||
}
|
||||
}
|
||||
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
|
||||
gdispDrawPixel(pem->x, pem->y, Green);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test: Click Jitter
|
||||
*/
|
||||
@ -320,38 +386,76 @@ StepPolling:
|
||||
StepClickJitter:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n");
|
||||
gwinPrintf(ghc, "\n6. Click Jitter\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
gwinPrintf(ghc, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n");
|
||||
gwinPrintf(ghc, "For a mouse click with the left and right buttons.\n\n");
|
||||
gwinPrintf(ghc, "Dots will display in this window. A yellow dash is a left (or short) click. "
|
||||
if (isTouch)
|
||||
gwinPrintf(ghc, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n");
|
||||
else
|
||||
gwinPrintf(ghc, "Click the mouse with the left and right buttons.\n\n");
|
||||
gwinPrintf(ghc, "A yellow dash is a left (or short) click.\n"
|
||||
"A red x is a right (or long) click.\n\n"
|
||||
"Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n"
|
||||
"Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n"
|
||||
"TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n"
|
||||
"Note: moving your finger (mouse) during a click cancels it.\n\n");
|
||||
gwinPrintf(ghc, "This is the last test but you can press Next or Back to continue.\n\n");
|
||||
"Adjust %s click jitter to the smallest value that this reliably works for.\n"
|
||||
"Note: moving your %s during a click cancels it.\n\n", isFingerText, deviceText);
|
||||
gwinPrintf(ghc, "Click jitter (%s) = %u\n", isFingerText, pjit->click);
|
||||
gwinPrintf(ghc, "Press + or - to adjust.\n");
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n\n");
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
switch (CheckButtons(pem)) {
|
||||
case BTN_NEXT:
|
||||
break;
|
||||
case BTN_PREV:
|
||||
goto StepMovementJitter;
|
||||
case BTN_PLUS:
|
||||
gwinPrintf(ghc, "Click jitter (%s) = %u", isFingerText, ++pjit->click);
|
||||
continue;
|
||||
case BTN_MINUS:
|
||||
gwinPrintf(ghc, "Click jitter (%s) = %u", isFingerText, --pjit->click);
|
||||
continue;
|
||||
default:
|
||||
if ((pem->buttons & GMETA_MOUSE_CLICK)) {
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "-");
|
||||
}
|
||||
if ((pem->buttons & GMETA_MOUSE_CXTCLICK)) {
|
||||
gwinSetColor(ghc, Red);
|
||||
gwinPrintf(ghc, "x");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test: Polling frequency
|
||||
*/
|
||||
|
||||
StepDrawing:
|
||||
gwinClear(ghc);
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "\n7. Drawing\n\n");
|
||||
|
||||
gwinSetColor(ghc, White);
|
||||
gwinPrintf(ghc, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
|
||||
gwinPrintf(ghc, "A green line will follow your %s.\n\n", deviceText);
|
||||
gwinPrintf(ghc, "Pressing Next will start the tests again but with the option of changing pen/finger mode.\n\n");
|
||||
gwinPrintf(ghc, "Press Next or Back to continue.\n\n");
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
if (pem->y < bHeight && pem->x >= swidth-2*bWidth) {
|
||||
if ((pem->meta & GMETA_MOUSE_UP)) {
|
||||
if ((pem->buttons & GMETA_MOUSE_UP)) {
|
||||
if (pem->x >= swidth-bWidth)
|
||||
break;
|
||||
goto StepPolling;
|
||||
goto StepClickJitter;
|
||||
}
|
||||
}
|
||||
if ((pem->meta & GMETA_MOUSE_CLICK)) {
|
||||
gwinSetColor(ghc, Yellow);
|
||||
gwinPrintf(ghc, "-");
|
||||
}
|
||||
if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
|
||||
gwinSetColor(ghc, Red);
|
||||
gwinPrintf(ghc, "x");
|
||||
}
|
||||
gdispDrawPixel(pem->x, pem->y, Green);
|
||||
}
|
||||
|
||||
// Can't let this really exit
|
||||
isFirstTime = FALSE;
|
||||
goto StepDeviceType;
|
||||
}
|
||||
|
62
tools/touch_raw_readings/gfxconf.h
Normal file
62
tools/touch_raw_readings/gfxconf.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _GFXCONF_H
|
||||
#define _GFXCONF_H
|
||||
|
||||
/* The operating system to use. One of these must be defined - preferably in your Makefile */
|
||||
//#define GFX_USE_OS_CHIBIOS FALSE
|
||||
//#define GFX_USE_OS_WIN32 FALSE
|
||||
//#define GFX_USE_OS_LINUX FALSE
|
||||
//#define GFX_USE_OS_OSX FALSE
|
||||
|
||||
/* GFX sub-systems to turn on */
|
||||
#define GFX_USE_GDISP TRUE
|
||||
#define GFX_USE_GWIN TRUE
|
||||
#define GFX_USE_GEVENT TRUE
|
||||
#define GFX_USE_GTIMER TRUE
|
||||
#define GFX_USE_GINPUT TRUE
|
||||
|
||||
/* Features for the GDISP sub-system. */
|
||||
#define GDISP_NEED_VALIDATION TRUE
|
||||
#define GDISP_NEED_CLIP TRUE
|
||||
#define GDISP_NEED_TEXT TRUE
|
||||
#define GDISP_NEED_MULTITHREAD TRUE
|
||||
|
||||
/* Builtin Fonts */
|
||||
#define GDISP_INCLUDE_FONT_UI2 TRUE
|
||||
|
||||
/* Features for the GWIN sub-system. */
|
||||
#define GWIN_NEED_CONSOLE TRUE
|
||||
|
||||
/* Features for the GINPUT sub-system. */
|
||||
#define GINPUT_NEED_MOUSE TRUE
|
||||
#define GINPUT_TOUCH_STARTRAW TRUE
|
||||
|
||||
#endif /* _GFXCONF_H */
|
110
tools/touch_raw_readings/main.c
Normal file
110
tools/touch_raw_readings/main.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Joel Bodenmann aka Tectu <joel@unormal.org>
|
||||
* Copyright (c) 2012, 2013, Andrew Hannam aka inmarket
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the <organization> nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
// We get nasty and look at some internal structures - get the relevant information
|
||||
#include "src/gdriver/sys_defs.h"
|
||||
#include "src/ginput/driver_mouse.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static GConsoleObject gc;
|
||||
static GListener gl;
|
||||
static font_t font;
|
||||
static coord_t bHeight;
|
||||
static GHandle ghc;
|
||||
static coord_t swidth, sheight;
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
* GINPUT Touch Driver Calibrator. *
|
||||
*------------------------------------------------------------------------*/
|
||||
int main(void) {
|
||||
GSourceHandle gs;
|
||||
GEventMouse *pem;
|
||||
GMouse * m;
|
||||
GMouseVMT * vmt;
|
||||
|
||||
gfxInit(); // Initialize the display
|
||||
|
||||
// Get the display dimensions
|
||||
swidth = gdispGetWidth();
|
||||
sheight = gdispGetHeight();
|
||||
|
||||
// Create our title
|
||||
font = gdispOpenFont("UI2");
|
||||
gwinSetDefaultFont(font);
|
||||
bHeight = gdispGetFontMetric(font, fontHeight)+4;
|
||||
gdispFillStringBox(0, 0, swidth, bHeight, "Raw Touch Readings", font, Red, White, justifyCenter);
|
||||
|
||||
// Create our main display writing window
|
||||
{
|
||||
GWindowInit wi;
|
||||
|
||||
gwinClearInit(&wi);
|
||||
wi.show = TRUE; wi.x = 0; wi.y = bHeight; wi.width = swidth; wi.height = sheight-bHeight;
|
||||
ghc = gwinConsoleCreate(&gc, &wi);
|
||||
}
|
||||
|
||||
// Initialize the listener
|
||||
geventListenerInit(&gl);
|
||||
|
||||
// Copy the current mouse's VMT so we can play with it.
|
||||
m = (GMouse *)gdriverGetInstance(GDRIVER_TYPE_MOUSE, 0);
|
||||
if (!m) gfxHalt("No mouse instance 0");
|
||||
vmt = gfxAlloc(sizeof(GMouseVMT));
|
||||
if (!vmt) gfxHalt("Could not allocate memory for mouse VMT");
|
||||
memcpy(vmt, m->d.vmt, sizeof(GMouseVMT));
|
||||
|
||||
// Swap VMT's on the current mouse to our RAM copy
|
||||
m->d.vmt = (const GDriverVMT *)vmt;
|
||||
|
||||
// Listen for events
|
||||
gs = ginputGetMouse(0);
|
||||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
|
||||
|
||||
// Make sure we are in uncalibrated pen mode
|
||||
m->flags &= ~(GMOUSE_FLG_CALIBRATE|GMOUSE_FLG_CLIP|GMOUSE_FLG_FINGERMODE);
|
||||
|
||||
// Pretend we are a mouse, turn off all touch processing, turn off move and click filtering
|
||||
vmt->d.flags &= ~(GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN);
|
||||
vmt->pen_jitter.move = 0;
|
||||
vmt->pen_jitter.click = 0;
|
||||
|
||||
// For this test turn on ALL mouse movement events
|
||||
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEUPMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
|
||||
|
||||
while(1) {
|
||||
pem = (GEventMouse *)geventEventWait(&gl, TIME_INFINITE);
|
||||
gwinPrintf(ghc, "%u, %u z=%u b=0x%04x\n", pem->x, pem->y, pem->z, pem->buttons & ~GINPUT_MISSED_MOUSE_EVENT);
|
||||
|
||||
// Always sleep a bit first to enable other events. We actually don't mind missing events.
|
||||
gfxSleepMilliseconds(100);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user