//==========================================================================
|
//==========================================================================
|
//
|
//
|
// lcd_support.c
|
// lcd_support.c
|
//
|
//
|
// SA1110/iPAQ - LCD support routines
|
// SA1110/iPAQ - LCD support routines
|
//
|
//
|
//==========================================================================
|
//==========================================================================
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
// -------------------------------------------
|
// -------------------------------------------
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
// Copyright (C) 2002 Gary Thomas
|
// Copyright (C) 2002 Gary Thomas
|
//
|
//
|
// eCos is free software; you can redistribute it and/or modify it under
|
// eCos 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
|
// the terms of the GNU General Public License as published by the Free
|
// Software Foundation; either version 2 or (at your option) any later version.
|
// Software Foundation; either version 2 or (at your option) any later version.
|
//
|
//
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for more details.
|
// for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License along
|
// You should have received a copy of the GNU General Public License along
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
//
|
//
|
// As a special exception, if other files instantiate templates or use macros
|
// 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
|
// 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
|
// 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
|
// 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
|
// License. However the source code for this file must still be made available
|
// in accordance with section (3) of the GNU General Public License.
|
// in accordance with section (3) of the GNU General Public License.
|
//
|
//
|
// This exception does not invalidate any other reasons why a work based on
|
// This exception does not invalidate any other reasons why a work based on
|
// this file might be covered by the GNU General Public License.
|
// this file might be covered by the GNU General Public License.
|
//
|
//
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
// at http://sources.redhat.com/ecos/ecos-license/
|
// at http://sources.redhat.com/ecos/ecos-license/
|
// -------------------------------------------
|
// -------------------------------------------
|
//####ECOSGPLCOPYRIGHTEND####
|
//####ECOSGPLCOPYRIGHTEND####
|
//==========================================================================
|
//==========================================================================
|
//#####DESCRIPTIONBEGIN####
|
//#####DESCRIPTIONBEGIN####
|
//
|
//
|
// Author(s): gthomas
|
// Author(s): gthomas
|
// Contributors: gthomas
|
// Contributors: gthomas
|
// Richard Panton <richard.panton@3glab.com>
|
// Richard Panton <richard.panton@3glab.com>
|
// Date: 2001-02-24
|
// Date: 2001-02-24
|
// Description: Simple LCD support
|
// Description: Simple LCD support
|
//####DESCRIPTIONEND####
|
//####DESCRIPTIONEND####
|
|
|
#include <pkgconf/hal.h>
|
#include <pkgconf/hal.h>
|
|
|
#include <cyg/infra/diag.h>
|
#include <cyg/infra/diag.h>
|
#include <cyg/hal/hal_io.h> // IO macros
|
#include <cyg/hal/hal_io.h> // IO macros
|
#include <cyg/hal/hal_if.h> // Virtual vector support
|
#include <cyg/hal/hal_if.h> // Virtual vector support
|
#include <cyg/hal/hal_arch.h> // Register state info
|
#include <cyg/hal/hal_arch.h> // Register state info
|
#include <cyg/hal/hal_intr.h> // HAL interrupt macros
|
#include <cyg/hal/hal_intr.h> // HAL interrupt macros
|
|
|
#include <cyg/hal/hal_sa11x0.h> // Board definitions
|
#include <cyg/hal/hal_sa11x0.h> // Board definitions
|
#include <cyg/hal/ipaq.h>
|
#include <cyg/hal/ipaq.h>
|
#include <cyg/hal/lcd_support.h>
|
#include <cyg/hal/lcd_support.h>
|
#include <cyg/hal/atmel_support.h>
|
#include <cyg/hal/atmel_support.h>
|
#include <cyg/hal/hal_cache.h>
|
#include <cyg/hal/hal_cache.h>
|
|
|
#ifdef CYGPKG_ISOINFRA
|
#ifdef CYGPKG_ISOINFRA
|
# include <pkgconf/isoinfra.h>
|
# include <pkgconf/isoinfra.h>
|
# ifdef CYGINT_ISO_STDIO_FORMATTED_IO
|
# ifdef CYGINT_ISO_STDIO_FORMATTED_IO
|
# include <stdio.h> // sscanf
|
# include <stdio.h> // sscanf
|
# endif
|
# endif
|
#endif
|
#endif
|
|
|
// Gross hack to force use of simple internal functions.
|
// Gross hack to force use of simple internal functions.
|
// Using libc sscanf fails (as far as I could tell from a quick look)
|
// Using libc sscanf fails (as far as I could tell from a quick look)
|
// when assertions are enabled because some of the C++ contructors have
|
// when assertions are enabled because some of the C++ contructors have
|
// not been run yet. jskov
|
// not been run yet. jskov
|
#undef CYGINT_ISO_STDIO_FORMATTED_IO
|
#undef CYGINT_ISO_STDIO_FORMATTED_IO
|
|
|
#ifndef FALSE
|
#ifndef FALSE
|
#define FALSE 0
|
#define FALSE 0
|
#define TRUE 1
|
#define TRUE 1
|
#endif
|
#endif
|
|
|
#define PORTRAIT_MODE
|
#define PORTRAIT_MODE
|
//#define LOGO_AT_TOP
|
//#define LOGO_AT_TOP
|
#include "banner.xpm"
|
#include "banner.xpm"
|
#include "font.h"
|
#include "font.h"
|
|
|
// Physical dimensions of LCD display
|
// Physical dimensions of LCD display
|
#define DISPLAY_WIDTH 320
|
#define DISPLAY_WIDTH 320
|
#define DISPLAY_HEIGHT 240
|
#define DISPLAY_HEIGHT 240
|
|
|
// Logical layout
|
// Logical layout
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
#define LCD_WIDTH 240
|
#define LCD_WIDTH 240
|
#define LCD_HEIGHT 320
|
#define LCD_HEIGHT 320
|
#else
|
#else
|
#define LCD_WIDTH 320
|
#define LCD_WIDTH 320
|
#define LCD_HEIGHT 240
|
#define LCD_HEIGHT 240
|
#endif
|
#endif
|
#define LCD_DEPTH 16
|
#define LCD_DEPTH 16
|
|
|
static struct lcd_frame {
|
static struct lcd_frame {
|
unsigned short palette[16];
|
unsigned short palette[16];
|
unsigned short pixels[DISPLAY_HEIGHT][DISPLAY_WIDTH];
|
unsigned short pixels[DISPLAY_HEIGHT][DISPLAY_WIDTH];
|
unsigned char pad[256];
|
unsigned char pad[256];
|
} *lcd_frame_buffer = (struct lcd_frame *)0x01FC0000; // Actually just 0x26000 bytes, but...
|
} *lcd_frame_buffer = (struct lcd_frame *)0x01FC0000; // Actually just 0x26000 bytes, but...
|
|
|
#define USE_RGB565
|
#define USE_RGB565
|
#ifdef USE_RGB565
|
#ifdef USE_RGB565
|
#define RGB_RED(x) (((x)&0x1F)<<11)
|
#define RGB_RED(x) (((x)&0x1F)<<11)
|
#define RGB_GREEN(x) (((x)&0x3F)<<5)
|
#define RGB_GREEN(x) (((x)&0x3F)<<5)
|
#define RGB_BLUE(x) ((x)&0x1F)
|
#define RGB_BLUE(x) ((x)&0x1F)
|
#else
|
#else
|
#define RGB_RED(x) (((x)&0x0F)<<12)
|
#define RGB_RED(x) (((x)&0x0F)<<12)
|
#define RGB_GREEN(x) (((x)&0x0F)<<7)
|
#define RGB_GREEN(x) (((x)&0x0F)<<7)
|
#define RGB_BLUE(x) (((x)&0x0F)<<1)
|
#define RGB_BLUE(x) (((x)&0x0F)<<1)
|
#endif
|
#endif
|
|
|
static volatile struct lcd_frame *fp;
|
static volatile struct lcd_frame *fp;
|
|
|
// Physical screen info
|
// Physical screen info
|
//static int lcd_depth = LCD_DEPTH; // Should be 1, 2, or 4
|
//static int lcd_depth = LCD_DEPTH; // Should be 1, 2, or 4
|
static int lcd_bpp;
|
static int lcd_bpp;
|
static int lcd_width = LCD_WIDTH;
|
static int lcd_width = LCD_WIDTH;
|
static int lcd_height = LCD_HEIGHT;
|
static int lcd_height = LCD_HEIGHT;
|
|
|
// Virtual screen info
|
// Virtual screen info
|
static int curX = 0; // Last used position
|
static int curX = 0; // Last used position
|
static int curY = 0;
|
static int curY = 0;
|
//static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
|
//static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
|
//static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
|
//static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
|
|
|
static int fg = RGB_RED(15) | RGB_GREEN(63) | RGB_BLUE(8);
|
static int fg = RGB_RED(15) | RGB_GREEN(63) | RGB_BLUE(8);
|
static int bg = RGB_RED(0) | RGB_GREEN(0) | RGB_BLUE(15/*31*/);
|
static int bg = RGB_RED(0) | RGB_GREEN(0) | RGB_BLUE(15/*31*/);
|
|
|
#define SCREEN_PAN 20
|
#define SCREEN_PAN 20
|
#define SCREEN_WIDTH 80
|
#define SCREEN_WIDTH 80
|
#define SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
|
#define SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
|
#define VISIBLE_SCREEN_WIDTH (LCD_WIDTH/FONT_WIDTH)
|
#define VISIBLE_SCREEN_WIDTH (LCD_WIDTH/FONT_WIDTH)
|
#define VISIBLE_SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
|
#define VISIBLE_SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
|
static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
|
static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
|
static int screen_start = 0;
|
static int screen_start = 0;
|
static int screen_height = SCREEN_HEIGHT;
|
static int screen_height = SCREEN_HEIGHT;
|
static int screen_width = SCREEN_WIDTH;
|
static int screen_width = SCREEN_WIDTH;
|
static int screen_pan = 0;
|
static int screen_pan = 0;
|
|
|
static bool cursor_enable = true;
|
static bool cursor_enable = true;
|
|
|
static int kbd_pos;
|
static int kbd_pos;
|
|
|
// Functions
|
// Functions
|
static void lcd_drawc(cyg_int8 c, int x, int y);
|
static void lcd_drawc(cyg_int8 c, int x, int y);
|
|
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
// Translate coordinates, rotating clockwise 90 degrees
|
// Translate coordinates, rotating clockwise 90 degrees
|
static void
|
static void
|
set_pixel(int row, int col, unsigned short val)
|
set_pixel(int row, int col, unsigned short val)
|
{
|
{
|
fp->pixels[col][(DISPLAY_WIDTH-1)-row] = val;
|
fp->pixels[col][(DISPLAY_WIDTH-1)-row] = val;
|
}
|
}
|
#else
|
#else
|
static void
|
static void
|
set_pixel(int row, int col, unsigned short val)
|
set_pixel(int row, int col, unsigned short val)
|
{
|
{
|
fp->pixels[row][col] = val;
|
fp->pixels[row][col] = val;
|
}
|
}
|
#endif
|
#endif
|
|
|
static int
|
static int
|
_hexdigit(char c)
|
_hexdigit(char c)
|
{
|
{
|
if ((c >= '0') && (c <= '9')) {
|
if ((c >= '0') && (c <= '9')) {
|
return c - '0';
|
return c - '0';
|
} else
|
} else
|
if ((c >= 'A') && (c <= 'F')) {
|
if ((c >= 'A') && (c <= 'F')) {
|
return (c - 'A') + 0x0A;
|
return (c - 'A') + 0x0A;
|
} else
|
} else
|
if ((c >= 'a') && (c <= 'f')) {
|
if ((c >= 'a') && (c <= 'f')) {
|
return (c - 'a') + 0x0a;
|
return (c - 'a') + 0x0a;
|
}
|
}
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static int
|
static int
|
_hex(char *cp)
|
_hex(char *cp)
|
{
|
{
|
return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));
|
return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));
|
}
|
}
|
|
|
static unsigned short
|
static unsigned short
|
parse_color(char *cp)
|
parse_color(char *cp)
|
{
|
{
|
int red, green, blue;
|
int red, green, blue;
|
|
|
while (*cp && (*cp != 'c')) cp++;
|
while (*cp && (*cp != 'c')) cp++;
|
if (cp) {
|
if (cp) {
|
cp += 2;
|
cp += 2;
|
if (*cp == '#') {
|
if (*cp == '#') {
|
red = _hex(cp+1);
|
red = _hex(cp+1);
|
green = _hex(cp+3);
|
green = _hex(cp+3);
|
blue = _hex(cp+5);
|
blue = _hex(cp+5);
|
#ifdef USE_RGB565
|
#ifdef USE_RGB565
|
return RGB_RED(red>>3) | RGB_GREEN(green>>2) | RGB_BLUE(blue>>3);
|
return RGB_RED(red>>3) | RGB_GREEN(green>>2) | RGB_BLUE(blue>>3);
|
#else
|
#else
|
return RGB_RED(red>>3) | RGB_GREEN(green>>3) | RGB_BLUE(blue>>3);
|
return RGB_RED(red>>3) | RGB_GREEN(green>>3) | RGB_BLUE(blue>>3);
|
#endif
|
#endif
|
} else {
|
} else {
|
// Should be "None"
|
// Should be "None"
|
return 0xFFFF;
|
return 0xFFFF;
|
}
|
}
|
} else {
|
} else {
|
return 0xFFFF;
|
return 0xFFFF;
|
}
|
}
|
}
|
}
|
|
|
#ifndef CYGINT_ISO_STDIO_FORMATTED_IO
|
#ifndef CYGINT_ISO_STDIO_FORMATTED_IO
|
static int
|
static int
|
get_int(char **_cp)
|
get_int(char **_cp)
|
{
|
{
|
char *cp = *_cp;
|
char *cp = *_cp;
|
char c;
|
char c;
|
int val = 0;
|
int val = 0;
|
|
|
while ((c = *cp++) && (c != ' ')) {
|
while ((c = *cp++) && (c != ' ')) {
|
if ((c >= '0') && (c <= '9')) {
|
if ((c >= '0') && (c <= '9')) {
|
val = val * 10 + (c - '0');
|
val = val * 10 + (c - '0');
|
} else {
|
} else {
|
return -1;
|
return -1;
|
}
|
}
|
}
|
}
|
*_cp = cp;
|
*_cp = cp;
|
return val;
|
return val;
|
}
|
}
|
#endif
|
#endif
|
|
|
int
|
int
|
show_xpm(char *xpm[], int screen_pos)
|
show_xpm(char *xpm[], int screen_pos)
|
{
|
{
|
int i, row, col, offset;
|
int i, row, col, offset;
|
char *cp;
|
char *cp;
|
int nrows, ncols, nclrs;
|
int nrows, ncols, nclrs;
|
unsigned short colors[256]; // Mapped by character index
|
unsigned short colors[256]; // Mapped by character index
|
|
|
cp = xpm[0];
|
cp = xpm[0];
|
#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
|
#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
|
if (sscanf(cp, "%d %d %d", &ncols, &nrows, &nclrs) != 3) {
|
if (sscanf(cp, "%d %d %d", &ncols, &nrows, &nclrs) != 3) {
|
#else
|
#else
|
if (((ncols = get_int(&cp)) < 0) ||
|
if (((ncols = get_int(&cp)) < 0) ||
|
((nrows = get_int(&cp)) < 0) ||
|
((nrows = get_int(&cp)) < 0) ||
|
((nclrs = get_int(&cp)) < 0)) {
|
((nclrs = get_int(&cp)) < 0)) {
|
|
|
#endif
|
#endif
|
diag_printf("Can't parse XPM data, sorry\n");
|
diag_printf("Can't parse XPM data, sorry\n");
|
return 0;
|
return 0;
|
}
|
}
|
// printf("%d rows, %d cols, %d colors\n", nrows, ncols, nclrs);
|
// printf("%d rows, %d cols, %d colors\n", nrows, ncols, nclrs);
|
|
|
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
colors[i] = 0x0000;
|
colors[i] = 0x0000;
|
}
|
}
|
for (i = 0; i < nclrs; i++) {
|
for (i = 0; i < nclrs; i++) {
|
cp = xpm[i+1];
|
cp = xpm[i+1];
|
colors[(unsigned int)*cp] = parse_color(&cp[1]);
|
colors[(unsigned int)*cp] = parse_color(&cp[1]);
|
// printf("Color[%c] = %x\n", *cp, colors[(unsigned int)*cp]);
|
// printf("Color[%c] = %x\n", *cp, colors[(unsigned int)*cp]);
|
}
|
}
|
|
|
#ifdef LOGO_AT_TOP
|
#ifdef LOGO_AT_TOP
|
offset = screen_pos;
|
offset = screen_pos;
|
#else
|
#else
|
offset = screen_pos-nrows;
|
offset = screen_pos-nrows;
|
#endif
|
#endif
|
for (row = 0; row < nrows; row++) {
|
for (row = 0; row < nrows; row++) {
|
cp = xpm[nclrs+1+row];
|
cp = xpm[nclrs+1+row];
|
for (col = 0; col < ncols; col++) {
|
for (col = 0; col < ncols; col++) {
|
set_pixel(row+offset, col, colors[(unsigned int)*cp++]);
|
set_pixel(row+offset, col, colors[(unsigned int)*cp++]);
|
}
|
}
|
}
|
}
|
#ifdef LOGO_AT_TOP
|
#ifdef LOGO_AT_TOP
|
screen_start = (nrows + (FONT_HEIGHT-1))/FONT_HEIGHT;
|
screen_start = (nrows + (FONT_HEIGHT-1))/FONT_HEIGHT;
|
return offset+nrows;
|
return offset+nrows;
|
#else
|
#else
|
screen_height = offset / FONT_HEIGHT;
|
screen_height = offset / FONT_HEIGHT;
|
return offset;
|
return offset;
|
#endif
|
#endif
|
}
|
}
|
|
|
void
|
void
|
lcd_init(int depth)
|
lcd_init(int depth)
|
{
|
{
|
// Currently only color/16bpp supported
|
// Currently only color/16bpp supported
|
|
|
if (depth != 16) {
|
if (depth != 16) {
|
return;
|
return;
|
}
|
}
|
lcd_bpp = depth;
|
lcd_bpp = depth;
|
fp = (struct lcd_frame *)hal_virt_to_phys_address((cyg_uint32)lcd_frame_buffer);
|
fp = (struct lcd_frame *)hal_virt_to_phys_address((cyg_uint32)lcd_frame_buffer);
|
// Enable LCD in 320x240 16bpp
|
// Enable LCD in 320x240 16bpp
|
*SA1110_DBAR1 = (unsigned long)&(fp->palette);
|
*SA1110_DBAR1 = (unsigned long)&(fp->palette);
|
*SA1110_LCCR1 = 0x0b100800 + DISPLAY_WIDTH - 16;
|
*SA1110_LCCR1 = 0x0b100800 + DISPLAY_WIDTH - 16;
|
*SA1110_LCCR2 = 0x0a010400 + DISPLAY_HEIGHT - 1;
|
*SA1110_LCCR2 = 0x0a010400 + DISPLAY_HEIGHT - 1;
|
*SA1110_LCCR3 = 0x00300010;
|
*SA1110_LCCR3 = 0x00300010;
|
fp->palette[0] = 0x2000; // Tell controller true color / 16 bits
|
fp->palette[0] = 0x2000; // Tell controller true color / 16 bits
|
*SA1110_LCCR0 = 0xB9; // Color
|
*SA1110_LCCR0 = 0xB9; // Color
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
SA1110_EIO_LCD_3V3_ON|SA1110_EIO_LCD_CTRL_ON|SA1110_EIO_LCD_5V_ON|SA1110_EIO_LCD_VDD_ON);
|
SA1110_EIO_LCD_3V3_ON|SA1110_EIO_LCD_CTRL_ON|SA1110_EIO_LCD_5V_ON|SA1110_EIO_LCD_VDD_ON);
|
lcd_clear();
|
lcd_clear();
|
lcd_brightness(31);
|
lcd_brightness(31);
|
}
|
}
|
|
|
// Get information about the frame buffer
|
// Get information about the frame buffer
|
int
|
int
|
lcd_getinfo(struct lcd_info *info)
|
lcd_getinfo(struct lcd_info *info)
|
{
|
{
|
if (lcd_bpp == 0) {
|
if (lcd_bpp == 0) {
|
return 0; // LCD not initialized
|
return 0; // LCD not initialized
|
}
|
}
|
info->width = DISPLAY_WIDTH;
|
info->width = DISPLAY_WIDTH;
|
info->height = DISPLAY_HEIGHT;
|
info->height = DISPLAY_HEIGHT;
|
info->bpp = lcd_bpp;
|
info->bpp = lcd_bpp;
|
info->fb = (void *)lcd_frame_buffer->pixels; // Note: this is cached
|
info->fb = (void *)lcd_frame_buffer->pixels; // Note: this is cached
|
info->rlen = DISPLAY_WIDTH * 2;
|
info->rlen = DISPLAY_WIDTH * 2;
|
info->type = FB_TRUE_RGB565;
|
info->type = FB_TRUE_RGB565;
|
return 1; // Information valid
|
return 1; // Information valid
|
}
|
}
|
|
|
// Control screen light [brightness]
|
// Control screen light [brightness]
|
|
|
static void
|
static void
|
lcd_brightness_ack(atmel_pkt *pkt)
|
lcd_brightness_ack(atmel_pkt *pkt)
|
{
|
{
|
}
|
}
|
|
|
static int _lcd_brightness;
|
static int _lcd_brightness;
|
|
|
void
|
void
|
lcd_brightness(int level)
|
lcd_brightness(int level)
|
{
|
{
|
unsigned char cmd[3];
|
unsigned char cmd[3];
|
|
|
atmel_register(ATMEL_CMD_LIGHT, lcd_brightness_ack);
|
atmel_register(ATMEL_CMD_LIGHT, lcd_brightness_ack);
|
cmd[0] = 1; // LCD magic
|
cmd[0] = 1; // LCD magic
|
cmd[1] = (level > 0) ? 1 : 0; // Turn light on
|
cmd[1] = (level > 0) ? 1 : 0; // Turn light on
|
cmd[2] = level;
|
cmd[2] = level;
|
if (level) _lcd_brightness = level;
|
if (level) _lcd_brightness = level;
|
atmel_send(ATMEL_CMD_LIGHT, cmd, 3);
|
atmel_send(ATMEL_CMD_LIGHT, cmd, 3);
|
}
|
}
|
|
|
// Clear screen
|
// Clear screen
|
void
|
void
|
lcd_clear(void)
|
lcd_clear(void)
|
{
|
{
|
int row, col;
|
int row, col;
|
int pos;
|
int pos;
|
|
|
#ifndef USE_RGB565
|
#ifndef USE_RGB565
|
int val;
|
int val;
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, RGB_RED(31));
|
set_pixel(row, col, RGB_RED(31));
|
}
|
}
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(100000);
|
CYGACC_CALL_IF_DELAY_US(100000);
|
|
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, RGB_GREEN(31));
|
set_pixel(row, col, RGB_GREEN(31));
|
}
|
}
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(100000);
|
CYGACC_CALL_IF_DELAY_US(100000);
|
val = 0;
|
val = 0;
|
for (pos = 0; pos < 16; pos++) {
|
for (pos = 0; pos < 16; pos++) {
|
val = (1<<pos);
|
val = (1<<pos);
|
diag_printf("Set pixel to 0x%04x\n", val);
|
diag_printf("Set pixel to 0x%04x\n", val);
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, val);
|
set_pixel(row, col, val);
|
}
|
}
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(100000);
|
CYGACC_CALL_IF_DELAY_US(100000);
|
}
|
}
|
val = 0;
|
val = 0;
|
for (pos = 8; pos < 16; pos++) {
|
for (pos = 8; pos < 16; pos++) {
|
val |= (1<<pos);
|
val |= (1<<pos);
|
diag_printf("Set pixel to 0x%04x\n", val);
|
diag_printf("Set pixel to 0x%04x\n", val);
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, val);
|
set_pixel(row, col, val);
|
}
|
}
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(100000);
|
CYGACC_CALL_IF_DELAY_US(100000);
|
}
|
}
|
|
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, RGB_BLUE(31));
|
set_pixel(row, col, RGB_BLUE(31));
|
}
|
}
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(100000);
|
CYGACC_CALL_IF_DELAY_US(100000);
|
#endif // RGB565
|
#endif // RGB565
|
|
|
for (row = 0; row < lcd_height; row++) {
|
for (row = 0; row < lcd_height; row++) {
|
for (col = 0; col < lcd_width; col++) {
|
for (col = 0; col < lcd_width; col++) {
|
set_pixel(row, col, bg);
|
set_pixel(row, col, bg);
|
}
|
}
|
}
|
}
|
for (row = 0; row < screen_height; row++) {
|
for (row = 0; row < screen_height; row++) {
|
for (col = 0; col < screen_width; col++) {
|
for (col = 0; col < screen_width; col++) {
|
screen[row][col] = ' ';
|
screen[row][col] = ' ';
|
}
|
}
|
}
|
}
|
// Note: Row 0 seems to wrap incorrectly
|
// Note: Row 0 seems to wrap incorrectly
|
#ifdef LOGO_AT_TOP
|
#ifdef LOGO_AT_TOP
|
pos = 0;
|
pos = 0;
|
#else
|
#else
|
pos = (LCD_HEIGHT-1);
|
pos = (LCD_HEIGHT-1);
|
#endif
|
#endif
|
kbd_pos = show_xpm(banner_xpm, pos);
|
kbd_pos = show_xpm(banner_xpm, pos);
|
curX = 0; curY = screen_start;
|
curX = 0; curY = screen_start;
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
}
|
}
|
}
|
}
|
|
|
// Position cursor
|
// Position cursor
|
void
|
void
|
lcd_moveto(int X, int Y)
|
lcd_moveto(int X, int Y)
|
{
|
{
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
|
lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
|
}
|
}
|
if (X < 0) X = 0;
|
if (X < 0) X = 0;
|
if (X >= screen_width) X = screen_width-1;
|
if (X >= screen_width) X = screen_width-1;
|
curX = X;
|
curX = X;
|
if (Y < screen_start) Y = screen_start;
|
if (Y < screen_start) Y = screen_start;
|
if (Y >= screen_height) Y = screen_height-1;
|
if (Y >= screen_height) Y = screen_height-1;
|
curY = Y;
|
curY = Y;
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
}
|
}
|
}
|
}
|
|
|
// Render a character at position (X,Y) with current background/foreground
|
// Render a character at position (X,Y) with current background/foreground
|
static void
|
static void
|
lcd_drawc(cyg_int8 c, int x, int y)
|
lcd_drawc(cyg_int8 c, int x, int y)
|
{
|
{
|
cyg_uint8 bits;
|
cyg_uint8 bits;
|
int l, p;
|
int l, p;
|
|
|
if ((x < 0) || (x >= VISIBLE_SCREEN_WIDTH) ||
|
if ((x < 0) || (x >= VISIBLE_SCREEN_WIDTH) ||
|
(y < 0) || (y >= screen_height)) return;
|
(y < 0) || (y >= screen_height)) return;
|
for (l = 0; l < FONT_HEIGHT; l++) {
|
for (l = 0; l < FONT_HEIGHT; l++) {
|
bits = font_table[c-FIRST_CHAR][l];
|
bits = font_table[c-FIRST_CHAR][l];
|
for (p = 0; p < FONT_WIDTH; p++) {
|
for (p = 0; p < FONT_WIDTH; p++) {
|
if (bits & 0x01) {
|
if (bits & 0x01) {
|
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, fg);
|
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, fg);
|
} else {
|
} else {
|
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, bg);
|
set_pixel(y*FONT_HEIGHT+l, x*FONT_WIDTH + p, bg);
|
}
|
}
|
bits >>= 1;
|
bits >>= 1;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void
|
lcd_refresh(void)
|
lcd_refresh(void)
|
{
|
{
|
int row, col;
|
int row, col;
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
for (row = screen_start; row < screen_height; row++) {
|
for (row = screen_start; row < screen_height; row++) {
|
for (col = 0; col < VISIBLE_SCREEN_WIDTH; col++) {
|
for (col = 0; col < VISIBLE_SCREEN_WIDTH; col++) {
|
if ((col+screen_pan) < screen_width) {
|
if ((col+screen_pan) < screen_width) {
|
lcd_drawc(screen[row][col+screen_pan], col, row);
|
lcd_drawc(screen[row][col+screen_pan], col, row);
|
} else {
|
} else {
|
lcd_drawc(' ', col, row);
|
lcd_drawc(' ', col, row);
|
}
|
}
|
}
|
}
|
}
|
}
|
#else
|
#else
|
cyg_uint16 *p1, *p2;
|
cyg_uint16 *p1, *p2;
|
// Now the physical screen
|
// Now the physical screen
|
for (row = FONT_HEIGHT*(screen_start+1); row < LCD_HEIGHT; row++) {
|
for (row = FONT_HEIGHT*(screen_start+1); row < LCD_HEIGHT; row++) {
|
p1 = &fp->pixels[row-FONT_HEIGHT][0];
|
p1 = &fp->pixels[row-FONT_HEIGHT][0];
|
p2 = &fp->pixels[row][0];
|
p2 = &fp->pixels[row][0];
|
for (col = 0; col < LCD_WIDTH; col++) {
|
for (col = 0; col < LCD_WIDTH; col++) {
|
*p1++ = *p2++;
|
*p1++ = *p2++;
|
}
|
}
|
}
|
}
|
for (row = LCD_HEIGHT-FONT_HEIGHT; row < LCD_HEIGHT; row++) {
|
for (row = LCD_HEIGHT-FONT_HEIGHT; row < LCD_HEIGHT; row++) {
|
p1 = &fp->pixels[row][0];
|
p1 = &fp->pixels[row][0];
|
for (col = 0; col < LCD_WIDTH; col++) {
|
for (col = 0; col < LCD_WIDTH; col++) {
|
*p1++ = bg;
|
*p1++ = bg;
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
}
|
}
|
}
|
}
|
|
|
static void
|
static void
|
lcd_scroll(void)
|
lcd_scroll(void)
|
{
|
{
|
int row, col;
|
int row, col;
|
cyg_uint8 *c1, *c2;
|
cyg_uint8 *c1, *c2;
|
|
|
// First scroll up the virtual screen
|
// First scroll up the virtual screen
|
for (row = (screen_start+1); row < screen_height; row++) {
|
for (row = (screen_start+1); row < screen_height; row++) {
|
c1 = &screen[row-1][0];
|
c1 = &screen[row-1][0];
|
c2 = &screen[row][0];
|
c2 = &screen[row][0];
|
for (col = 0; col < screen_width; col++) {
|
for (col = 0; col < screen_width; col++) {
|
*c1++ = *c2++;
|
*c1++ = *c2++;
|
}
|
}
|
}
|
}
|
c1 = &screen[screen_height-1][0];
|
c1 = &screen[screen_height-1][0];
|
for (col = 0; col < screen_width; col++) {
|
for (col = 0; col < screen_width; col++) {
|
*c1++ = 0x20;
|
*c1++ = 0x20;
|
}
|
}
|
lcd_refresh();
|
lcd_refresh();
|
}
|
}
|
|
|
// Draw one character at the current position
|
// Draw one character at the current position
|
void
|
void
|
lcd_putc(cyg_int8 c)
|
lcd_putc(cyg_int8 c)
|
{
|
{
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
|
lcd_drawc(screen[curY][curX], curX-screen_pan, curY);
|
}
|
}
|
switch (c) {
|
switch (c) {
|
case '\r':
|
case '\r':
|
curX = 0;
|
curX = 0;
|
break;
|
break;
|
case '\n':
|
case '\n':
|
curY++;
|
curY++;
|
break;
|
break;
|
case '\b':
|
case '\b':
|
curX--;
|
curX--;
|
if (curX < 0) {
|
if (curX < 0) {
|
curY--;
|
curY--;
|
if (curY < 0) curY = 0;
|
if (curY < 0) curY = 0;
|
curX = screen_width-1;
|
curX = screen_width-1;
|
}
|
}
|
break;
|
break;
|
default:
|
default:
|
if (((cyg_uint8)c < FIRST_CHAR) || ((cyg_uint8)c > LAST_CHAR)) c = '.';
|
if (((cyg_uint8)c < FIRST_CHAR) || ((cyg_uint8)c > LAST_CHAR)) c = '.';
|
screen[curY][curX] = c;
|
screen[curY][curX] = c;
|
lcd_drawc(c, curX-screen_pan, curY);
|
lcd_drawc(c, curX-screen_pan, curY);
|
curX++;
|
curX++;
|
if (curX == screen_width) {
|
if (curX == screen_width) {
|
curY++;
|
curY++;
|
curX = 0;
|
curX = 0;
|
}
|
}
|
}
|
}
|
if (curY >= screen_height) {
|
if (curY >= screen_height) {
|
lcd_scroll();
|
lcd_scroll();
|
curY = (screen_height-1);
|
curY = (screen_height-1);
|
}
|
}
|
if (cursor_enable) {
|
if (cursor_enable) {
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
lcd_drawc(CURSOR_ON, curX-screen_pan, curY);
|
}
|
}
|
}
|
}
|
|
|
// Basic LCD 'printf()' support
|
// Basic LCD 'printf()' support
|
|
|
#include <stdarg.h>
|
#include <stdarg.h>
|
#include <string.h>
|
#include <string.h>
|
|
|
#define is_digit(c) ((c >= '0') && (c <= '9'))
|
#define is_digit(c) ((c >= '0') && (c <= '9'))
|
|
|
static int
|
static int
|
_cvt(unsigned long val, char *buf, long radix, char *digits)
|
_cvt(unsigned long val, char *buf, long radix, char *digits)
|
{
|
{
|
char temp[80];
|
char temp[80];
|
char *cp = temp;
|
char *cp = temp;
|
int length = 0;
|
int length = 0;
|
if (val == 0) {
|
if (val == 0) {
|
/* Special case */
|
/* Special case */
|
*cp++ = '0';
|
*cp++ = '0';
|
} else {
|
} else {
|
while (val) {
|
while (val) {
|
*cp++ = digits[val % radix];
|
*cp++ = digits[val % radix];
|
val /= radix;
|
val /= radix;
|
}
|
}
|
}
|
}
|
while (cp != temp) {
|
while (cp != temp) {
|
*buf++ = *--cp;
|
*buf++ = *--cp;
|
length++;
|
length++;
|
}
|
}
|
*buf = '\0';
|
*buf = '\0';
|
return (length);
|
return (length);
|
}
|
}
|
|
|
static int
|
static int
|
lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap)
|
lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap)
|
{
|
{
|
char c, sign, *cp;
|
char c, sign, *cp;
|
int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
|
int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
|
char buf[32];
|
char buf[32];
|
long val;
|
long val;
|
|
|
while ((c = *fmt0++)) {
|
while ((c = *fmt0++)) {
|
cp = buf;
|
cp = buf;
|
length = 0;
|
length = 0;
|
if (c == '%') {
|
if (c == '%') {
|
c = *fmt0++;
|
c = *fmt0++;
|
left_prec = right_prec = pad_on_right = 0;
|
left_prec = right_prec = pad_on_right = 0;
|
if (c == '-') {
|
if (c == '-') {
|
c = *fmt0++;
|
c = *fmt0++;
|
pad_on_right++;
|
pad_on_right++;
|
}
|
}
|
if (c == '0') {
|
if (c == '0') {
|
zero_fill = TRUE;
|
zero_fill = TRUE;
|
c = *fmt0++;
|
c = *fmt0++;
|
} else {
|
} else {
|
zero_fill = FALSE;
|
zero_fill = FALSE;
|
}
|
}
|
while (is_digit(c)) {
|
while (is_digit(c)) {
|
left_prec = (left_prec * 10) + (c - '0');
|
left_prec = (left_prec * 10) + (c - '0');
|
c = *fmt0++;
|
c = *fmt0++;
|
}
|
}
|
if (c == '.') {
|
if (c == '.') {
|
c = *fmt0++;
|
c = *fmt0++;
|
zero_fill++;
|
zero_fill++;
|
while (is_digit(c)) {
|
while (is_digit(c)) {
|
right_prec = (right_prec * 10) + (c - '0');
|
right_prec = (right_prec * 10) + (c - '0');
|
c = *fmt0++;
|
c = *fmt0++;
|
}
|
}
|
} else {
|
} else {
|
right_prec = left_prec;
|
right_prec = left_prec;
|
}
|
}
|
sign = '\0';
|
sign = '\0';
|
switch (c) {
|
switch (c) {
|
case 'd':
|
case 'd':
|
case 'x':
|
case 'x':
|
case 'X':
|
case 'X':
|
val = va_arg(ap, long);
|
val = va_arg(ap, long);
|
switch (c) {
|
switch (c) {
|
case 'd':
|
case 'd':
|
if (val < 0) {
|
if (val < 0) {
|
sign = '-';
|
sign = '-';
|
val = -val;
|
val = -val;
|
}
|
}
|
length = _cvt(val, buf, 10, "0123456789");
|
length = _cvt(val, buf, 10, "0123456789");
|
break;
|
break;
|
case 'x':
|
case 'x':
|
length = _cvt(val, buf, 16, "0123456789abcdef");
|
length = _cvt(val, buf, 16, "0123456789abcdef");
|
break;
|
break;
|
case 'X':
|
case 'X':
|
length = _cvt(val, buf, 16, "0123456789ABCDEF");
|
length = _cvt(val, buf, 16, "0123456789ABCDEF");
|
break;
|
break;
|
}
|
}
|
break;
|
break;
|
case 's':
|
case 's':
|
cp = va_arg(ap, char *);
|
cp = va_arg(ap, char *);
|
length = strlen(cp);
|
length = strlen(cp);
|
break;
|
break;
|
case 'c':
|
case 'c':
|
c = va_arg(ap, long /*char*/);
|
c = va_arg(ap, long /*char*/);
|
(*putc)(c);
|
(*putc)(c);
|
continue;
|
continue;
|
default:
|
default:
|
(*putc)('?');
|
(*putc)('?');
|
}
|
}
|
pad = left_prec - length;
|
pad = left_prec - length;
|
if (sign != '\0') {
|
if (sign != '\0') {
|
pad--;
|
pad--;
|
}
|
}
|
if (zero_fill) {
|
if (zero_fill) {
|
c = '0';
|
c = '0';
|
if (sign != '\0') {
|
if (sign != '\0') {
|
(*putc)(sign);
|
(*putc)(sign);
|
sign = '\0';
|
sign = '\0';
|
}
|
}
|
} else {
|
} else {
|
c = ' ';
|
c = ' ';
|
}
|
}
|
if (!pad_on_right) {
|
if (!pad_on_right) {
|
while (pad-- > 0) {
|
while (pad-- > 0) {
|
(*putc)(c);
|
(*putc)(c);
|
}
|
}
|
}
|
}
|
if (sign != '\0') {
|
if (sign != '\0') {
|
(*putc)(sign);
|
(*putc)(sign);
|
}
|
}
|
while (length-- > 0) {
|
while (length-- > 0) {
|
(*putc)(c = *cp++);
|
(*putc)(c = *cp++);
|
if (c == '\n') {
|
if (c == '\n') {
|
(*putc)('\r');
|
(*putc)('\r');
|
}
|
}
|
}
|
}
|
if (pad_on_right) {
|
if (pad_on_right) {
|
while (pad-- > 0) {
|
while (pad-- > 0) {
|
(*putc)(' ');
|
(*putc)(' ');
|
}
|
}
|
}
|
}
|
} else {
|
} else {
|
(*putc)(c);
|
(*putc)(c);
|
if (c == '\n') {
|
if (c == '\n') {
|
(*putc)('\r');
|
(*putc)('\r');
|
}
|
}
|
}
|
}
|
}
|
}
|
return 0; // Should be length of string written
|
return 0; // Should be length of string written
|
}
|
}
|
|
|
int
|
int
|
lcd_printf(char const *fmt, ...)
|
lcd_printf(char const *fmt, ...)
|
{
|
{
|
int ret;
|
int ret;
|
va_list ap;
|
va_list ap;
|
|
|
va_start(ap, fmt);
|
va_start(ap, fmt);
|
ret = lcd_vprintf(lcd_putc, fmt, ap);
|
ret = lcd_vprintf(lcd_putc, fmt, ap);
|
va_end(ap);
|
va_end(ap);
|
return (ret);
|
return (ret);
|
}
|
}
|
|
|
void
|
void
|
lcd_setbg(int red, int green, int blue)
|
lcd_setbg(int red, int green, int blue)
|
{
|
{
|
bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
|
bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
|
}
|
}
|
|
|
void
|
void
|
lcd_setfg(int red, int green, int blue)
|
lcd_setfg(int red, int green, int blue)
|
{
|
{
|
fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
|
fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
|
}
|
}
|
|
|
#ifdef CYGSEM_IPAQ_LCD_COMM
|
#ifdef CYGSEM_IPAQ_LCD_COMM
|
|
|
//
|
//
|
// Support LCD/touchscreen as a virtual I/O channel
|
// Support LCD/touchscreen as a virtual I/O channel
|
//
|
//
|
|
|
#include "kbd.xpm" // Contains 4 keyboard images
|
#include "kbd.xpm" // Contains 4 keyboard images
|
|
|
static int _timeout = 500;
|
static int _timeout = 500;
|
|
|
struct coord {
|
struct coord {
|
short x,y;
|
short x,y;
|
};
|
};
|
|
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
#define CS_UL 1
|
#define CS_UL 1
|
#define CS_UR 0
|
#define CS_UR 0
|
#define CS_LL 3
|
#define CS_LL 3
|
#define CS_LR 2
|
#define CS_LR 2
|
#else
|
#else
|
#define CS_UL 0
|
#define CS_UL 0
|
#define CS_UR 1
|
#define CS_UR 1
|
#define CS_LL 2
|
#define CS_LL 2
|
#define CS_LR 3
|
#define CS_LR 3
|
#endif
|
#endif
|
#define KBD_FUZZ 50
|
#define KBD_FUZZ 50
|
static struct coord kbd_limits[4];
|
static struct coord kbd_limits[4];
|
static short minX, maxX, minY, maxY; // Coordinates for the keyboard matrix
|
static short minX, maxX, minY, maxY; // Coordinates for the keyboard matrix
|
|
|
#define CODE_NONE 0x00
|
#define CODE_NONE 0x00
|
#define CODE_CTRL 0x81
|
#define CODE_CTRL 0x81
|
#define CODE_SHIFT 0x82
|
#define CODE_SHIFT 0x82
|
#define CODE_NUM 0x83
|
#define CODE_NUM 0x83
|
#define CODE_BS 0x08
|
#define CODE_BS 0x08
|
#define CODE_CR 0x0D
|
#define CODE_CR 0x0D
|
#define CODE_ESC 0x1B
|
#define CODE_ESC 0x1B
|
#define CODE_DEL 0x7F
|
#define CODE_DEL 0x7F
|
#define CTRL(x) (x&0x1F)
|
#define CTRL(x) (x&0x1F)
|
|
|
typedef unsigned char kbd_map[4][11];
|
typedef unsigned char kbd_map[4][11];
|
static kbd_map kbd_norm_map = {
|
static kbd_map kbd_norm_map = {
|
{ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', CODE_BS },
|
{ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', CODE_BS },
|
{ 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '-', CODE_CR },
|
{ 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '-', CODE_CR },
|
{ CODE_CTRL, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', ';' },
|
{ CODE_CTRL, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', ';' },
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '\'', '=', '\\', '/'}
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '\'', '=', '\\', '/'}
|
};
|
};
|
|
|
static kbd_map kbd_num_map = {
|
static kbd_map kbd_num_map = {
|
{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', CODE_BS },
|
{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', CODE_BS },
|
{ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', CODE_CR },
|
{ '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', CODE_CR },
|
{ CODE_CTRL, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '`', '~' },
|
{ CODE_CTRL, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '`', '~' },
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '[', ']', '{', '}'}
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '[', ']', '{', '}'}
|
};
|
};
|
|
|
static kbd_map kbd_ctrl_map = {
|
static kbd_map kbd_ctrl_map = {
|
{ CTRL('q'), CTRL('w'), CTRL('e'), CTRL('r'), CTRL('t'), CTRL('y'),
|
{ CTRL('q'), CTRL('w'), CTRL('e'), CTRL('r'), CTRL('t'), CTRL('y'),
|
CTRL('u'), CTRL('i'), CTRL('o'), CTRL('p'), CODE_ESC },
|
CTRL('u'), CTRL('i'), CTRL('o'), CTRL('p'), CODE_ESC },
|
{ CTRL('a'), CTRL('s'), CTRL('d'), CTRL('f'), CTRL('g'), CTRL('h'),
|
{ CTRL('a'), CTRL('s'), CTRL('d'), CTRL('f'), CTRL('g'), CTRL('h'),
|
CTRL('j'), CTRL('k'), CTRL('l'), CTRL('_'), CODE_CR },
|
CTRL('j'), CTRL('k'), CTRL('l'), CTRL('_'), CODE_CR },
|
{ CODE_CTRL, CTRL('z'), CTRL('x'), CTRL('c'), CTRL('v'), CTRL('b'),
|
{ CODE_CTRL, CTRL('z'), CTRL('x'), CTRL('c'), CTRL('v'), CTRL('b'),
|
CTRL('n'), CTRL('m'), '\\', CTRL(']'), CTRL('^') },
|
CTRL('n'), CTRL('m'), '\\', CTRL(']'), CTRL('^') },
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, ' ', ' ', ' ', CODE_DEL}
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, ' ', ' ', ' ', CODE_DEL}
|
};
|
};
|
|
|
static kbd_map kbd_shift_map = {
|
static kbd_map kbd_shift_map = {
|
{ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', CODE_BS },
|
{ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', CODE_BS },
|
{ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '_', CODE_CR },
|
{ 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '_', CODE_CR },
|
{ CODE_CTRL, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', ':' },
|
{ CODE_CTRL, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', ':' },
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '"', '+', '|', '?'}
|
{ CODE_SHIFT, CODE_SHIFT, ' ', ' ', ' ', ' ', CODE_NUM, '"', '+', '|', '?'}
|
};
|
};
|
|
|
static kbd_map *cur_kbd_map = &kbd_norm_map;
|
static kbd_map *cur_kbd_map = &kbd_norm_map;
|
static bool kbd_active = true;
|
static bool kbd_active = true;
|
|
|
// Pseudo-keyboard indicator
|
// Pseudo-keyboard indicator
|
#define LCD_KBD_NORM 0
|
#define LCD_KBD_NORM 0
|
#define LCD_KBD_SHIFT 1
|
#define LCD_KBD_SHIFT 1
|
#define LCD_KBD_NUM 2
|
#define LCD_KBD_NUM 2
|
#define LCD_KBD_CTRL 3
|
#define LCD_KBD_CTRL 3
|
|
|
// Display pseudo keyboard
|
// Display pseudo keyboard
|
static void
|
static void
|
lcd_kbd(int which)
|
lcd_kbd(int which)
|
{
|
{
|
char **kbd_xpm;
|
char **kbd_xpm;
|
|
|
switch (which) {
|
switch (which) {
|
case LCD_KBD_NORM:
|
case LCD_KBD_NORM:
|
kbd_xpm = keynorm_xpm;
|
kbd_xpm = keynorm_xpm;
|
break;
|
break;
|
case LCD_KBD_SHIFT:
|
case LCD_KBD_SHIFT:
|
kbd_xpm = keyshft_xpm;
|
kbd_xpm = keyshft_xpm;
|
break;
|
break;
|
case LCD_KBD_CTRL:
|
case LCD_KBD_CTRL:
|
kbd_xpm = keyctrl_xpm;
|
kbd_xpm = keyctrl_xpm;
|
break;
|
break;
|
case LCD_KBD_NUM:
|
case LCD_KBD_NUM:
|
kbd_xpm = keynum_xpm;
|
kbd_xpm = keynum_xpm;
|
break;
|
break;
|
default:
|
default:
|
return;
|
return;
|
}
|
}
|
show_xpm(kbd_xpm, kbd_pos);
|
show_xpm(kbd_xpm, kbd_pos);
|
}
|
}
|
|
|
static bool
|
static bool
|
inside(int pos, int lim1, int lim2)
|
inside(int pos, int lim1, int lim2)
|
{
|
{
|
if (lim1 <= lim2) {
|
if (lim1 <= lim2) {
|
return ((pos >= lim1) && (pos <= lim2));
|
return ((pos >= lim1) && (pos <= lim2));
|
} else {
|
} else {
|
return ((pos >= lim2) && (pos <= lim1));
|
return ((pos >= lim2) && (pos <= lim1));
|
}
|
}
|
}
|
}
|
|
|
static int
|
static int
|
abs(int x)
|
abs(int x)
|
{
|
{
|
if (x < 0) {
|
if (x < 0) {
|
return -x;
|
return -x;
|
} else {
|
} else {
|
return x;
|
return x;
|
}
|
}
|
}
|
}
|
|
|
static int
|
static int
|
min(int x, int y)
|
min(int x, int y)
|
{
|
{
|
if (x < y) {
|
if (x < y) {
|
return x;
|
return x;
|
} else {
|
} else {
|
return y;
|
return y;
|
}
|
}
|
}
|
}
|
|
|
static int
|
static int
|
max(int x, int y)
|
max(int x, int y)
|
{
|
{
|
if (x < y) {
|
if (x < y) {
|
return y;
|
return y;
|
} else {
|
} else {
|
return x;
|
return x;
|
}
|
}
|
}
|
}
|
|
|
static cyg_bool
|
static cyg_bool
|
lcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch)
|
lcd_comm_getc_nonblock(void* __ch_data, cyg_uint8* ch)
|
{
|
{
|
static bool pen_down = false;
|
static bool pen_down = false;
|
static bool waiting_for_pen_down = true;
|
static bool waiting_for_pen_down = true;
|
static int total_events = 0;
|
static int total_events = 0;
|
static int pen_idle;
|
static int pen_idle;
|
static unsigned long totalX, totalY;
|
static unsigned long totalX, totalY;
|
struct ts_event tse;
|
struct ts_event tse;
|
struct key_event ke;
|
struct key_event ke;
|
//#define KBD_DEBUG
|
//#define KBD_DEBUG
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
static bool dump_info = false;
|
static bool dump_info = false;
|
#endif
|
#endif
|
#define PEN_IDLE_TIMEOUT 50000
|
#define PEN_IDLE_TIMEOUT 50000
|
#define MIN_KBD_EVENTS 10
|
#define MIN_KBD_EVENTS 10
|
|
|
// See if any buttons have been pushed
|
// See if any buttons have been pushed
|
if (key_get_event(&ke)) {
|
if (key_get_event(&ke)) {
|
if ((ke.button_info & ATMEL_BUTTON_STATE) == ATMEL_BUTTON_STATE_UP) {
|
if ((ke.button_info & ATMEL_BUTTON_STATE) == ATMEL_BUTTON_STATE_UP) {
|
// diag_printf("Key = %x\n", ke.button_info);
|
// diag_printf("Key = %x\n", ke.button_info);
|
lcd_on(true);
|
lcd_on(true);
|
switch (ke.button_info & ATMEL_BUTTON_VALUE) {
|
switch (ke.button_info & ATMEL_BUTTON_VALUE) {
|
case ATMEL_BUTTON_RETURN:
|
case ATMEL_BUTTON_RETURN:
|
*ch = CTRL('C');
|
*ch = CTRL('C');
|
return true;
|
return true;
|
case ATMEL_BUTTON_JOY_DOWN:
|
case ATMEL_BUTTON_JOY_DOWN:
|
case ATMEL_BUTTON_JOY_UP:
|
case ATMEL_BUTTON_JOY_UP:
|
screen_pan = 0;
|
screen_pan = 0;
|
lcd_refresh();
|
lcd_refresh();
|
break;
|
break;
|
case ATMEL_BUTTON_JOY_LEFT:
|
case ATMEL_BUTTON_JOY_LEFT:
|
screen_pan -= SCREEN_PAN;
|
screen_pan -= SCREEN_PAN;
|
if (screen_pan < 0) screen_pan = 0;
|
if (screen_pan < 0) screen_pan = 0;
|
lcd_refresh();
|
lcd_refresh();
|
break;
|
break;
|
case ATMEL_BUTTON_JOY_RIGHT:
|
case ATMEL_BUTTON_JOY_RIGHT:
|
screen_pan += SCREEN_PAN;
|
screen_pan += SCREEN_PAN;
|
if (screen_pan > (SCREEN_WIDTH-SCREEN_PAN)) screen_pan = SCREEN_WIDTH-SCREEN_PAN;
|
if (screen_pan > (SCREEN_WIDTH-SCREEN_PAN)) screen_pan = SCREEN_WIDTH-SCREEN_PAN;
|
lcd_refresh();
|
lcd_refresh();
|
break;
|
break;
|
default:
|
default:
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
{
|
{
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
end_console(cur);
|
end_console(cur);
|
dump_info = !dump_info;
|
dump_info = !dump_info;
|
}
|
}
|
#endif
|
#endif
|
return false;
|
return false;
|
}
|
}
|
}
|
}
|
return false; // Ignore down presses
|
return false; // Ignore down presses
|
}
|
}
|
// If keyboard not active, always returns false
|
// If keyboard not active, always returns false
|
if (!kbd_active) {
|
if (!kbd_active) {
|
return false;
|
return false;
|
}
|
}
|
// Wait for pen down
|
// Wait for pen down
|
if (waiting_for_pen_down) {
|
if (waiting_for_pen_down) {
|
if (ts_get_event(&tse)) {
|
if (ts_get_event(&tse)) {
|
lcd_on(true);
|
lcd_on(true);
|
if (!tse.up) {
|
if (!tse.up) {
|
pen_down = true;
|
pen_down = true;
|
waiting_for_pen_down = false;
|
waiting_for_pen_down = false;
|
totalX = totalY = 0;
|
totalX = totalY = 0;
|
total_events = 0;
|
total_events = 0;
|
pen_idle = PEN_IDLE_TIMEOUT;
|
pen_idle = PEN_IDLE_TIMEOUT;
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
if (dump_info) {
|
if (dump_info) {
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
diag_printf("start pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
end_console(cur);
|
end_console(cur);
|
}
|
}
|
#endif
|
#endif
|
}
|
}
|
}
|
}
|
return false;
|
return false;
|
}
|
}
|
// While the pen is down, accumulate some data
|
// While the pen is down, accumulate some data
|
if (ts_get_event(&tse)) {
|
if (ts_get_event(&tse)) {
|
pen_idle = PEN_IDLE_TIMEOUT;
|
pen_idle = PEN_IDLE_TIMEOUT;
|
if (tse.up) {
|
if (tse.up) {
|
pen_down = false;
|
pen_down = false;
|
waiting_for_pen_down = true;
|
waiting_for_pen_down = true;
|
} else {
|
} else {
|
total_events++;
|
total_events++;
|
pen_down = true;
|
pen_down = true;
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
totalX += tse.y;
|
totalX += tse.y;
|
totalY += tse.x;
|
totalY += tse.x;
|
#else
|
#else
|
totalX += tse.x;
|
totalX += tse.x;
|
totalY += tse.y;
|
totalY += tse.y;
|
#endif
|
#endif
|
}
|
}
|
} else {
|
} else {
|
if (--pen_idle == 0) {
|
if (--pen_idle == 0) {
|
pen_down = false;
|
pen_down = false;
|
waiting_for_pen_down = true;
|
waiting_for_pen_down = true;
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
if (dump_info) {
|
if (dump_info) {
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("going idle\n");
|
diag_printf("going idle\n");
|
end_console(cur);
|
end_console(cur);
|
}
|
}
|
#endif
|
#endif
|
}
|
}
|
return false;
|
return false;
|
}
|
}
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
if (dump_info) {
|
if (dump_info) {
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
diag_printf("pen: %d, waiting: %d, total: %d\n", pen_down, waiting_for_pen_down, total_events);
|
end_console(cur);
|
end_console(cur);
|
}
|
}
|
#endif
|
#endif
|
if (total_events == MIN_KBD_EVENTS) {
|
if (total_events == MIN_KBD_EVENTS) {
|
// If pen just went up then see if this was a valid
|
// If pen just went up then see if this was a valid
|
// character (inside the keyboard picture, etc)
|
// character (inside the keyboard picture, etc)
|
int x = totalX/total_events;
|
int x = totalX/total_events;
|
int y = totalY/total_events;
|
int y = totalY/total_events;
|
int row, col;
|
int row, col;
|
int char_width, char_height;
|
int char_width, char_height;
|
unsigned char kbd_ch;
|
unsigned char kbd_ch;
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
if (dump_info) {
|
if (dump_info) {
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("Pen[%d] at %d/%d\n", total_events, x, y);
|
diag_printf("Pen[%d] at %d/%d\n", total_events, x, y);
|
end_console(cur);
|
end_console(cur);
|
}
|
}
|
#endif
|
#endif
|
// Try and determine row/col in our keyboard matrix
|
// Try and determine row/col in our keyboard matrix
|
if (inside(x, minX, maxX) && inside(y, minY, maxY)) {
|
if (inside(x, minX, maxX) && inside(y, minY, maxY)) {
|
// Point seems to be with the matrix
|
// Point seems to be with the matrix
|
char_width = abs(minX - maxX) / 11;
|
char_width = abs(minX - maxX) / 11;
|
char_height = abs(minY - maxY) / 4;
|
char_height = abs(minY - maxY) / 4;
|
col = abs(x-maxX) / char_width;
|
col = abs(x-maxX) / char_width;
|
row = abs(y-minY) / char_height;
|
row = abs(y-minY) / char_height;
|
kbd_ch = (*cur_kbd_map)[row][col];
|
kbd_ch = (*cur_kbd_map)[row][col];
|
#ifdef KBD_DEBUG
|
#ifdef KBD_DEBUG
|
if (dump_info) {
|
if (dump_info) {
|
int cur = start_console(0);
|
int cur = start_console(0);
|
diag_printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch);
|
diag_printf("Row/Col = %d/%d = %x\n", row, col, kbd_ch);
|
end_console(cur);
|
end_console(cur);
|
}
|
}
|
#endif
|
#endif
|
switch (kbd_ch) {
|
switch (kbd_ch) {
|
case CODE_SHIFT:
|
case CODE_SHIFT:
|
if (cur_kbd_map == &kbd_shift_map) {
|
if (cur_kbd_map == &kbd_shift_map) {
|
cur_kbd_map = &kbd_norm_map;
|
cur_kbd_map = &kbd_norm_map;
|
lcd_kbd(LCD_KBD_NORM);
|
lcd_kbd(LCD_KBD_NORM);
|
} else {
|
} else {
|
cur_kbd_map = &kbd_shift_map;
|
cur_kbd_map = &kbd_shift_map;
|
lcd_kbd(LCD_KBD_SHIFT);
|
lcd_kbd(LCD_KBD_SHIFT);
|
}
|
}
|
break;
|
break;
|
case CODE_CTRL:
|
case CODE_CTRL:
|
if (cur_kbd_map == &kbd_ctrl_map) {
|
if (cur_kbd_map == &kbd_ctrl_map) {
|
cur_kbd_map = &kbd_norm_map;
|
cur_kbd_map = &kbd_norm_map;
|
lcd_kbd(LCD_KBD_NORM);
|
lcd_kbd(LCD_KBD_NORM);
|
} else {
|
} else {
|
cur_kbd_map = &kbd_ctrl_map;
|
cur_kbd_map = &kbd_ctrl_map;
|
lcd_kbd(LCD_KBD_CTRL);
|
lcd_kbd(LCD_KBD_CTRL);
|
}
|
}
|
break;
|
break;
|
case CODE_NUM:
|
case CODE_NUM:
|
if (cur_kbd_map == &kbd_num_map) {
|
if (cur_kbd_map == &kbd_num_map) {
|
cur_kbd_map = &kbd_norm_map;
|
cur_kbd_map = &kbd_norm_map;
|
lcd_kbd(LCD_KBD_NORM);
|
lcd_kbd(LCD_KBD_NORM);
|
} else {
|
} else {
|
cur_kbd_map = &kbd_num_map;
|
cur_kbd_map = &kbd_num_map;
|
lcd_kbd(LCD_KBD_NUM);
|
lcd_kbd(LCD_KBD_NUM);
|
}
|
}
|
break;
|
break;
|
case CODE_NONE:
|
case CODE_NONE:
|
break;
|
break;
|
default:
|
default:
|
*ch = kbd_ch;
|
*ch = kbd_ch;
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
}
|
}
|
return false;
|
return false;
|
}
|
}
|
|
|
static cyg_uint8
|
static cyg_uint8
|
lcd_comm_getc(void* __ch_data)
|
lcd_comm_getc(void* __ch_data)
|
{
|
{
|
cyg_uint8 ch;
|
cyg_uint8 ch;
|
|
|
while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;
|
while (!lcd_comm_getc_nonblock(__ch_data, &ch)) ;
|
return ch;
|
return ch;
|
}
|
}
|
|
|
static void
|
static void
|
lcd_comm_putc(void* __ch_data, cyg_uint8 c)
|
lcd_comm_putc(void* __ch_data, cyg_uint8 c)
|
{
|
{
|
lcd_putc(c);
|
lcd_putc(c);
|
}
|
}
|
|
|
static void
|
static void
|
lcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
|
lcd_comm_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
|
{
|
{
|
#if 0
|
#if 0
|
CYGARC_HAL_SAVE_GP();
|
CYGARC_HAL_SAVE_GP();
|
|
|
while(__len-- > 0)
|
while(__len-- > 0)
|
lcd_comm_putc(__ch_data, *__buf++);
|
lcd_comm_putc(__ch_data, *__buf++);
|
|
|
CYGARC_HAL_RESTORE_GP();
|
CYGARC_HAL_RESTORE_GP();
|
#endif
|
#endif
|
}
|
}
|
|
|
static void
|
static void
|
lcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
|
lcd_comm_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
|
{
|
{
|
#if 0
|
#if 0
|
CYGARC_HAL_SAVE_GP();
|
CYGARC_HAL_SAVE_GP();
|
|
|
while(__len-- > 0)
|
while(__len-- > 0)
|
*__buf++ = lcd_comm_getc(__ch_data);
|
*__buf++ = lcd_comm_getc(__ch_data);
|
|
|
CYGARC_HAL_RESTORE_GP();
|
CYGARC_HAL_RESTORE_GP();
|
#endif
|
#endif
|
}
|
}
|
|
|
static cyg_bool
|
static cyg_bool
|
lcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch)
|
lcd_comm_getc_timeout(void* __ch_data, cyg_uint8* ch)
|
{
|
{
|
int delay_count;
|
int delay_count;
|
cyg_bool res;
|
cyg_bool res;
|
|
|
delay_count = _timeout * 10; // delay in .1 ms steps
|
delay_count = _timeout * 10; // delay in .1 ms steps
|
for(;;) {
|
for(;;) {
|
res = lcd_comm_getc_nonblock(__ch_data, ch);
|
res = lcd_comm_getc_nonblock(__ch_data, ch);
|
if (res || 0 == delay_count--)
|
if (res || 0 == delay_count--)
|
break;
|
break;
|
CYGACC_CALL_IF_DELAY_US(100);
|
CYGACC_CALL_IF_DELAY_US(100);
|
}
|
}
|
return res;
|
return res;
|
}
|
}
|
|
|
static int
|
static int
|
lcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...)
|
lcd_comm_control(void *__ch_data, __comm_control_cmd_t __func, ...)
|
{
|
{
|
static int vector = 0;
|
static int vector = 0;
|
int ret = -1;
|
int ret = -1;
|
static int irq_state = 0;
|
static int irq_state = 0;
|
|
|
CYGARC_HAL_SAVE_GP();
|
CYGARC_HAL_SAVE_GP();
|
|
|
switch (__func) {
|
switch (__func) {
|
case __COMMCTL_IRQ_ENABLE:
|
case __COMMCTL_IRQ_ENABLE:
|
ret = irq_state;
|
ret = irq_state;
|
irq_state = 1;
|
irq_state = 1;
|
#if 0
|
#if 0
|
if (vector == 0) {
|
if (vector == 0) {
|
vector = eth_drv_int_vector();
|
vector = eth_drv_int_vector();
|
}
|
}
|
HAL_INTERRUPT_UNMASK(vector);
|
HAL_INTERRUPT_UNMASK(vector);
|
#endif
|
#endif
|
break;
|
break;
|
case __COMMCTL_IRQ_DISABLE:
|
case __COMMCTL_IRQ_DISABLE:
|
ret = irq_state;
|
ret = irq_state;
|
irq_state = 0;
|
irq_state = 0;
|
#if 0
|
#if 0
|
HAL_INTERRUPT_MASK(vector);
|
HAL_INTERRUPT_MASK(vector);
|
#endif
|
#endif
|
break;
|
break;
|
case __COMMCTL_DBG_ISR_VECTOR:
|
case __COMMCTL_DBG_ISR_VECTOR:
|
ret = vector;
|
ret = vector;
|
break;
|
break;
|
case __COMMCTL_SET_TIMEOUT:
|
case __COMMCTL_SET_TIMEOUT:
|
{
|
{
|
va_list ap;
|
va_list ap;
|
|
|
va_start(ap, __func);
|
va_start(ap, __func);
|
|
|
ret = _timeout;
|
ret = _timeout;
|
_timeout = va_arg(ap, cyg_uint32);
|
_timeout = va_arg(ap, cyg_uint32);
|
|
|
va_end(ap);
|
va_end(ap);
|
break;
|
break;
|
}
|
}
|
case __COMMCTL_FLUSH_OUTPUT:
|
case __COMMCTL_FLUSH_OUTPUT:
|
case __COMMCTL_GETBAUD:
|
case __COMMCTL_GETBAUD:
|
case __COMMCTL_SETBAUD:
|
case __COMMCTL_SETBAUD:
|
ret = 0;
|
ret = 0;
|
break;
|
break;
|
default:
|
default:
|
break;
|
break;
|
}
|
}
|
CYGARC_HAL_RESTORE_GP();
|
CYGARC_HAL_RESTORE_GP();
|
return ret;
|
return ret;
|
}
|
}
|
|
|
static int
|
static int
|
lcd_comm_isr(void *__ch_data, int* __ctrlc,
|
lcd_comm_isr(void *__ch_data, int* __ctrlc,
|
CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
|
CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
|
{
|
{
|
#if 0
|
#if 0
|
char ch;
|
char ch;
|
|
|
cyg_drv_interrupt_acknowledge(__vector);
|
cyg_drv_interrupt_acknowledge(__vector);
|
*__ctrlc = 0;
|
*__ctrlc = 0;
|
if (lcd_comm_getc_nonblock(__ch_data, &ch)) {
|
if (lcd_comm_getc_nonblock(__ch_data, &ch)) {
|
if (ch == 0x03) {
|
if (ch == 0x03) {
|
*__ctrlc = 1;
|
*__ctrlc = 1;
|
}
|
}
|
}
|
}
|
return CYG_ISR_HANDLED;
|
return CYG_ISR_HANDLED;
|
#endif
|
#endif
|
return 0;
|
return 0;
|
}
|
}
|
|
|
static bool
|
static bool
|
init_kbd_coord(int indx, char *prompt_char)
|
init_kbd_coord(int indx, char *prompt_char)
|
{
|
{
|
char prompt[] = "Press %s on kbd graphic";
|
char prompt[] = "Press %s on kbd graphic";
|
int off = ((VISIBLE_SCREEN_WIDTH-sizeof(prompt))/2)-1;
|
int off = ((VISIBLE_SCREEN_WIDTH-sizeof(prompt))/2)-1;
|
int off2 = ((VISIBLE_SCREEN_WIDTH-20)/2)-1;
|
int off2 = ((VISIBLE_SCREEN_WIDTH-20)/2)-1;
|
struct ts_event tse;
|
struct ts_event tse;
|
struct key_event ke;
|
struct key_event ke;
|
bool pen_down;
|
bool pen_down;
|
int i, down_timer, total_events;
|
int i, down_timer, total_events;
|
int timeout = 100000;
|
int timeout = 100000;
|
unsigned long totalX, totalY;
|
unsigned long totalX, totalY;
|
|
|
lcd_moveto(off, screen_height/2);
|
lcd_moveto(off, screen_height/2);
|
lcd_printf(prompt, prompt_char);
|
lcd_printf(prompt, prompt_char);
|
lcd_moveto(off2, (screen_height/2)+2);
|
lcd_moveto(off2, (screen_height/2)+2);
|
lcd_printf("Keep pen down until");
|
lcd_printf("Keep pen down until");
|
lcd_moveto(off2, (screen_height/2)+3);
|
lcd_moveto(off2, (screen_height/2)+3);
|
lcd_printf("message disappears");
|
lcd_printf("message disappears");
|
pen_down = false;
|
pen_down = false;
|
down_timer = 0;
|
down_timer = 0;
|
total_events = 0;
|
total_events = 0;
|
totalX = totalY = 0;
|
totalX = totalY = 0;
|
// Wait for a pen-down event
|
// Wait for a pen-down event
|
while (!pen_down) {
|
while (!pen_down) {
|
if (ts_get_event(&tse)) {
|
if (ts_get_event(&tse)) {
|
if (!tse.up) {
|
if (!tse.up) {
|
pen_down = true;
|
pen_down = true;
|
}
|
}
|
}
|
}
|
if (key_get_event(&ke)) {
|
if (key_get_event(&ke)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
if (--timeout == 0) {
|
if (--timeout == 0) {
|
// Give up if the guy hasn't pressed anything
|
// Give up if the guy hasn't pressed anything
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
// Now accumulate data
|
// Now accumulate data
|
// Assumption: the Atmel can send at most 3 position reports
|
// Assumption: the Atmel can send at most 3 position reports
|
// per millisecond. We should wait for 50ms before moving on
|
// per millisecond. We should wait for 50ms before moving on
|
while (total_events < 100) {
|
while (total_events < 100) {
|
if (ts_get_event(&tse)) {
|
if (ts_get_event(&tse)) {
|
if (tse.up) {
|
if (tse.up) {
|
pen_down = false;
|
pen_down = false;
|
continue;
|
continue;
|
} else {
|
} else {
|
#ifdef PORTRAIT_MODE
|
#ifdef PORTRAIT_MODE
|
totalX += tse.y;
|
totalX += tse.y;
|
totalY += tse.x;
|
totalY += tse.x;
|
#else
|
#else
|
totalX += tse.x;
|
totalX += tse.x;
|
totalY += tse.y;
|
totalY += tse.y;
|
#endif
|
#endif
|
total_events++;
|
total_events++;
|
pen_down = true;
|
pen_down = true;
|
}
|
}
|
}
|
}
|
if (key_get_event(&ke)) {
|
if (key_get_event(&ke)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
}
|
}
|
// Tell the guy we have enough data
|
// Tell the guy we have enough data
|
lcd_moveto(off, screen_height/2);
|
lcd_moveto(off, screen_height/2);
|
for (i = 0; i < screen_width; i++) {
|
for (i = 0; i < screen_width; i++) {
|
lcd_putc(' ');
|
lcd_putc(' ');
|
}
|
}
|
// Now wait for the pen to go back up
|
// Now wait for the pen to go back up
|
while (pen_down) {
|
while (pen_down) {
|
if (ts_get_event(&tse)) {
|
if (ts_get_event(&tse)) {
|
if (tse.up) {
|
if (tse.up) {
|
pen_down = false;
|
pen_down = false;
|
}
|
}
|
}
|
}
|
if (key_get_event(&ke)) {
|
if (key_get_event(&ke)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
if (ke.button_info == (ATMEL_BUTTON_STATE_UP|ATMEL_BUTTON_RETURN)) {
|
return true;
|
return true;
|
}
|
}
|
}
|
}
|
}
|
}
|
kbd_limits[indx].x = totalX / total_events;
|
kbd_limits[indx].x = totalX / total_events;
|
kbd_limits[indx].y = totalY / total_events;
|
kbd_limits[indx].y = totalY / total_events;
|
return false;
|
return false;
|
}
|
}
|
|
|
static bool
|
static bool
|
close(int c1, int c2)
|
close(int c1, int c2)
|
{
|
{
|
int diff = c1 - c2;
|
int diff = c1 - c2;
|
if (diff < 0) diff = -diff;
|
if (diff < 0) diff = -diff;
|
return (diff < 50);
|
return (diff < 50);
|
}
|
}
|
|
|
#define LCD_COMM_CHANNEL 1 // Logical I/O channel used for LCD/TS console
|
#define LCD_COMM_CHANNEL 1 // Logical I/O channel used for LCD/TS console
|
|
|
void
|
void
|
lcd_comm_init(void)
|
lcd_comm_init(void)
|
{
|
{
|
static int init = 0;
|
static int init = 0;
|
bool need_params = true;
|
bool need_params = true;
|
unsigned short cksum, param;
|
unsigned short cksum, param;
|
int i;
|
int i;
|
|
|
if (!init) {
|
if (!init) {
|
hal_virtual_comm_table_t* comm;
|
hal_virtual_comm_table_t* comm;
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
|
|
// Setup procs in the vector table
|
// Setup procs in the vector table
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(LCD_COMM_CHANNEL);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(LCD_COMM_CHANNEL);
|
comm = CYGACC_CALL_IF_CONSOLE_PROCS();
|
comm = CYGACC_CALL_IF_CONSOLE_PROCS();
|
//CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
|
//CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
|
CYGACC_COMM_IF_WRITE_SET(*comm, lcd_comm_write);
|
CYGACC_COMM_IF_WRITE_SET(*comm, lcd_comm_write);
|
CYGACC_COMM_IF_READ_SET(*comm, lcd_comm_read);
|
CYGACC_COMM_IF_READ_SET(*comm, lcd_comm_read);
|
CYGACC_COMM_IF_PUTC_SET(*comm, lcd_comm_putc);
|
CYGACC_COMM_IF_PUTC_SET(*comm, lcd_comm_putc);
|
CYGACC_COMM_IF_GETC_SET(*comm, lcd_comm_getc);
|
CYGACC_COMM_IF_GETC_SET(*comm, lcd_comm_getc);
|
CYGACC_COMM_IF_CONTROL_SET(*comm, lcd_comm_control);
|
CYGACC_COMM_IF_CONTROL_SET(*comm, lcd_comm_control);
|
CYGACC_COMM_IF_DBG_ISR_SET(*comm, lcd_comm_isr);
|
CYGACC_COMM_IF_DBG_ISR_SET(*comm, lcd_comm_isr);
|
CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, lcd_comm_getc_timeout);
|
CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, lcd_comm_getc_timeout);
|
|
|
// Restore original console
|
// Restore original console
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
|
|
init = 1;
|
init = 1;
|
|
|
// Pick up parameters for virtual keyboard from RAM
|
// Pick up parameters for virtual keyboard from RAM
|
cksum = (unsigned short)&_ipaq_LCD_params[0];
|
cksum = (unsigned short)&_ipaq_LCD_params[0];
|
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
param = _ipaq_LCD_params[i*2];
|
param = _ipaq_LCD_params[i*2];
|
kbd_limits[i].x = param;
|
kbd_limits[i].x = param;
|
cksum ^= param;
|
cksum ^= param;
|
param = _ipaq_LCD_params[(i*2)+1];
|
param = _ipaq_LCD_params[(i*2)+1];
|
kbd_limits[i].y = param;
|
kbd_limits[i].y = param;
|
cksum ^= param;
|
cksum ^= param;
|
}
|
}
|
need_params = cksum != _ipaq_LCD_params[(4*2)+1];
|
need_params = cksum != _ipaq_LCD_params[(4*2)+1];
|
|
|
// If the data are currently bad, set up some defaults
|
// If the data are currently bad, set up some defaults
|
if (need_params) {
|
if (need_params) {
|
kbd_limits[CS_UL].x = 994;
|
kbd_limits[CS_UL].x = 994;
|
kbd_limits[CS_UL].y = 710;
|
kbd_limits[CS_UL].y = 710;
|
kbd_limits[CS_UR].x = 413;
|
kbd_limits[CS_UR].x = 413;
|
kbd_limits[CS_UR].y = 710;
|
kbd_limits[CS_UR].y = 710;
|
kbd_limits[CS_LL].x = 989;
|
kbd_limits[CS_LL].x = 989;
|
kbd_limits[CS_LL].y = 839;
|
kbd_limits[CS_LL].y = 839;
|
kbd_limits[CS_LR].x = 411;
|
kbd_limits[CS_LR].x = 411;
|
kbd_limits[CS_LR].y = 836;
|
kbd_limits[CS_LR].y = 836;
|
}
|
}
|
|
|
if (!need_params) {
|
if (!need_params) {
|
// See if the guy wants to force new parameters
|
// See if the guy wants to force new parameters
|
lcd_clear();
|
lcd_clear();
|
lcd_moveto(5, screen_height/2);
|
lcd_moveto(5, screen_height/2);
|
lcd_printf("Calibrate touch screen?\n");
|
lcd_printf("Calibrate touch screen?\n");
|
lcd_moveto(5, (screen_height/2)+1);
|
lcd_moveto(5, (screen_height/2)+1);
|
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
struct key_event ke;
|
struct key_event ke;
|
if (key_get_event(&ke) && ((ke.button_info & ATMEL_BUTTON_STATE) == ATMEL_BUTTON_STATE_UP)) {
|
if (key_get_event(&ke) && ((ke.button_info & ATMEL_BUTTON_STATE) == ATMEL_BUTTON_STATE_UP)) {
|
need_params = (ke.button_info & ATMEL_BUTTON_VALUE) != ATMEL_BUTTON_RETURN;
|
need_params = (ke.button_info & ATMEL_BUTTON_VALUE) != ATMEL_BUTTON_RETURN;
|
break;
|
break;
|
}
|
}
|
CYGACC_CALL_IF_DELAY_US(50000);
|
CYGACC_CALL_IF_DELAY_US(50000);
|
lcd_putc('.');
|
lcd_putc('.');
|
}
|
}
|
}
|
}
|
|
|
while (need_params) {
|
while (need_params) {
|
cursor_enable = false;
|
cursor_enable = false;
|
lcd_clear();
|
lcd_clear();
|
lcd_kbd(LCD_KBD_NORM);
|
lcd_kbd(LCD_KBD_NORM);
|
if (init_kbd_coord(CS_UL, "'q'")) {
|
if (init_kbd_coord(CS_UL, "'q'")) {
|
goto no_kbd;
|
goto no_kbd;
|
}
|
}
|
if (init_kbd_coord(CS_UR, "BS ")) {
|
if (init_kbd_coord(CS_UR, "BS ")) {
|
goto no_kbd;
|
goto no_kbd;
|
}
|
}
|
if (init_kbd_coord(CS_LL, "SHIFT")) {
|
if (init_kbd_coord(CS_LL, "SHIFT")) {
|
goto no_kbd;
|
goto no_kbd;
|
}
|
}
|
if (init_kbd_coord(CS_LR, "'/' ")) {
|
if (init_kbd_coord(CS_LR, "'/' ")) {
|
goto no_kbd;
|
goto no_kbd;
|
}
|
}
|
cursor_enable = true;
|
cursor_enable = true;
|
if (close(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) &&
|
if (close(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) &&
|
close(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) &&
|
close(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) &&
|
close(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) &&
|
close(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) &&
|
close(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y)) {
|
close(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y)) {
|
// Save values so we don't need to repeat this
|
// Save values so we don't need to repeat this
|
cksum = (unsigned short)&_ipaq_LCD_params[0];
|
cksum = (unsigned short)&_ipaq_LCD_params[0];
|
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
param = kbd_limits[i].x;
|
param = kbd_limits[i].x;
|
cksum ^= param;
|
cksum ^= param;
|
_ipaq_LCD_params[i*2] = param;
|
_ipaq_LCD_params[i*2] = param;
|
param = kbd_limits[i].y;
|
param = kbd_limits[i].y;
|
cksum ^= param;
|
cksum ^= param;
|
_ipaq_LCD_params[(i*2)+1] = param;
|
_ipaq_LCD_params[(i*2)+1] = param;
|
}
|
}
|
_ipaq_LCD_params[(4*2)+1] = cksum;
|
_ipaq_LCD_params[(4*2)+1] = cksum;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
|
|
no_kbd:
|
no_kbd:
|
// Munge the limits to allow for some slop
|
// Munge the limits to allow for some slop
|
if (kbd_limits[CS_UL].x < kbd_limits[CS_UR].x) {
|
if (kbd_limits[CS_UL].x < kbd_limits[CS_UR].x) {
|
minX = min(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) - KBD_FUZZ;
|
minX = min(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) - KBD_FUZZ;
|
maxX = max(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) + KBD_FUZZ;
|
maxX = max(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) + KBD_FUZZ;
|
} else {
|
} else {
|
minX = min(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) - KBD_FUZZ;
|
minX = min(kbd_limits[CS_UR].x, kbd_limits[CS_LR].x) - KBD_FUZZ;
|
maxX = max(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) + KBD_FUZZ;
|
maxX = max(kbd_limits[CS_UL].x, kbd_limits[CS_LL].x) + KBD_FUZZ;
|
}
|
}
|
if (kbd_limits[CS_UL].y < kbd_limits[CS_LL].y) {
|
if (kbd_limits[CS_UL].y < kbd_limits[CS_LL].y) {
|
minY = min(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) - KBD_FUZZ;
|
minY = min(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) - KBD_FUZZ;
|
maxY = max(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y) + KBD_FUZZ;
|
maxY = max(kbd_limits[CS_LL].y, kbd_limits[CS_LR].y) + KBD_FUZZ;
|
} else {
|
} else {
|
minY = min(kbd_limits[CS_LR].y, kbd_limits[CS_LL].y) - KBD_FUZZ;
|
minY = min(kbd_limits[CS_LR].y, kbd_limits[CS_LL].y) - KBD_FUZZ;
|
maxY = max(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) + KBD_FUZZ;
|
maxY = max(kbd_limits[CS_UL].y, kbd_limits[CS_UR].y) + KBD_FUZZ;
|
}
|
}
|
cursor_enable = true;
|
cursor_enable = true;
|
lcd_clear();
|
lcd_clear();
|
if (kbd_active) {
|
if (kbd_active) {
|
lcd_kbd(LCD_KBD_NORM);
|
lcd_kbd(LCD_KBD_NORM);
|
}
|
}
|
#if 0
|
#if 0
|
diag_printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n",
|
diag_printf("KBD Limits[] = %d/%d, %d/%d, %d/%d, %d/%d\n",
|
kbd_limits[CS_UL].x, kbd_limits[CS_UL].y,
|
kbd_limits[CS_UL].x, kbd_limits[CS_UL].y,
|
kbd_limits[CS_UR].x, kbd_limits[CS_UR].y,
|
kbd_limits[CS_UR].x, kbd_limits[CS_UR].y,
|
kbd_limits[CS_LL].x, kbd_limits[CS_LL].y,
|
kbd_limits[CS_LL].x, kbd_limits[CS_LL].y,
|
kbd_limits[CS_LR].x, kbd_limits[CS_LR].y);
|
kbd_limits[CS_LR].x, kbd_limits[CS_LR].y);
|
diag_printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY);
|
diag_printf("KBD in %d/%d .. %d/%d\n", minX, minY, maxX, maxY);
|
diag_printf("screen %d x %d\n", screen_height, screen_width);
|
diag_printf("screen %d x %d\n", screen_height, screen_width);
|
#endif
|
#endif
|
}
|
}
|
}
|
}
|
|
|
// Control state of LCD display - only called by logical I/O layers
|
// Control state of LCD display - only called by logical I/O layers
|
|
|
void
|
void
|
lcd_on(bool enable)
|
lcd_on(bool enable)
|
{
|
{
|
static bool enabled = true;
|
static bool enabled = true;
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
|
|
if (cur != LCD_COMM_CHANNEL)
|
if (cur != LCD_COMM_CHANNEL)
|
enable = false; // Only enable display if LCD is the active "console"
|
enable = false; // Only enable display if LCD is the active "console"
|
if (enable) {
|
if (enable) {
|
if (!enabled) {
|
if (!enabled) {
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
SA1110_EIO_LCD_3V3_ON|SA1110_EIO_LCD_CTRL_ON|SA1110_EIO_LCD_5V_ON|SA1110_EIO_LCD_VDD_ON);
|
SA1110_EIO_LCD_3V3_ON|SA1110_EIO_LCD_CTRL_ON|SA1110_EIO_LCD_5V_ON|SA1110_EIO_LCD_VDD_ON);
|
lcd_brightness(_lcd_brightness);
|
lcd_brightness(_lcd_brightness);
|
}
|
}
|
enabled = true;
|
enabled = true;
|
} else {
|
} else {
|
if (enabled) {
|
if (enabled) {
|
lcd_brightness(0);
|
lcd_brightness(0);
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
ipaq_EGPIO(SA1110_EIO_LCD_3V3|SA1110_EIO_LCD_CTRL|SA1110_EIO_LCD_5V|SA1110_EIO_LCD_VDD,
|
SA1110_EIO_LCD_3V3_OFF|SA1110_EIO_LCD_CTRL_OFF|SA1110_EIO_LCD_5V_OFF|SA1110_EIO_LCD_VDD_OFF);
|
SA1110_EIO_LCD_3V3_OFF|SA1110_EIO_LCD_CTRL_OFF|SA1110_EIO_LCD_5V_OFF|SA1110_EIO_LCD_VDD_OFF);
|
}
|
}
|
enabled = false;
|
enabled = false;
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
|
|