Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions _examples/touch_calibration/touch_calibration.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/***************************************************************************
* Copyright (C) 2010, 2011, 2012, 2013, 2014 by Terraneo Federico *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* As a special exception, if other files instantiate templates or use *
* macros or inline functions from this file, or you compile this file *
* and link it with other works to produce a work based on this file, *
* this file does not by itself cause the resulting work to be covered *
* by the GNU General Public License. However the source code for this *
* file must still be made available in accordance with the GNU General *
* Public License. This exception does not invalidate any other reasons *
* why a work based on this file might be covered by the GNU General *
* Public License. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "mxgui/entry.h"
#include "mxgui/display.h"
#include "mxgui/misc_inst.h"
#include "mxgui/level2/input.h"
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace mxgui;

// function to draw the crosses
static void drawCross(DrawingContext &dc, Point c, int r)
{
dc.line(Point(c.x() - r, c.y()), Point(c.x() + r, c.y()), white);
dc.line(Point(c.x(), c.y() - r), Point(c.x(), c.y() + r), white);
}

struct Calib
{
double min, max;
};

// The transformation from RAW to pixels is performed through a linear transformation of the form:
// pixel = a * raw + b
static void calibrationFrom2Points(double raw1, double pix1, double raw2, double pix2, double W, Calib &out)
{
double a = (pix2 - pix1) / (raw2 - raw1);
double b = pix1 - a * raw1;

out.min = -b / a;
out.max = (W - b) / a;
}

ENTRY()
{
Display &display = DisplayManager::instance().getDisplay();
InputHandler &backend = InputHandler::instance();

// calibration reset
backend.setTouchscreenCalibration(0.0, 0.0, 0.0, 0.0);

const short w = display.getWidth() - 1;
const short h = display.getHeight() - 1;

short oldX = 0, oldY = 0;

// cross points array
Point targets[] = {
Point(30, 30),
Point(w - 30, 30),
Point(w - 30, h - 30),
Point(30, h - 30)};

enum State
{
WAIT_DOWN,
WAIT_UP
};
State state = WAIT_DOWN;

int idx = 0;

DrawingContext dc(display);
drawCross(dc, targets[idx], 20);

Point rawDatas[4];

for (;;)
{
Event e = backend.getEvent();

if (e.getEvent() != EventType::TouchDown && e.getEvent() != EventType::TouchMove && e.getEvent() != EventType::TouchUp)
{
continue;
}

if (state == WAIT_DOWN)
{
if (e.getEvent() == EventType::TouchDown)
{
rawDatas[idx] = e.getPoint();

// I wait for the touch-up before showing the next cross.
state = WAIT_UP;
}
}
else
{
if (e.getEvent() == EventType::TouchUp)
{
idx++;
if (idx >= 4)
{
dc.clear(black);

// compute the calibration parameters
Calib cx1, cy1, cx2, cy2;

calibrationFrom2Points((double)rawDatas[0].x(), (double)targets[0].x(),
(double)rawDatas[2].x(), (double)targets[2].x(),
w, cx1);

calibrationFrom2Points((double)rawDatas[0].y(), (double)targets[0].y(),
(double)rawDatas[2].y(), (double)targets[2].y(),
h, cy1);

calibrationFrom2Points((double)rawDatas[1].x(), (double)targets[1].x(),
(double)rawDatas[3].x(), (double)targets[3].x(),
w, cx2);

calibrationFrom2Points((double)rawDatas[1].y(), (double)targets[1].y(),
(double)rawDatas[3].y(), (double)targets[3].y(),
h, cy2);

cx1.max = (cx1.max + cx2.max) / 2;
cx1.min = (cx1.min + cx2.min) / 2;
cy1.max = (cy1.max + cy2.max) / 2;
cy1.min = (cy1.min + cy2.min) / 2;

backend.setTouchscreenCalibration(cx1.min, cx1.max, cy1.min, cy1.max);
for (;;)
{
Event e2 = backend.getEvent();
switch (e2.getEvent())
{
case EventType::ButtonA:
display.turnOff();
return 0;
case EventType::TouchDown:
case EventType::TouchUp:
case EventType::TouchMove:
{
dc.line(Point(0, oldY), Point(w, oldY), black);
dc.line(Point(oldX, 0), Point(oldX, h), black);
oldX = e2.getPoint().x();
oldY = e2.getPoint().y();

dc.line(Point(0, oldY), Point(w, oldY), white);
dc.line(Point(oldX, 0), Point(oldX, h), white);
char line[128];
siprintf(line, "(%d, %d) ", oldX, oldY);
dc.write(Point(0, 0), line);
break;
}
default:
break;
}
}
}

// mostra prossima croce
dc.clear(black);
drawCross(dc, targets[idx], 20);

state = WAIT_DOWN;
}
}
}
}
48 changes: 39 additions & 9 deletions drivers/event_st25dvdiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "event_st25dvdiscovery.h"
#include "miosix.h"
#include "kernel/scheduler/scheduler.h"
#include "util/software_i2c.h"
#include <algorithm>

Expand All @@ -43,17 +44,32 @@ using namespace miosix;

static Semaphore touchIntSema;

/**
* Touchscreen interrupt
*/
void __attribute__((naked)) EXTI9_5_IRQHandler()
{
saveContext();
asm volatile("bl EXTI9_5_HandlerImpl");
restoreContext();
}

/**
* Touchscreen interrupt actual implementation
*/
void EXTI9_5_HandlerImpl()
extern "C" void __attribute__((used)) EXTI9_5_HandlerImpl()
{
EXTI->PR = EXTI_PR_PR5;
touchIntSema.IRQsignal();
}

namespace mxgui {

static int g_xMin;
static int g_xMax;
static int g_yMin;
static int g_yMax;

typedef Gpio<GPIOC_BASE,14> buttonKey;
typedef Gpio<GPIOE_BASE,8> joySel;
typedef Gpio<GPIOE_BASE,9> joyLeft;
Expand Down Expand Up @@ -219,10 +235,17 @@ class STMPE811
const int xMax = 3800;
const int yMin = 220;
const int yMax = 3700;
x = (x - xMin) * 240 / (xMax - xMin);
y = (y - yMin) * 320 / (yMax - yMin);
x=min(239,max(0,x));
y=min(319,max(0,y));
int x = static_cast<int>(tsData[0]) << 4 | tsData[1] >> 4;
int y = ((static_cast<int>(tsData[1]) & 0xf) << 8) | tsData[2];
y = 4095 - y; // Y is swapped

if (g_xMax != g_xMin && g_yMax != g_yMin)
{
x = (x - g_xMin) * 240 / (g_xMax - g_xMin);
y = (y - g_yMin) * 320 / (g_yMax - g_yMin);
x = min(239, max(0, x));
y = min(319, max(0, y));
}

#if defined(MXGUI_ORIENTATION_VERTICAL)
lastTouchPoint=Point(x,y);
Expand Down Expand Up @@ -263,7 +286,7 @@ static std::function<void ()> eventCallback;
static void callback(Event e)
{
{
FastGlobalIrqLock dLock;
FastInterruptDisableLock dLock;
if(eventQueue.IRQput(e)==false) return;
}
if(eventCallback) eventCallback();
Expand Down Expand Up @@ -370,8 +393,7 @@ static void eventThread(void *)
InputHandlerImpl::InputHandlerImpl()
{
{
GlobalIrqLock dLock;
IRQregisterIrq(dLock,EXTI9_5_IRQn,&EXTI9_5_HandlerImpl);
FastInterruptDisableLock dLock;
buttonKey::mode(Mode::INPUT);
interrupt::mode(Mode::INPUT);
joySel::mode(Mode::INPUT);
Expand Down Expand Up @@ -401,6 +423,14 @@ InputHandlerImpl::InputHandlerImpl()
Thread::create(eventThread,STACK_MIN);
}

void InputHandlerImpl::setTouchscreenCalibration(double xMin, double xMax, double yMin, double yMax)
{
g_xMin = (int)xMin;
g_xMax = (int)xMax;
g_yMin = (int)yMin;
g_yMax = (int)yMax;
}

Event InputHandlerImpl::getEvent()
{
Event result;
Expand All @@ -410,7 +440,7 @@ Event InputHandlerImpl::getEvent()

Event InputHandlerImpl::popEvent()
{
FastGlobalIrqLock dLock;
FastInterruptDisableLock dLock;
Event result;
if(eventQueue.isEmpty() == false) {
eventQueue.IRQget(result);
Expand Down
2 changes: 2 additions & 0 deletions drivers/event_st25dvdiscovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class InputHandlerImpl
* \return the previous callback
*/
std::function<void ()> registerEventCallback(std::function<void ()> cb);

void setTouchscreenCalibration(double xMin, double xMax, double yMin, double yMax);
};

} //namespace mxgui
Expand Down
7 changes: 7 additions & 0 deletions level2/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ function<void ()> InputHandler::registerEventCallback(function<void ()> cb)
return pImpl->registerEventCallback(cb);
}

#if defined(_BOARD_STM32F415VG_ST25DVDISCOVERY)
void InputHandler::setTouchscreenCalibration(double xMin, double xMax, double yMin, double yMax)
{
pImpl->setTouchscreenCalibration(xMin, xMax, yMin, yMax);
}
#endif

InputHandler::InputHandler(InputHandlerImpl *impl) : pImpl(impl) {}

} //namespace mxgui
Expand Down
4 changes: 4 additions & 0 deletions level2/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ class InputHandler
*/
std::function<void ()> registerEventCallback(std::function<void ()> cb);

#if defined(_BOARD_STM32F415VG_ST25DVDISCOVERY)
void setTouchscreenCalibration(double xMin, double xMax, double yMin, double yMax);
#endif

private:
/**
* Class cannot be copied
Expand Down