/**
 * \brief Handle maXTouch messages
 *
 * This function handles the maXTouch messages, triggering the drawing of
 * squares around new or moved touches, and removing the squares around
 * released touches.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_handler(struct mxt_device *device)
{
	static struct finger fingers[MAX_TOUCHES];
	static const gfx_color_t finger_colors[MAX_TOUCHES] = {
		GFX_COLOR_RED,
		GFX_COLOR_GREEN,
		GFX_COLOR_BLUE,
		GFX_COLOR_CYAN,
		GFX_COLOR_YELLOW,
		GFX_COLOR_MAGENTA,
		GFX_COLOR_WHITE,
		GFX_COLOR_GRAY,
	};
	struct mxt_touch_event touch_event;
	struct finger *curr_finger;
	uint8_t finger_index;

	do {
		/* Get the first touch event in queue */
		if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
			continue;
		}

		/* Discard non press, movement or release events */
		if (!(touch_event.status &
				(MXT_PRESS_EVENT | MXT_MOVE_EVENT | MXT_RELEASE_EVENT))) {
			continue;
		}

		/* Use the touch ID as finger index */
		finger_index = touch_event.id;

		/* Skip if touch ID is out of bounds */
		if (!(finger_index < MAX_TOUCHES)) {
			continue;
		}

		/* Get address of current finger info struct */
		curr_finger = &fingers[finger_index];

		/* If finger already registered (and thus drawn), clear it on the display */
		if (curr_finger->enable) {
			draw_finger_square(curr_finger, DISPLAY_COLOR);
		}

		/* Update finger info - finger is enabled unless it was released */
		curr_finger->enable = !(touch_event.status & MXT_RELEASE_EVENT);

		/* If the finger is now enabled, we need to update its position and redraw */
		if (curr_finger->enable) {
			/* Compute new display coordinates from touch coordinates */
			get_finger_display_coordinates(&touch_event, curr_finger);

			/* Draw updated representation on the display */
			draw_finger_square(curr_finger,
					finger_colors[finger_index]);
		}
	} while (mxt_is_message_pending(device));
}
Пример #2
0
/**
 * \brief Main application function
 *
 * This function executes the necessary initialization calls and displays the
 * demo widgets before entering the main work loop of the application.
 *
 * The main work loop reads out the touch events from the mXT143E Xplained and
 * enqueues the corresponding touch events in the window system, before
 * processing the window system's event queue.
 */
int main(void)
{
	static struct mxt_device device;

	board_init();
	sysclk_init();
	membag_init();
	gfx_init();
	mxt_init(&device);
	win_init();

	setup_root_window();
	app_widget_launch();

	while (true) {
		/* Process received messages from the maXTouch device */
		while (mxt_is_message_pending(&device)) {
			struct mxt_touch_event touch_event;
			struct win_pointer_event win_touch_event;

			/* Get the first touch event in queue */
			if (mxt_read_touch_event(&device,
					&touch_event) != STATUS_OK) {
				continue;
			}

			/* Translate touch event type into a WTK event type */
			if (touch_event.status & MXT_PRESS_EVENT) {
				win_touch_event.type = WIN_POINTER_PRESS;
			} else if (touch_event.status & MXT_MOVE_EVENT) {
				win_touch_event.type = WIN_POINTER_MOVE;
			} else if (touch_event.status & MXT_RELEASE_EVENT) {
				win_touch_event.type = WIN_POINTER_RELEASE;
			} else {
				continue;
			}

			/* Indicate the touch event is a non-relative movement
			 * with the virtual touch button pressed
			 */
			win_touch_event.is_relative = false;
			win_touch_event.buttons = WIN_TOUCH_BUTTON;

			/* Translate the touch X and Y position into a screen
			 * coordinate
			 */
			win_touch_event.pos.x =
					((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;
			win_touch_event.pos.y =
					((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;
			win_queue_pointer_event(&win_touch_event);
		}

		/* Process queued events in the windowing system */
		win_process_events();
	}
}
Пример #3
0
/**
 * \brief Convert touch events from the touchscreen into window pointer events
 *
 * Reads touch events in from the touchscreen and converts them into a
 * Window Manager pointer event, for enqueuing into the window event queue.
 *
 * \return Boolean true if a touch event was read, false if no touch event
 *         or a corrupt touch event was received
 */
static bool read_touch_event(struct mxt_device *device,
		struct win_pointer_event *win_touch_event)
{
	struct mxt_touch_event touch_event;

	/* Abort if no touch event is pending */
	if (!(mxt_is_message_pending(device))) {
		return false;
	}

	/* Get the first touch event in queue */
	if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
		return false;
	}

	/* Translate touch event type into a WTK event type */
	if (touch_event.status & MXT_PRESS_EVENT) {
		win_touch_event->type = WIN_POINTER_PRESS;
	} else if (touch_event.status & MXT_MOVE_EVENT) {
		win_touch_event->type = WIN_POINTER_MOVE;
	} else if (touch_event.status & MXT_RELEASE_EVENT) {
		win_touch_event->type = WIN_POINTER_RELEASE;
	} else {
		return false;
	}

	/* Indicate the touch event is a non-relative movement with the virtual
	 * touch button pressed
	 */
	win_touch_event->is_relative = false;
	win_touch_event->buttons = WIN_TOUCH_BUTTON;

	/* Translate the touch X and Y position into a screen coordinate */
	win_touch_event->pos.x =
			((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;
	win_touch_event->pos.y =
			((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;

	return true;
}
Пример #4
0
static void mxt_handler(struct mxt_device *device)
{
	/* USART tx buffer initialized to 0 */
	char tx_buf[STRING_LENGTH * MAX_ENTRIES] = {0};
	uint8_t i = 0; /* Iterator */

	/* Temporary touch event data struct */
	struct mxt_touch_event touch_event;

	/* Collect touch events and put the data in a string,
	 * maximum 2 events at the time */
	do {
		/* Temporary buffer for each new touch event line */
		char buf[STRING_LENGTH];
	
		/* Read next next touch event in the queue, discard if read fails */
		if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
			continue;
		}

		/* Format a new entry in the data string that will be sent over USART */
		sprintf(buf, "Nr: %1d, X:%4d, Y:%4d, Status:0x%2x\n\r",
				touch_event.id, touch_event.x, touch_event.y,
				touch_event.status);

		/* Add the new string to the string buffer */
		strcat(tx_buf, buf);
		i++;

		/* Check if there is still messages in the queue and
		 * if we have reached the maximum numbers of events */
	} while ((mxt_is_message_pending(device)) & (i < MAX_ENTRIES));

	/* If there is any entries in the buffer, send them over USART */
	if (i > 0) {
		usart_serial_write_packet(USART_SERIAL_EXAMPLE, (uint8_t *)tx_buf, strlen(tx_buf));
	}
}
Пример #5
0
/**
 * \brief Handle maXTouch messages
 *
 * This function handles the maXTouch messages, triggering the drawing of
 * squares around new or moved touches, and removing the squares around
 * released touches.
 *
 * \param device Pointer to mxt_device struct
 */
static void mxt_handler(struct mxt_device *device)
{
	struct mxt_touch_event touch_event;
	gfx_coord_t screen_touch_x, screen_touch_y, screen_touch_size;

	do {
		/* Get the first touch event in queue */
		if (mxt_read_touch_event(device, &touch_event) != STATUS_OK) {
			continue;
		}

		/* Discard non press, movement or release events */
		if (!(touch_event.status &
				(MXT_PRESS_EVENT | MXT_MOVE_EVENT | MXT_RELEASE_EVENT))) {
			continue;
		}

		/* Rescale from 4k touch X-coordinate to the display width */
		screen_touch_x = ((uint32_t)(4096 - touch_event.x) * gfx_get_width()) / 4096;

		/* Rescale from 4k touch Y-coordinate to the display height */
		screen_touch_y = ((uint32_t)(4096 - touch_event.y) * gfx_get_height()) / 4096;

		/* Scale the touch size to a value suitable for the target display */
		screen_touch_size = touch_event.size;

		/* Check if the touch is within the drawing area */
		if (screen_touch_y < (gfx_get_height() - PALLET_HEIGHT)) {
			/* Obtain the color to draw from the pallet colors */
			gfx_color_t draw_color = pallet_colors[selected_pallet_color];

			/* Color pallet index 0 selects multi-color mode */
			if (selected_pallet_color == 0) {
				draw_color = get_next_rainbow_color();
			}

			/* Set clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(),
					(gfx_get_height() - PALLET_HEIGHT - 2));

			/* Draw touch point on the screen in the selected color */
			gfx_draw_filled_circle(screen_touch_x, screen_touch_y,
					screen_touch_size, draw_color, GFX_WHOLE);

			/* Reset clipping area */
			gfx_set_clipping(0, 0, gfx_get_width(), gfx_get_height());

		} else if (touch_event.status & MXT_PRESS_EVENT) {
			/* Calculate the pressed pallet entry */
			uint8_t pallete_index = (screen_touch_x / PALLET_COLOR_WIDTH);

			/* The last entry in the pallet clears the screen */
			if (pallete_index == (NUM_PALLET_COLORS - 1)) {
				/* Indicate display is being cleared */
				draw_pallet_labels(true);

				/* Clear the display */
				gfx_draw_filled_rect(0, 0, gfx_get_width(),
						(gfx_get_height() - PALLET_HEIGHT - 1),
						GFX_COLOR_BLACK);

				/* Indicate display has been cleared */
				draw_pallet_labels(false);
			} else {
				/* Change color selection based on the color chosen */
				selected_pallet_color = pallete_index;

				/* Draw new selection box around chosen color */
				update_pallet_selection();
			}
		}

	} while (mxt_is_message_pending(device));
}
/**
 * \brief Main application function
 *
 * This function ensures that the hardware and drivers are initialized before
 * entering an infinite work loop.
 *
 * In the work loop, the maXTouch device is polled for new touch events and any
 * new event is passed on to the user interface implementation for processing.
 * The loop then attempts to enter sleep.
 *
 * The user interface processing itself is not started by the work loop, but by
 * the USB callback function for start of frame.
 */
int main(void)
{
#ifdef USB_DEVICE_LOW_SPEED
	uint16_t virtual_sof_sub;
	uint16_t virtual_sof;
#endif

	/* maXTouch data structure */
	static struct mxt_device device;

	/* Initialize system clocks */
	sysclk_init();

	/* Initialize interrupt vectors */
	irq_initialize_vectors();

	/* Enable interrupts */
	cpu_irq_enable();

	/* Initialize the sleep manager */
	sleepmgr_init();

	/* Initialize the board */
	board_init();

	/* Initialize the mXT touch device */
	mxt_init(&device);

	/* Initialize the graphical library */
	gfx_init();

	/* Set correct landscape orientation */
	gfx_set_orientation(GFX_SWITCH_XY | GFX_FLIP_Y);

	/* Set background color */
	gfx_draw_filled_rect(0, 0, gfx_get_width(), gfx_get_height(),
			COLOR_BACKGROUND);

	/* Draw the help text */
	gfx_draw_string_aligned(
			"Middle finger to move cursor\n"
			"Index finger to left click\n"
			"Ring finger to right click",
			gfx_get_width() / 2, gfx_get_height() / 2,
			&sysfont, GFX_COLOR_TRANSPARENT, GFX_COLOR_WHITE,
			TEXT_POS_CENTER, TEXT_ALIGN_CENTER);

	/* Initialize the user interface */
	ui_init();
	ui_powerdown();

	/* Start USB stack to authorize VBus monitoring */
	udc_start();

	/* Check if there are any new touch data pending */
	while (true) {
		if (mxt_is_message_pending(&device)) {
			if (mxt_read_touch_event(&device, &ui_touch_event) == STATUS_OK) {
				ui_flag_new_touch_event();
			}
		}

		/* Try to sleep */
		sleepmgr_enter_sleep();

#ifdef USB_DEVICE_LOW_SPEED
		/* No USB "Keep alive" interrupt available in low speed
		 * to scan mouse interface then use main loop */
		if (main_b_mouse_enable) {
			virtual_sof_sub = 0;
			virtual_sof = 0;
			if (virtual_sof_sub++ == 700) {
				virtual_sof_sub = 0;
				ui_process(virtual_sof++);
			}
		}
#endif
	}
}