New uGFXnetESP8266 driver. A gdisp driver for the ESP8266.
Not tested yet.
This commit is contained in:
parent
ea632d5001
commit
81505c8be2
@ -19,7 +19,7 @@ and a touchscreen driver.
|
||||
|
||||
2. To your makefile add the following lines:
|
||||
include $(GFXLIB)/gfx.mk
|
||||
include $(GFXLIB)/drivers/multiple/uGFXnet/gdisp_lld.mk
|
||||
include $(GFXLIB)/drivers/multiple/uGFXnet/driver.mk
|
||||
|
||||
3. Make sure you have networking libraries included in your Makefile.
|
||||
|
||||
|
2
drivers/multiple/uGFXnetESP8266/driver.mk
Normal file
2
drivers/multiple/uGFXnetESP8266/driver.mk
Normal file
@ -0,0 +1,2 @@
|
||||
GFXINC += $(GFXLIB)/drivers/multiple/uGFXnetESP8266
|
||||
GFXSRC += $(GFXLIB)/drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp
|
32
drivers/multiple/uGFXnetESP8266/gdisp_lld_config.h
Normal file
32
drivers/multiple/uGFXnetESP8266/gdisp_lld_config.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 _GDISP_LLD_CONFIG_H
|
||||
#define _GDISP_LLD_CONFIG_H
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver hardware support. */
|
||||
/*===========================================================================*/
|
||||
|
||||
// Calling gdispGFlush() is optional for this driver but can be used by the
|
||||
// application to force a display update. eg after streaming.
|
||||
|
||||
#define GDISP_HARDWARE_FLUSH TRUE
|
||||
#define GDISP_HARDWARE_DRAWPIXEL TRUE
|
||||
#define GDISP_HARDWARE_FILLS TRUE
|
||||
#define GDISP_HARDWARE_BITFILLS TRUE
|
||||
#define GDISP_HARDWARE_PIXELREAD TRUE
|
||||
#define GDISP_HARDWARE_SCROLL TRUE
|
||||
#define GDISP_HARDWARE_CONTROL TRUE
|
||||
|
||||
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
||||
|
||||
#endif /* _GDISP_LLD_CONFIG_H */
|
622
drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp
Normal file
622
drivers/multiple/uGFXnetESP8266/gdisp_lld_uGFXnetESP8266.cpp
Normal file
@ -0,0 +1,622 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// We need to include stdio.h below. Turn off GFILE_NEED_STDIO just for this file to prevent conflicts
|
||||
#define GFILE_NEED_STDIO_MUST_BE_OFF
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#if GFX_USE_GDISP
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
||||
#define GDISP_DRIVER_VMT GDISPVMT_uGFXnetESP8266
|
||||
#include "gdisp_lld_config.h"
|
||||
#include "../../../src/gdisp/gdisp_driver.h"
|
||||
#include "uGFXnetProtocol.h"
|
||||
|
||||
#ifndef GDISP_SCREEN_WIDTH
|
||||
#define GDISP_SCREEN_WIDTH 640
|
||||
#endif
|
||||
#ifndef GDISP_SCREEN_HEIGHT
|
||||
#define GDISP_SCREEN_HEIGHT 480
|
||||
#endif
|
||||
#ifndef GDISP_GFXNET_PORT
|
||||
#define GDISP_GFXNET_PORT GNETCODE_DEFAULT_PORT
|
||||
#endif
|
||||
#ifndef GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
#define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE
|
||||
#endif
|
||||
|
||||
static WiFiServer server(GDISP_GFXNET_PORT);
|
||||
static GTimer poller;
|
||||
static bool_t uGFXInitDone;
|
||||
|
||||
#ifndef GDISP_GFXNET_WIFI_INIT_FUNCTION
|
||||
#define GDISP_GFXNET_WIFI_INIT_FUNCTION uGFXnetArduinoWifiInit
|
||||
#ifndef GDISP_GFXNET_WIFI_SSID
|
||||
#error "uGFXnetArduino: GDISP_GFXNET_WIFI_SSID is not set. You must define the Wifi SSID"
|
||||
#endif
|
||||
#ifndef GDISP_GFXNET_WIFI_PASSWORD
|
||||
#error "uGFXnetArduino: GDISP_GFXNET_WIFI_PASSWORD is not set. You must define the Wifi password"
|
||||
#endif
|
||||
|
||||
static void uGFXnetArduinoWifiInit(WifiServer *ws) {
|
||||
WiFi.begin(GDISP_GFXNET_WIFI_SSID, GDISP_GFXNET_WIFI_PASSWORD);
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
gfxYield();
|
||||
|
||||
ws->begin();
|
||||
}
|
||||
#else
|
||||
extern "C" void GDISP_GFXNET_WIFI_INIT_FUNCTION(WifiServer *ws);
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
// Include mouse support code
|
||||
#define GMOUSE_DRIVER_VMT GMOUSEVMT_uGFXnet
|
||||
#include "../../../src/ginput/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: uGFXnetESP8266 - This driver only support protocol V1.0"
|
||||
#endif
|
||||
#if GDISP_LLD_PIXELFORMAT != GNETCODE_PIXELFORMAT
|
||||
#error "GDISP: uGFXnetESP8266 - The driver pixel format must match the protocol"
|
||||
#endif
|
||||
|
||||
#define GDISP_FLG_CONNECTED (GDISP_FLG_DRIVER<<0)
|
||||
#define GDISP_FLG_HAVEDATA (GDISP_FLG_DRIVER<<1)
|
||||
|
||||
#define CLIENTFD WifiClient *
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local routines . */
|
||||
/*===========================================================================*/
|
||||
|
||||
typedef struct netPriv {
|
||||
CLIENTFD netfd; // The current client
|
||||
unsigned databytes; // How many bytes have been read
|
||||
uint16_t data[2]; // Buffer for storing data read.
|
||||
#if GINPUT_NEED_MOUSE
|
||||
coord_t mousex, mousey;
|
||||
uint16_t mousebuttons;
|
||||
GMouse * mouse;
|
||||
#endif
|
||||
} netPriv;
|
||||
|
||||
#if GDISP_GFXNET_UNSAFE_SOCKETS
|
||||
static gfxMutex uGFXnetMutex;
|
||||
#define MUTEX_INIT gfxMutexInit(&uGFXnetMutex)
|
||||
#define MUTEX_ENTER gfxMutexEnter(&uGFXnetMutex)
|
||||
#define MUTEX_EXIT gfxMutexExit(&uGFXnetMutex)
|
||||
#else
|
||||
#define MUTEX_INIT
|
||||
#define MUTEX_ENTER
|
||||
#define MUTEX_EXIT
|
||||
#endif
|
||||
|
||||
static void endcon(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
|
||||
g->flags &= ~GDISP_FLG_CONNECTED;
|
||||
priv = g->priv;
|
||||
priv->netfd->stop();
|
||||
delete priv->netfd;
|
||||
priv->netfd = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a whole packet of data.
|
||||
* Len is specified in the number of uint16_t's we want to send as our protocol only talks uint16_t's.
|
||||
* Note that contents of the packet are modified to ensure it will cross the wire in the correct format.
|
||||
* If the connection closes before we send all the data - the call returns FALSE.
|
||||
*/
|
||||
static bool_t sendpkt(CLIENTFD fd, uint16_t *pkt, int len) {
|
||||
// Convert each uint16_t to network order
|
||||
#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < len; i++)
|
||||
pkt[i] = ((pkt[i]>>8)|(pkt[i]<<8));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Send it
|
||||
len *= sizeof(uint16_t);
|
||||
return fd->write((uint8_t *)pkt, len) == len;
|
||||
}
|
||||
|
||||
static void rxdata(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
CLIENTFD fd;
|
||||
int len;
|
||||
|
||||
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.
|
||||
return;
|
||||
}
|
||||
|
||||
priv = g->priv;
|
||||
fd = priv->netfd;
|
||||
|
||||
MUTEX_ENTER;
|
||||
// Are we still connected?
|
||||
if (!fd->connected()) {
|
||||
MUTEX_EXIT;
|
||||
endcon(g);
|
||||
return;
|
||||
}
|
||||
|
||||
// Is there data available
|
||||
if (!fd->available()) {
|
||||
MUTEX_EXIT;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the data
|
||||
if ((len = fd->read(((uint8_t *)priv->data)+priv->databytes, sizeof(priv->data)-priv->databytes, 0)) <= 0) {
|
||||
// Socket closed or in error state
|
||||
MUTEX_EXIT;
|
||||
endcon(g);
|
||||
return;
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Do we have a full reply yet
|
||||
priv->databytes += len;
|
||||
if (priv->databytes < sizeof(priv->data))
|
||||
return;
|
||||
priv->databytes = 0;
|
||||
|
||||
// Convert network byte or to host byte order
|
||||
#if GFX_CPU_ENDIAN == GFX_CPU_ENDIAN_LITTLE
|
||||
priv->data[0] = ((priv->data[0]>>8)|(priv->data[0]<<8))
|
||||
priv->data[1] = ((priv->data[1]>>8)|(priv->data[1]<<8))
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
void uGFXnetClientPoller(void *param) {
|
||||
GDisplay *g;
|
||||
(void) param;
|
||||
|
||||
// Is there a new server connection?
|
||||
if (server.hasClient()) {
|
||||
|
||||
// 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)) {
|
||||
netPriv * priv;
|
||||
|
||||
// Reset the priv area
|
||||
priv = g->priv;
|
||||
priv->netfd = new WifiClient(server.available());
|
||||
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
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look for a display that is connected so we can check if it has data
|
||||
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))
|
||||
rxdata(g);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
|
||||
// Initialise the receiver thread (if it hasn't been done already)
|
||||
if (!uGFXInitDone) {
|
||||
MUTEX_INIT;
|
||||
// Init and Start the poller
|
||||
GDISP_GFXNET_WIFI_INIT_FUNCTION(&server);
|
||||
|
||||
// Initialise the poller
|
||||
gtimerInit(&poller);
|
||||
gtimerStart(&poller, uGFXnetClientPoller, 0, TRUE, 50);
|
||||
uGFXInitDone = TRUE;
|
||||
}
|
||||
|
||||
// Create a private area for this window
|
||||
if (!(priv = gfxAlloc(sizeof(netPriv))))
|
||||
gfxHalt("GDISP: uGFXnetESP8266 - Memory allocation failed");
|
||||
memset(priv, 0, sizeof(netPriv));
|
||||
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;
|
||||
g->g.Backlight = 100;
|
||||
g->g.Contrast = 50;
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if GDISP_HARDWARE_FLUSH
|
||||
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[1];
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_FLUSH;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 1);
|
||||
MUTEX_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_HARDWARE_DRAWPIXEL
|
||||
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[4];
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_PIXEL;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = g->p.y;
|
||||
buf[3] = gdispColor2Native(g->p.color);
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 4);
|
||||
MUTEX_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ---- Optional Routines ---- */
|
||||
|
||||
#if GDISP_HARDWARE_FILLS
|
||||
LLDSPEC void gdisp_lld_fill_area(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[6];
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_FILL;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = g->p.y;
|
||||
buf[3] = g->p.cx;
|
||||
buf[4] = g->p.cy;
|
||||
buf[5] = gdispColor2Native(g->p.color);
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 6);
|
||||
MUTEX_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_HARDWARE_BITFILLS
|
||||
LLDSPEC void gdisp_lld_blit_area(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
pixel_t * buffer;
|
||||
uint16_t buf[5];
|
||||
coord_t x, y;
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
// Make everything relative to the start of the line
|
||||
buffer = g->p.ptr;
|
||||
buffer += g->p.x2*g->p.y1;
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_BLIT;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = g->p.y;
|
||||
buf[3] = g->p.cx;
|
||||
buf[4] = g->p.cy;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 5);
|
||||
|
||||
for(y = 0; y < g->p.cy; y++, buffer += g->p.x2 - g->p.cx) {
|
||||
for(x = 0; x < g->p.cx; x++, buffer++) {
|
||||
buf[0] = gdispColor2Native(buffer[0]);
|
||||
sendpkt(priv->netfd, buf, 1);
|
||||
}
|
||||
}
|
||||
MUTEX_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_HARDWARE_PIXELREAD
|
||||
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[3];
|
||||
color_t data;
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return 0;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_READ;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = g->p.y;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 3);
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Now wait for a reply
|
||||
while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_READ)
|
||||
gfxSleepMilliseconds(1);
|
||||
|
||||
data = gdispNative2Color(priv->data[1]);
|
||||
g->flags &= ~GDISP_FLG_HAVEDATA;
|
||||
|
||||
return data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL
|
||||
LLDSPEC void gdisp_lld_vertical_scroll(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[6];
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_SCROLL;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = g->p.y;
|
||||
buf[3] = g->p.cx;
|
||||
buf[4] = g->p.cy;
|
||||
buf[5] = g->p.y1;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 6);
|
||||
MUTEX_EXIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL
|
||||
LLDSPEC void gdisp_lld_control(GDisplay *g) {
|
||||
netPriv * priv;
|
||||
uint16_t buf[3];
|
||||
bool_t allgood;
|
||||
|
||||
#if GDISP_DONT_WAIT_FOR_NET_DISPLAY
|
||||
if (!(g->flags & GDISP_FLG_CONNECTED))
|
||||
return;
|
||||
#else
|
||||
while(!(g->flags & GDISP_FLG_CONNECTED))
|
||||
gfxSleepMilliseconds(200);
|
||||
#endif
|
||||
|
||||
// Check if we might support the code
|
||||
switch(g->p.x) {
|
||||
case GDISP_CONTROL_ORIENTATION:
|
||||
if (g->g.Orientation == (orientation_t)g->p.ptr)
|
||||
return;
|
||||
break;
|
||||
case GDISP_CONTROL_POWER:
|
||||
if (g->g.Powermode == (powermode_t)g->p.ptr)
|
||||
return;
|
||||
break;
|
||||
case GDISP_CONTROL_BACKLIGHT:
|
||||
if (g->g.Backlight == (uint16_t)(int)g->p.ptr)
|
||||
return;
|
||||
if ((uint16_t)(int)g->p.ptr > 100)
|
||||
g->p.ptr = (void *)100;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// Send the command
|
||||
priv = g->priv;
|
||||
buf[0] = GNETCODE_CONTROL;
|
||||
buf[1] = g->p.x;
|
||||
buf[2] = (uint16_t)(int)g->p.ptr;
|
||||
MUTEX_ENTER;
|
||||
sendpkt(priv->netfd, buf, 3);
|
||||
MUTEX_EXIT;
|
||||
|
||||
// Now wait for a reply
|
||||
while(!(g->flags & GDISP_FLG_HAVEDATA) || priv->data[0] != GNETCODE_CONTROL)
|
||||
gfxSleepMilliseconds(1);
|
||||
|
||||
// Extract the return status
|
||||
allgood = priv->data[1] ? TRUE : FALSE;
|
||||
g->flags &= ~GDISP_FLG_HAVEDATA;
|
||||
|
||||
// Do nothing more if the operation failed
|
||||
if (!allgood) return;
|
||||
|
||||
// Update the local stuff
|
||||
switch(g->p.x) {
|
||||
case GDISP_CONTROL_ORIENTATION:
|
||||
switch((orientation_t)g->p.ptr) {
|
||||
case GDISP_ROTATE_0:
|
||||
case GDISP_ROTATE_180:
|
||||
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||
break;
|
||||
case GDISP_ROTATE_90:
|
||||
case GDISP_ROTATE_270:
|
||||
g->g.Height = GDISP_SCREEN_WIDTH;
|
||||
g->g.Width = GDISP_SCREEN_HEIGHT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
g->g.Orientation = (orientation_t)g->p.ptr;
|
||||
break;
|
||||
case GDISP_CONTROL_POWER:
|
||||
g->g.Powermode = (powermode_t)g->p.ptr;
|
||||
break;
|
||||
case GDISP_CONTROL_BACKLIGHT:
|
||||
g->g.Backlight = (uint16_t)(int)g->p.ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if GINPUT_NEED_MOUSE
|
||||
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 = m->display;
|
||||
priv = g->priv;
|
||||
|
||||
pt->x = priv->mousex;
|
||||
pt->y = priv->mousey;
|
||||
pt->z = (priv->mousebuttons & GINPUT_MOUSE_BTN_LEFT) ? 1 : 0;
|
||||
pt->buttons = priv->mousebuttons;
|
||||
return TRUE;
|
||||
}
|
||||
#endif /* GINPUT_NEED_MOUSE */
|
||||
|
||||
#endif /* GFX_USE_GDISP */
|
41
drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h
Normal file
41
drivers/multiple/uGFXnetESP8266/ginput_lld_mouse_config.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
// This driver does not require rotation of co-ordinates for orientations other than 0.
|
||||
#define GINPUT_MOUSE_NO_ROTATION TRUE
|
||||
|
||||
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
|
30
drivers/multiple/uGFXnetESP8266/readme.txt
Normal file
30
drivers/multiple/uGFXnetESP8266/readme.txt
Normal file
@ -0,0 +1,30 @@
|
||||
To use this driver:
|
||||
|
||||
This driver is special in that it implements both the gdisp low level driver
|
||||
and a touchscreen driver.
|
||||
|
||||
1. Add in your gfxconf.h:
|
||||
a) #define GFX_USE_GDISP TRUE
|
||||
b) Optionally #define GFX_USE_GINPUT TRUE
|
||||
#define GINPUT_USE_MOUSE TRUE
|
||||
c) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD
|
||||
d) Optionally the following (with appropriate values):
|
||||
#define GDISP_SCREEN_WIDTH 640 // Virtual display width
|
||||
#define GDISP_SCREEN_HEIGHT 480 // Virtual display height
|
||||
#define GDISP_GFXNET_WIFI_INIT_FUNCTION MyWifiStart // Optionally specify if you want to
|
||||
// use your own wifi startup routine.
|
||||
// Prototype...
|
||||
// extern "C" void MyWifiStart(WifiServer *ws);
|
||||
#define GDISP_GFXNET_WIFI_SSID "ssid" // Your wifi SSID.
|
||||
// Not required if GDISP_GFXNET_WIFI_INIT_FUNCTION
|
||||
// is specified.
|
||||
#define GDISP_GFXNET_WIFI_PASSWORD "password" // Your wifi password.
|
||||
// Not required if GDISP_GFXNET_WIFI_INIT_FUNCTION
|
||||
// is specified.
|
||||
#define GDISP_DONT_WAIT_FOR_NET_DISPLAY FALSE // Don't halt waiting for the first connection
|
||||
$define GDISP_GFXNET_PORT 13001 // The TCP port the display sits on
|
||||
|
||||
|
||||
2. To your makefile (or Library) add the following lines:
|
||||
include $(GFXLIB)/gfx.mk
|
||||
include $(GFXLIB)/drivers/multiple/uGFXnetESP8266/driver.mk
|
34
drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h
Normal file
34
drivers/multiple/uGFXnetESP8266/uGFXnetProtocol.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define GNETCODE_VERSION GNETCODE_VERSION_1_0 // The current protocol version
|
||||
|
||||
// The list of possible protocol version numbers
|
||||
#define GNETCODE_VERSION_1_0 0x0100 // V1.0
|
||||
|
||||
// The required pixel format
|
||||
#define GNETCODE_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
|
||||
|
||||
// The default TCP/IP port
|
||||
#define GNETCODE_DEFAULT_PORT 13001
|
||||
|
||||
/**
|
||||
* All commands are sent in 16 bit blocks (2 bytes) in network order (BigEndian)
|
||||
* Across all uGFXnet protocol versions, the stream will always start with GNETCODE_INIT (0xFFFF) and then the version number.
|
||||
*/
|
||||
#define GNETCODE_INIT 0xFFFF // Followed by version,width,height,pixelformat,hasmouse
|
||||
#define GNETCODE_FLUSH 0x0000 // No following data
|
||||
#define GNETCODE_PIXEL 0x0001 // Followed by x,y,color
|
||||
#define GNETCODE_FILL 0x0002 // Followed by x,y,cx,cy,color
|
||||
#define GNETCODE_BLIT 0x0003 // Followed by x,y,cx,cy,bits
|
||||
#define GNETCODE_READ 0x0004 // Followed by x,y - Response is GNETCODE_READ,color
|
||||
#define GNETCODE_SCROLL 0x0005 // Followed by x,y,cx,cy,lines
|
||||
#define GNETCODE_CONTROL 0x0006 // Followed by what,data - Response is GNETCODE_CONTROL,0x0000 (fail) or GNETCODE_CONTROL,0x0001 (success)
|
||||
#define GNETCODE_MOUSE_X 0x0007 // This is only ever received - never sent. Response is GNETCODE_MOUSE_X,x
|
||||
#define GNETCODE_MOUSE_Y 0x0008 // This is only ever received - never sent. Response is GNETCODE_MOUSE_Y,y
|
||||
#define GNETCODE_MOUSE_B 0x0009 // This is only ever received - never sent. Response is GNETCODE_MOUSE_B,buttons. This is also the sync signal for mouse updates.
|
||||
#define GNETCODE_KILL 0xFFFE // This is only ever received - never sent. Response is GNETCODE_KILL,retcode
|
Loading…
Reference in New Issue
Block a user