Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/**
 * @brief   Read the mouse/touch position.
 *
 * @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.
 *
 * @notapi
 */
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(0xD1);
	for(i = 0; i < 7; i++)
		sampleBuf[i] = read_value(0xD1);
	read_value(0xD0);
	filter();
	lastx = (coord_t)sampleBuf[3];

	/* Get the Y value using the same process as above */
	read_value(0x91);
	for(i = 0; i < 7; i++)
		sampleBuf[i] = read_value(0x91);
	read_value(0x90);
	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;
}
Exemplo n.º 3
0
/**
 * 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;
}
Exemplo n.º 4
0
	/**
	 * @brief   Get the color of a particular pixel.
	 * @note    Optional.
	 * @note    If x,y is off the screen, the result is undefined.
	 *
	 * @param[in] x, y     The start of the text
	 *
	 * @notapi
	 */
	color_t GDISP_LLD(getpixelcolor)(coord_t x, coord_t y) {
		/* This routine is marked "DO NOT USE" in the original
		 *  GLCD driver. We just keep our GDISP_HARDWARE_READPIXEL
		 *  turned off for now.
		 */
		color_t color;

		#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
			if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
		#endif

		aquire_bus();
		set_cursor(x, y);
		stream_start();

		color = lld_lcdReadData();
		color = lld_lcdReadData();

		stream_stop();
		release_bus();

		return color;
	}
Exemplo n.º 5
0
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
		#if GDISP_NEED_CONTROL
			switch(gdispGGetOrientation(m->display)) {
			default:
			case GDISP_ROTATE_0:
			case GDISP_ROTATE_180:
				pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
				pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
				break;
			case GDISP_ROTATE_90:
			case GDISP_ROTATE_270:
				pdr->x = gdispGGetHeight(m->display) - pdr->x / (4096/gdispGGetHeight(m->display));
				pdr->y = pdr->y / (4096/gdispGGetWidth(m->display));
				break;
			}
		#else
			pdr->x = gdispGGetWidth(m->display) - pdr->x / (4096/gdispGGetWidth(m->display));
			pdr->y = pdr->y / (4096/gdispGGetHeight(m->display));
		#endif
	#endif

	return TRUE;
}