added more documentation
This commit is contained in:
parent
fc0c0f05fc
commit
7e098aa63a
27
src/config.c
27
src/config.c
|
@ -7,6 +7,7 @@
|
||||||
#include "scode.h"
|
#include "scode.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
/* command line options for UPIWIN */
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"framebuffer", required_argument, 0, 'F'},
|
{"framebuffer", required_argument, 0, 'F'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
|
@ -16,6 +17,7 @@ static const struct option long_options[] = {
|
||||||
|
|
||||||
static const char *short_options = "F:hT:";
|
static const char *short_options = "F:hT:";
|
||||||
|
|
||||||
|
/* printed to stdout when upiwin is executed with -h/--help option */
|
||||||
static const char *helptext =
|
static const char *helptext =
|
||||||
"UPIWIN - Micro Pi Windows server program\n\n"
|
"UPIWIN - Micro Pi Windows server program\n\n"
|
||||||
"Usage: upiwin [options] scriptname [scriptargs]\n\n"
|
"Usage: upiwin [options] scriptname [scriptargs]\n\n"
|
||||||
|
@ -25,19 +27,20 @@ static const char *helptext =
|
||||||
" -T,--touchscreen - Specifies the touchscreen device name\n"
|
" -T,--touchscreen - Specifies the touchscreen device name\n"
|
||||||
"";
|
"";
|
||||||
|
|
||||||
#define EXITFUNCBLOCK_FUNCCOUNT 64
|
#define EXITFUNCBLOCK_FUNCCOUNT 64 /* number of exit functions per function block */
|
||||||
|
|
||||||
|
/* exit functions are stored in these data blocks */
|
||||||
typedef struct tagEXITFUNCBLOCK
|
typedef struct tagEXITFUNCBLOCK
|
||||||
{
|
{
|
||||||
struct tagEXITFUNCBLOCK *next;
|
struct tagEXITFUNCBLOCK *next; /* chained in single linked list */
|
||||||
int num_funcs;
|
int num_funcs; /* number of functions this block contains */
|
||||||
PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT];
|
PEXITFUNC funcs[EXITFUNCBLOCK_FUNCCOUNT]; /* pointers to functions */
|
||||||
} EXITFUNCBLOCK, *PEXITFUNCBLOCK;
|
} EXITFUNCBLOCK, *PEXITFUNCBLOCK;
|
||||||
|
|
||||||
/* The global configuration data */
|
/* The global configuration data */
|
||||||
GLOBAL_CONFIG Gconfig;
|
GLOBAL_CONFIG Gconfig;
|
||||||
|
|
||||||
static PEXITFUNCBLOCK exitfuncs = NULL;
|
static PEXITFUNCBLOCK exitfuncs = NULL; /* pointer to head of exit function chain */
|
||||||
|
|
||||||
static void run_exit_funcs(void)
|
static void run_exit_funcs(void)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +53,7 @@ static void run_exit_funcs(void)
|
||||||
exitfuncs = p->next;
|
exitfuncs = p->next;
|
||||||
for (i = p->num_funcs - 1; i >= 0; i--)
|
for (i = p->num_funcs - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
/* execute functions in LIFO order */
|
||||||
ASSERT(p->funcs[i]);
|
ASSERT(p->funcs[i]);
|
||||||
(*(p->funcs[i]))();
|
(*(p->funcs[i]))();
|
||||||
}
|
}
|
||||||
|
@ -59,6 +63,7 @@ static void run_exit_funcs(void)
|
||||||
|
|
||||||
static void init_defaults(void)
|
static void init_defaults(void)
|
||||||
{
|
{
|
||||||
|
memset(&Gconfig, 0, sizeof(GLOBAL_CONFIG));
|
||||||
Gconfig.framebuffer_device = "/dev/fb1";
|
Gconfig.framebuffer_device = "/dev/fb1";
|
||||||
Gconfig.touchscreen_device = "/dev/input/touchscreen";
|
Gconfig.touchscreen_device = "/dev/input/touchscreen";
|
||||||
Gconfig.button_debounce = 100;
|
Gconfig.button_debounce = 100;
|
||||||
|
@ -79,7 +84,7 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
|
||||||
break;
|
break;
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'F':
|
case 'F': /* frame buffer device name */
|
||||||
pstr = strdup(optarg);
|
pstr = strdup(optarg);
|
||||||
if (!pstr)
|
if (!pstr)
|
||||||
{
|
{
|
||||||
|
@ -91,11 +96,11 @@ static HRESULT parse_cmdline(int argc, char *argv[], GLOBAL_CONFIG *parsed)
|
||||||
parsed->framebuffer_device = pstr;
|
parsed->framebuffer_device = pstr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h': /* show help */
|
||||||
help = TRUE;
|
help = TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T':
|
case 'T': /* touchscreen device name */
|
||||||
pstr = strdup(optarg);
|
pstr = strdup(optarg);
|
||||||
if (!pstr)
|
if (!pstr)
|
||||||
{
|
{
|
||||||
|
@ -138,10 +143,16 @@ HRESULT Config_setup(int argc, char *argv[])
|
||||||
Log(LFATAL, "Unable to set up exit function mechanism");
|
Log(LFATAL, "Unable to set up exit function mechanism");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set defaults */
|
||||||
init_defaults();
|
init_defaults();
|
||||||
|
|
||||||
|
/* evaluate command line */
|
||||||
hr = parse_cmdline(argc, argv, &from_commandline);
|
hr = parse_cmdline(argc, argv, &from_commandline);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
|
/* command line overrides everything */
|
||||||
overlay_config(&from_commandline);
|
overlay_config(&from_commandline);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
11
src/config.h
11
src/config.h
|
@ -5,14 +5,15 @@
|
||||||
|
|
||||||
typedef void (*PEXITFUNC)(void);
|
typedef void (*PEXITFUNC)(void);
|
||||||
|
|
||||||
|
/* global configuration data for UPIWIN */
|
||||||
typedef struct tagGLOBAL_CONFIG {
|
typedef struct tagGLOBAL_CONFIG {
|
||||||
PCSTR framebuffer_device;
|
PCSTR framebuffer_device; /* name of frame buffer device */
|
||||||
PCSTR touchscreen_device;
|
PCSTR touchscreen_device; /* name of touchscreen device */
|
||||||
UINT32 button_debounce;
|
UINT32 button_debounce; /* minimum time between button up and next button down (ms) */
|
||||||
UINT32 sys_mq_length;
|
UINT32 sys_mq_length; /* length of system message queue */
|
||||||
} GLOBAL_CONFIG;
|
} GLOBAL_CONFIG;
|
||||||
|
|
||||||
extern GLOBAL_CONFIG Gconfig;
|
extern GLOBAL_CONFIG Gconfig; /* one global configuration to rule them all */
|
||||||
|
|
||||||
extern HRESULT Config_setup(int argc, char *argv[]);
|
extern HRESULT Config_setup(int argc, char *argv[]);
|
||||||
extern HRESULT Config_exitfunc(PEXITFUNC pfn);
|
extern HRESULT Config_exitfunc(PEXITFUNC pfn);
|
||||||
|
|
16
src/fbinit.c
16
src/fbinit.c
|
@ -16,12 +16,13 @@ extern uint8_t _binary_splash_bin_start[];
|
||||||
extern uint8_t _binary_splash_bin_end;
|
extern uint8_t _binary_splash_bin_end;
|
||||||
extern uint8_t _binary_splash_bin_size;
|
extern uint8_t _binary_splash_bin_size;
|
||||||
|
|
||||||
static int fb_fd = -1;
|
static int fb_fd = -1; /* framebuffer file descriptor */
|
||||||
|
|
||||||
|
/* frame buffer information */
|
||||||
static FBINFO local_info;
|
static FBINFO local_info;
|
||||||
PCFBINFO Fb_Info = &local_info;
|
PCFBINFO Fb_Info = &local_info;
|
||||||
|
|
||||||
UINT16 *Fb_Ptr = NULL;
|
UINT16 *Fb_Ptr = NULL; /* pointer to memory-mapped frame buffer */
|
||||||
|
|
||||||
inline static UINT16 makemask(unsigned offset, unsigned length)
|
inline static UINT16 makemask(unsigned offset, unsigned length)
|
||||||
{
|
{
|
||||||
|
@ -30,12 +31,11 @@ inline static UINT16 makemask(unsigned offset, unsigned length)
|
||||||
|
|
||||||
static void do_cleanup(void)
|
static void do_cleanup(void)
|
||||||
{
|
{
|
||||||
/* additional cleanup here */
|
/* black out the display */
|
||||||
|
|
||||||
memset(Fb_Ptr, 0, local_info.screenbytes);
|
memset(Fb_Ptr, 0, local_info.screenbytes);
|
||||||
|
|
||||||
munmap((void *)Fb_Ptr, local_info.screenbytes);
|
munmap((void *)Fb_Ptr, local_info.screenbytes);
|
||||||
Fb_Ptr = NULL;
|
Fb_Ptr = NULL;
|
||||||
|
|
||||||
close(fb_fd);
|
close(fb_fd);
|
||||||
fb_fd = -1;
|
fb_fd = -1;
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,11 @@ HRESULT Fb_setup(void)
|
||||||
if (fb_fd == -1)
|
if (fb_fd == -1)
|
||||||
{
|
{
|
||||||
hr = ERRNO_AS_SCODE;
|
hr = ERRNO_AS_SCODE;
|
||||||
Log(LFATAL, "Unable to open framebuffer (%08X)", hr);
|
Log(LFATAL, "Unable to open framebuffer device %s (%08X)", Gconfig.framebuffer_device, hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fixed info is needed to get the memory parameters for the display */
|
||||||
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed))
|
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixed))
|
||||||
{
|
{
|
||||||
hr = ERRNO_AS_SCODE;
|
hr = ERRNO_AS_SCODE;
|
||||||
|
@ -64,6 +65,7 @@ HRESULT Fb_setup(void)
|
||||||
local_info.linebytes = fixed.line_length;
|
local_info.linebytes = fixed.line_length;
|
||||||
local_info.screenbytes = fixed.smem_len;
|
local_info.screenbytes = fixed.smem_len;
|
||||||
|
|
||||||
|
/* variable info is used to get scren geometry and color info */
|
||||||
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
|
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
|
||||||
{
|
{
|
||||||
hr = ERRNO_AS_SCODE;
|
hr = ERRNO_AS_SCODE;
|
||||||
|
@ -100,8 +102,6 @@ HRESULT Fb_setup(void)
|
||||||
/* display the splash screen */
|
/* display the splash screen */
|
||||||
memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size));
|
memcpy(Fb_Ptr, _binary_splash_bin_start, (size_t)(&_binary_splash_bin_size));
|
||||||
|
|
||||||
/* additional setup here */
|
|
||||||
|
|
||||||
hr = Config_exitfunc(do_cleanup);
|
hr = Config_exitfunc(do_cleanup);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
do_cleanup();
|
do_cleanup();
|
||||||
|
|
37
src/fbinit.h
37
src/fbinit.h
|
@ -3,28 +3,29 @@
|
||||||
|
|
||||||
#include "wintype.h"
|
#include "wintype.h"
|
||||||
|
|
||||||
|
/* info about the frame buffer */
|
||||||
typedef struct tagFBINFO {
|
typedef struct tagFBINFO {
|
||||||
UINT32 width;
|
UINT32 width; /* screen width */
|
||||||
UINT32 height;
|
UINT32 height; /* screen height */
|
||||||
UINT32 virtual_width;
|
UINT32 virtual_width; /* virtual screen width */
|
||||||
UINT32 virtual_height;
|
UINT32 virtual_height; /* virtual screen height */
|
||||||
UINT32 bpp;
|
UINT32 bpp; /* bits per pixel (16) */
|
||||||
UINT32 linebytes;
|
UINT32 linebytes; /* number of bytes per line */
|
||||||
UINT32 screenbytes;
|
UINT32 screenbytes; /* number of bytes for the entire screen */
|
||||||
UINT16 red_offset;
|
UINT16 red_offset; /* offset of "red" bits within pixel word (11) */
|
||||||
UINT16 red_length;
|
UINT16 red_length; /* number of "red" bits within pixel word (5) */
|
||||||
UINT16 red_mask;
|
UINT16 red_mask; /* mask for the "red" bits in a pixel word */
|
||||||
UINT16 green_offset;
|
UINT16 green_offset; /* offset of "green" bits within pixel word (5) */
|
||||||
UINT16 green_length;
|
UINT16 green_length; /* number of "green" bits within pixel word (6) */
|
||||||
UINT16 green_mask;
|
UINT16 green_mask; /* mask for the "green" bits in a pixel word */
|
||||||
UINT16 blue_offset;
|
UINT16 blue_offset; /* offset of "blue" bits within pixel word (0) */
|
||||||
UINT16 blue_length;
|
UINT16 blue_length; /* number of "blue" bits within pixel word (5) */
|
||||||
UINT16 blue_mask;
|
UINT16 blue_mask; /* mask for the "blue" bits in a pixel word */
|
||||||
} FBINFO;
|
} FBINFO;
|
||||||
typedef const FBINFO * const PCFBINFO;
|
typedef const FBINFO * const PCFBINFO;
|
||||||
|
|
||||||
extern PCFBINFO Fb_Info;
|
extern PCFBINFO Fb_Info; /* pointer to screen information */
|
||||||
extern UINT16 *Fb_Ptr;
|
extern UINT16 *Fb_Ptr; /* pointer to memory-mapped screen buffer */
|
||||||
|
|
||||||
extern HRESULT Fb_setup(void);
|
extern HRESULT Fb_setup(void);
|
||||||
extern void Fb_clear(void);
|
extern void Fb_clear(void);
|
||||||
|
|
|
@ -25,6 +25,7 @@ void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor)
|
||||||
INT32 dx = x2 - x1;
|
INT32 dx = x2 - x1;
|
||||||
INT32 dy = y2 - y1;
|
INT32 dy = y2 - y1;
|
||||||
|
|
||||||
|
/* uses Bresenham's line algorithm with fixed-point arithmetic */
|
||||||
if (ABS(dx) < ABS(dy))
|
if (ABS(dx) < ABS(dy))
|
||||||
{
|
{
|
||||||
if (y1 > y2)
|
if (y1 > y2)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "wintype.h"
|
#include "wintype.h"
|
||||||
|
|
||||||
|
/* Some predefined "primitive" color values */
|
||||||
#define FBPRIMCLR_BLACK 0x0000
|
#define FBPRIMCLR_BLACK 0x0000
|
||||||
#define FBPRIMCLR_RED 0xF800
|
#define FBPRIMCLR_RED 0xF800
|
||||||
#define FBPRIMCLR_GREEN 0x07E0
|
#define FBPRIMCLR_GREEN 0x07E0
|
||||||
|
|
|
@ -5,13 +5,14 @@
|
||||||
#include "scode.h"
|
#include "scode.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
/* GPIO lines used by various peripheral devices */
|
||||||
#define GLINE_BUTTON1 17
|
#define GLINE_BUTTON1 17
|
||||||
#define GLINE_BUTTON2 22
|
#define GLINE_BUTTON2 22
|
||||||
#define GLINE_BUTTON3 23
|
#define GLINE_BUTTON3 23
|
||||||
#define GLINE_BUTTON4 27
|
#define GLINE_BUTTON4 27
|
||||||
#define GLINE_BACKLIGHT 18
|
#define GLINE_BACKLIGHT 18
|
||||||
|
|
||||||
#define PWM_BACKLIGHT 0
|
#define PWM_BACKLIGHT 0 /* PWM channel used for backlight */
|
||||||
|
|
||||||
static void do_cleanup(void)
|
static void do_cleanup(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,14 +3,15 @@
|
||||||
|
|
||||||
#include "wintype.h"
|
#include "wintype.h"
|
||||||
|
|
||||||
#define GPIO_BUTTON_COUNT 4
|
#define GPIO_BUTTON_COUNT 4 /* number of GPIO buttons we have */
|
||||||
|
|
||||||
|
/* state flags for the GPIO buttons */
|
||||||
#define GRB_STATE_BUTTON1 (1 << 0)
|
#define GRB_STATE_BUTTON1 (1 << 0)
|
||||||
#define GRB_STATE_BUTTON2 (1 << 1)
|
#define GRB_STATE_BUTTON2 (1 << 1)
|
||||||
#define GRB_STATE_BUTTON3 (1 << 2)
|
#define GRB_STATE_BUTTON3 (1 << 2)
|
||||||
#define GRB_STATE_BUTTON4 (1 << 3)
|
#define GRB_STATE_BUTTON4 (1 << 3)
|
||||||
|
|
||||||
#define GSB_BACKLIGHT_MAX 1023
|
#define GSB_BACKLIGHT_MAX 1023 /* maximum level for backlight */
|
||||||
|
|
||||||
extern HRESULT Gpio_setup(void);
|
extern HRESULT Gpio_setup(void);
|
||||||
extern UINT32 Gpio_read_buttons(void);
|
extern UINT32 Gpio_read_buttons(void);
|
||||||
|
|
|
@ -4,8 +4,11 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
/* string equivalents to the severity values */
|
||||||
static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" };
|
static const char *severities[] = { "FATAL", "ERROR", "WARN ", "INFO ", "DEBUG" };
|
||||||
|
|
||||||
|
static FILE *logfile = stdout; /* log file pointer */
|
||||||
|
|
||||||
void Log(int level, const char *format, ...)
|
void Log(int level, const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list argp;
|
va_list argp;
|
||||||
|
@ -21,7 +24,7 @@ void Log(int level, const char *format, ...)
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
localtime_r(&(tv.tv_sec), &tm);
|
localtime_r(&(tv.tv_sec), &tm);
|
||||||
strftime(timestamp, 32, "%F %T", &tm);
|
strftime(timestamp, 32, "%F %T", &tm);
|
||||||
printf("%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf);
|
fprintf(logfile, "%s.%06u %s %s\n", timestamp, tv.tv_usec, severities[level], buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Log_assert_failed(const char *test, const char *file, int line)
|
void Log_assert_failed(const char *test, const char *file, int line)
|
||||||
|
|
13
src/log.h
13
src/log.h
|
@ -1,18 +1,21 @@
|
||||||
#ifndef __LOG_H_INCLUDED
|
#ifndef __LOG_H_INCLUDED
|
||||||
#define __LOG_H_INCLUDED
|
#define __LOG_H_INCLUDED
|
||||||
|
|
||||||
#define LFATAL 0
|
/* Logging level severities */
|
||||||
#define LERROR 1
|
#define LFATAL 0 /* fatal error */
|
||||||
#define LWARN 2
|
#define LERROR 1 /* error */
|
||||||
#define LINFO 3
|
#define LWARN 2 /* warning */
|
||||||
#define LDEBUG 4
|
#define LINFO 3 /* information */
|
||||||
|
#define LDEBUG 4 /* debugging */
|
||||||
|
|
||||||
extern void Log(int level, const char *format, ...);
|
extern void Log(int level, const char *format, ...);
|
||||||
extern void Log_assert_failed(const char *test, const char *file, int line);
|
extern void Log_assert_failed(const char *test, const char *file, int line);
|
||||||
|
|
||||||
|
/* Current file name definitions for assert macros */
|
||||||
#define THIS_FILE __FILE__
|
#define THIS_FILE __FILE__
|
||||||
#define DECLARE_THIS_FILE() static const char THIS_FILE[] = __FILE__
|
#define DECLARE_THIS_FILE() static const char THIS_FILE[] = __FILE__
|
||||||
|
|
||||||
|
/* Assert macros */
|
||||||
#ifdef DEBUG_ASSERT
|
#ifdef DEBUG_ASSERT
|
||||||
#define ASSERT(x) ((x) ? (void)0 : Log_assert_failed(#x, THIS_FILE, __LINE__))
|
#define ASSERT(x) ((x) ? (void)0 : Log_assert_failed(#x, THIS_FILE, __LINE__))
|
||||||
#define VERIFY(x) ASSERT(x)
|
#define VERIFY(x) ASSERT(x)
|
||||||
|
|
|
@ -35,6 +35,7 @@ int main(int argc, char *argv[])
|
||||||
MSG msg;
|
MSG msg;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
/* initialization sequence */
|
||||||
Time_init();
|
Time_init();
|
||||||
hr = Config_setup(argc, argv);
|
hr = Config_setup(argc, argv);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
@ -48,7 +49,7 @@ int main(int argc, char *argv[])
|
||||||
if (FAILED(Sys_enable_input()))
|
if (FAILED(Sys_enable_input()))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
Log(LINFO, "Pausing at startup.");
|
Log(LINFO, "Pausing at startup.");
|
||||||
sleep(5); /* wait to show off splash screen */
|
sleep(3); /* wait to show off splash screen */
|
||||||
|
|
||||||
Fb_clear();
|
Fb_clear();
|
||||||
/* temporary drawing here */
|
/* temporary drawing here */
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
#ifndef __MSG_QUEUE_H_INCLUDED
|
#ifndef __MSG_QUEUE_H_INCLUDED
|
||||||
#define __MSG_QUEUE_H_INCLUDED
|
#define __MSG_QUEUE_H_INCLUDED
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include "wintype.h"
|
#include "wintype.h"
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
|
|
||||||
|
/* internal structure of a message queue */
|
||||||
typedef struct tagMSG_QUEUE {
|
typedef struct tagMSG_QUEUE {
|
||||||
struct tagMSG_QUEUE *next;
|
struct tagMSG_QUEUE *next; /* allow us to be in a singly-linked list */
|
||||||
PMSG startbound;
|
PMSG startbound; /* start boundary for message buffer */
|
||||||
PMSG endbound;
|
PMSG endbound; /* end boundary for message buffer */
|
||||||
PMSG head;
|
PMSG head; /* head pointer of message queue */
|
||||||
PMSG tail;
|
PMSG tail; /* tail pointer of message queue */
|
||||||
UINT32 nentries;
|
UINT32 nentries; /* number of entries possible in message buffer */
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex; /* controls access to queue from multiple threads */
|
||||||
MSG messagestore[0];
|
MSG messagestore[0]; /* message buffer */
|
||||||
} MSG_QUEUE, *PMSG_QUEUE;
|
} MSG_QUEUE, *PMSG_QUEUE;
|
||||||
|
|
||||||
#define PEEK_REMOVE 0x0001
|
/* flags to Mq_peek */
|
||||||
#define PEEK_NOREMOVE 0x0000
|
#define PEEK_REMOVE 0x0001 /* remove message if found */
|
||||||
|
#define PEEK_NOREMOVE 0x0000 /* do not remove message if found */
|
||||||
|
|
||||||
extern PMSG_QUEUE Mq_alloc(UINT32 nentries);
|
extern PMSG_QUEUE Mq_alloc(UINT32 nentries);
|
||||||
extern void Mq_destroy(PMSG_QUEUE queue);
|
extern void Mq_destroy(PMSG_QUEUE queue);
|
||||||
|
|
|
@ -13,20 +13,22 @@
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "time_func.h"
|
#include "time_func.h"
|
||||||
|
|
||||||
#define INPUT_EVENT_BATCH 16
|
#define INPUT_EVENT_BATCH 16 /* number of events to retrieve from touchscreen at once */
|
||||||
|
|
||||||
PMSG_QUEUE Sys_Queue = NULL;
|
PMSG_QUEUE Sys_Queue = NULL; /* system message queue */
|
||||||
|
static int ts_fd = 0; /* file descriptor for touchscreen */
|
||||||
|
|
||||||
static pthread_t ithread;
|
static pthread_t ithread; /* input thread handle */
|
||||||
static volatile sig_atomic_t running = 1;
|
static volatile sig_atomic_t running = 1; /* "running" flag for input thread */
|
||||||
static int ts_fd = 0;
|
|
||||||
|
|
||||||
static UINT32 last_bstate = 0;
|
/* Local data for poll_buttons() */
|
||||||
static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT];
|
static UINT32 last_bstate = 0; /* previous button state */
|
||||||
|
static TIMESTAMP button_event_ok[GPIO_BUTTON_COUNT]; /* timestamps to debounce events */
|
||||||
|
|
||||||
static UINT_PTR touch_x = 0;
|
/* Local data for poll_touchscreen() */
|
||||||
static UINT_PTR touch_y = 0;
|
static UINT_PTR touch_x = 0; /* X coordinate to send with next message */
|
||||||
static UINT32 touch_nextmsg = WM_TOUCHMOVE;
|
static UINT_PTR touch_y = 0; /* Y coordinate to send with next message */
|
||||||
|
static UINT32 touch_nextmsg = WM_TOUCHMOVE; /* identifier of next message to send */
|
||||||
|
|
||||||
static void poll_buttons(void)
|
static void poll_buttons(void)
|
||||||
{
|
{
|
||||||
|
@ -44,9 +46,10 @@ static void poll_buttons(void)
|
||||||
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
|
for (attr = 1, mask = GRB_STATE_BUTTON1; attr <= GPIO_BUTTON_COUNT; attr++, mask <<= 1)
|
||||||
{
|
{
|
||||||
if (now < button_event_ok[attr - 1])
|
if (now < button_event_ok[attr - 1])
|
||||||
continue;
|
continue; /* this is a "contact bounce" event, don't bother */
|
||||||
if (up & mask)
|
if (up & mask)
|
||||||
{
|
{
|
||||||
|
/* reset contact bounce timer - only seems to happen after button releases */
|
||||||
button_event_ok[attr - 1] = now + Gconfig.button_debounce;
|
button_event_ok[attr - 1] = now + Gconfig.button_debounce;
|
||||||
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
|
Mq_post1(Sys_Queue, 0, WM_HWBUTTONUP, attr);
|
||||||
}
|
}
|
||||||
|
@ -75,10 +78,12 @@ static void poll_touchscreen(void)
|
||||||
Log(LERROR, "Unexpected end of file reading from touchscreen device");
|
Log(LERROR, "Unexpected end of file reading from touchscreen device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nev = nb / sizeof(struct input_event);
|
nev = nb / sizeof(struct input_event);
|
||||||
xerrno = nev * sizeof(struct input_event);
|
xerrno = nev * sizeof(struct input_event);
|
||||||
if (nb > xerrno)
|
if (nb > xerrno)
|
||||||
Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno);
|
Log(LERROR, "read %d bytes from touchscreen but we can only use %d", nb, xerrno);
|
||||||
|
|
||||||
for (i=0; i<nev; i++)
|
for (i=0; i<nev; i++)
|
||||||
{
|
{
|
||||||
switch (buffer[i].type)
|
switch (buffer[i].type)
|
||||||
|
@ -111,6 +116,7 @@ static void poll_touchscreen(void)
|
||||||
|
|
||||||
static void *input_thread(void *arg)
|
static void *input_thread(void *arg)
|
||||||
{
|
{
|
||||||
|
/* clear all state at startup */
|
||||||
last_bstate = 0;
|
last_bstate = 0;
|
||||||
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
|
memset(button_event_ok, 0, GPIO_BUTTON_COUNT * sizeof(TIMESTAMP));
|
||||||
touch_x = touch_y = 0;
|
touch_x = touch_y = 0;
|
||||||
|
@ -151,7 +157,7 @@ HRESULT Sys_enable_input(void)
|
||||||
{
|
{
|
||||||
rc = ERRNO_AS_SCODE;
|
rc = ERRNO_AS_SCODE;
|
||||||
Mq_destroy(Sys_Queue);
|
Mq_destroy(Sys_Queue);
|
||||||
Log(LFATAL, "Unable to open touchscreen device (%08X).", rc);
|
Log(LFATAL, "Unable to open touchscreen device %s (%08X).", Gconfig.touchscreen_device, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "time_func.h"
|
#include "time_func.h"
|
||||||
|
|
||||||
static TIMESTAMP start_timestamp = 0;
|
static TIMESTAMP start_timestamp = 0; /* time since epoch at start of run */
|
||||||
|
|
||||||
TIMESTAMP Time_since_epoch(void)
|
TIMESTAMP Time_since_epoch(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user