Merge pull request #8 from Tectu/master

Merge Tectu Changes
ugfx_release_2.6
Andrew Hannam 2012-11-25 22:44:25 -08:00
commit 6cc2bc280c
33 changed files with 993 additions and 676 deletions

View File

@ -0,0 +1,95 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Make sure you have the following stuff enabled in your halconf.h:
*
* #define GFX_USE_GDISP TRUE
* #define GFX_USE_GWIN TRUE
* #define GDISP_NEED_SCROLL TRUE (optional but recommended)
* #define GDISP_NEED_CLIP TRUE (optional but recommended)
* #define GWIN_NEED_CONSOLE TRUE
*/
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "gdisp.h"
#include "gwin.h"
/* The handles for our three consoles */
GHandle GW1, GW2, GW3;
/* The streams for our three consoles */
BaseSequentialStream *S1, *S2, *S3;
int main(void) {
uint8_t i;
halInit();
chSysInit();
/* initialize and clear the display */
gdispInit();
gdispClear(Black);
/* create the three console windows and set a font for each */
GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, &fontUI2Double);
GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), &fontSmall);
GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), &fontSmall);
/* Set the fore- and background colors for each console */
gwinSetColor(GW1, Green);
gwinSetBgColor(GW1, Black);
gwinSetColor(GW2, White);
gwinSetBgColor(GW2, Blue);
gwinSetColor(GW3, Black);
gwinSetBgColor(GW3, Red);
/* clear all console windows - to set background */
gwinClear(GW1);
gwinClear(GW2);
gwinClear(GW3);
/* receive the stream pointers of each console */
S1 = gwinGetConsoleStream(GW1);
S2 = gwinGetConsoleStream(GW2);
S3 = gwinGetConsoleStream(GW3);
/* Output some data on the first console */
for(i = 0; i < 10; i++) {
chprintf(S1, "Hello ChibiOS/GFX!\r\n");
}
/* Output some data on the second console */
for(i = 0; i < 16; i++) {
chprintf(S2, "Message Nr.: %d\r\n", i+1);
}
/* Output some data on the third console */
for(i = 0; i < 18; i++) {
chprintf(S3, "Message Nr.: %d\r\n", i+1);
}
while(TRUE) {
chThdSleepMilliseconds(500);
}
}

View File

@ -0,0 +1,65 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Make sure you have enabled the GTimer module in your halconf.h:
*
* #define GFX_USE_GTIMER TRUE
*/
#include "ch.h"
#include "hal.h"
#include "gtimer.h"
GTimer GT1, GT2;
void callback1(void* arg) {
(void)arg;
palTogglePad(GPIOD, GPIOD_LED3);
}
void callback2(void* arg) {
(void)arg;
palSetPad(GPIOD, GPIOD_LED4);
}
int main(void) {
halInit();
chSysInit();
/* initialize the timers */
gtimerInit(&GT1);
gtimerInit(&GT2);
/* continious mode - callback1() called without any argument every 250ms */
gtimerStart(&GT1, callback1, NULL, TRUE, 250);
/* single shot mode - callback2() called without any argument once after 1s */
gtimerStart(&GT2, callback2, NULL, FALSE, 1000);
while(TRUE) {
chThdSleepMilliseconds(500);
}
return 0;
}

View File

@ -0,0 +1,72 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* Make sure you have the following stuff enabled in your halconf.h:
*
* #define GFX_USE_GDISP TRUE
* #define GDISP_NEED_SCROLL TRUE
* #define GDISP_NEED_CLIP TRUE (optional but recommended)
*/
#include "ch.h"
#include "hal.h"
#include "gdisp.h"
#include "gwin.h"
/* The handles for our two Windows */
GHandle GW1, GW2;
int main(void) {
halInit();
chSysInit();
/* Initialize and clear the display */
gdispInit();
gdispClear(Lime);
/* Create two windows */
GW1 = gwinCreateWindow(NULL, 20, 10, 200, 150);
GW2 = gwinCreateWindow(NULL, 50, 190, 150, 100);
/* Set fore- and background colors for both windows */
gwinSetColor(GW1, Black);
gwinSetBgColor(GW1, White);
gwinSetColor(GW2, White);
gwinSetBgColor(GW2, Blue);
/* Clear both windows - to set background color */
gwinClear(GW1);
gwinClear(GW2);
/*
* Draw two filled circles at the same coordinate
* of each window to demonstrate the relative coordinates
* of windows
*/
gwinFillCircle(GW1, 20, 20, 15);
gwinFillCircle(GW2, 20, 20, 15);
while(TRUE) {
chThdSleepMilliseconds(500);
}
}

View File

@ -0,0 +1,36 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup GTIMER
* @details The GTIMER module provides high level, simple and hardware
* independend timers. The timers are meant to be used in different
* ChibiOS/GFX modules and are not very accurate.
*
* @details The reason why ChibiOS/GFX has it's own timer abstraction is because
* virtual timers provided by ChibiOS/RT are interrupt context only.
* While great for what they are designed for, they make coding of the input
* drivers much more complex.
* For non-performance critical drivers like these input drivers, it would also
* hog an in-ordinate amount of critical (interrupt locked) system time.
* This contrary to the goals of a real-time operating system. So a user-land
* (thread based) timer mechanism is also required.
*/

View File

@ -125,7 +125,7 @@ bool_t GDISP_LLD(init)(void) {
delayms(20);
// Get the bus for the following initialisation commands
get_bus();
acquire_bus();
#if defined(GDISP_USE_GE8)
write_cmd3(DISCTL, 0x00, 0x20, 0x00); // Display control
@ -245,7 +245,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
#endif
get_bus();
acquire_bus();
setviewport(x, y, 1, 1);
write_cmd3(RAMWR, 0, (color>>8) & 0x0F, color & 0xFF);
release_bus();
@ -277,7 +277,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
tuples = (cx*cy+1)/2; // With an odd sized area we over-print by one pixel.
// This extra pixel is ignored by the controller.
get_bus();
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
for(i=0; i < tuples; i++)
@ -319,7 +319,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
endx = srcx + cx;
endy = y + cy;
get_bus();
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
@ -537,7 +537,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
return;
case GDISP_CONTROL_CONTRAST:
if ((unsigned)value > 100) value = (void *)100;
get_bus();
acquire_bus();
#if defined(GDISP_USE_GE8)
write_cmd2(VOLCTR, (unsigned)value, 0x03);
#elif defined(GDISP_USE_GE12)

View File

@ -76,8 +76,8 @@ static __inline void set_backlight(uint8_t percent) {
*
* @notapi
*/
static __inline void get_bus(void) {
#error "gdispNokia6610: You must supply a definition for get_bus for your board"
static __inline void acquire_bus(void) {
#error "gdispNokia6610: You must supply a definition for acquire_bus for your board"
}
/**

View File

@ -137,8 +137,8 @@ static __inline void set_backlight(uint8_t percent) {
*
* @notapi
*/
static __inline void get_bus(void) {
// Nothing to do for this board as the LCD is the only device on the SPI port
static __inline void acquire_bus(void) {
/* Nothing to do for this board as the LCD is the only device on the SPI port */
}
/**

View File

@ -35,147 +35,195 @@
/* Include the emulation code for things we don't support */
#include "gdisp_emulation.c"
#include "s6d1121_lld.c.h"
/*===========================================================================*/
/* Driver interrupt handlers. */
/* Driver local definitions. */
/*===========================================================================*/
#if defined(GDISP_SCREEN_HEIGHT)
#undef GISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#undef GDISP_SCREEN_WIDTH
#endif
#define GDISP_SCREEN_HEIGHT 320
#define GDISP_SCREEN_WIDTH 240
#define GDISP_INITIAL_CONTRAST 50
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver exported functions. */
/* Driver local definitions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
#if defined(BOARD_OLIMEX_STM32_E407)
#include "gdisp_lld_board_olimex_e407.h"
#else
#include "gdisp_lld_board.h"
#endif
/* Some common routines and macros */
#define write_reg(reg, data) { write_index(reg); write_data(data); }
#define stream_start() write_index(0x0022);
#define stream_stop()
#define delay(us) chThdSleepMicroseconds(us)
#define delayms(ms) chThdSleepMilliseconds(ms)
static __inline void set_cursor(coord_t x, coord_t y) {
/* R20h - 8 bit
* R21h - 9 bit
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
write_reg(0x0020, x & 0x00FF);
write_reg(0x0021, y & 0x01FF);
break;
case GDISP_ROTATE_90:
/* Note X has already been mirrored, so we do it directly */
write_reg(0x0020, y & 0x00FF);
write_reg(0x0021, x & 0x01FF);
break;
case GDISP_ROTATE_180:
write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - x) & 0x00FF);
write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x01FF);
break;
case GDISP_ROTATE_270:
write_reg(0x0020, (GDISP_SCREEN_WIDTH - 1 - y) & 0x00FF);
write_reg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - x) & 0x01FF);
break;
}
}
static __inline void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
/* HSA / HEA are 8 bit
* VSA / VEA are 9 bit
* use masks 0x00FF and 0x01FF to enforce this
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
write_reg(0x46, (((x + cx - 1) << 8) & 0xFF00 ) |
(x & 0x00FF));
write_reg(0x48, y & 0x01FF);
write_reg(0x47, (y + cy - 1) & 0x01FF);
break;
case GDISP_ROTATE_90:
write_reg(0x46, (((y + cy - 1) << 8) & 0xFF00) |
(y & 0x00FF));
write_reg(0x48, x & 0x01FF);
write_reg(0x47, (x + cx - 1) & 0x01FF);
break;
case GDISP_ROTATE_180:
write_reg(0x46, (((GDISP_SCREEN_WIDTH - x - 1) & 0x00FF) << 8) |
((GDISP_SCREEN_WIDTH - (x + cx)) & 0x00FF));
write_reg(0x48, (GDISP_SCREEN_HEIGHT - (y + cy)) & 0x01FF);
write_reg(0x47, (GDISP_SCREEN_HEIGHT- y - 1) & 0x01FF);
break;
case GDISP_ROTATE_270:
write_reg(0x46, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) |
((GDISP_SCREEN_WIDTH - (y + cy)) & 0x00FF));
write_reg(0x48, (GDISP_SCREEN_HEIGHT - (x + cx)) & 0x01FF);
write_reg(0x47, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
break;
}
set_cursor(x, y);
}
static __inline void reset_viewport(void) {
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
set_viewport(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270:
set_viewport(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH);
break;
}
}
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t GDISP_LLD(init)(void) {
palSetPadMode(GDISP_RST_GPIO, GDISP_RST_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
// A Good idea to reset the module before using
GDISP_RST_LOW;
s6d1121_delay(2);
GDISP_RST_HIGH; // Hardware Reset
s6d1121_delay(2);
/* initialize the hardware */
init_board();
#ifdef GDISP_USE_GPIO
// IO Default Configurations
palSetPadMode(GDISP_CS_GPIO, GDISP_CS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palSetPadMode(GDISP_WR_GPIO, GDISP_WR_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palSetPadMode(GDISP_RD_GPIO, GDISP_RD_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palSetPadMode(GDISP_RS_GPIO, GDISP_RS_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palSetPadMode(GDISP_BL_GPIO, GDISP_BL_PIN, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
/* Hardware reset */
setpin_reset(TRUE);
delayms(20);
setpin_reset(TRUE);
delayms(20);
palSetGroupMode(GDISP_D0_GPIO, 0x0000000F, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
palSetGroupMode(GDISP_D4_GPIO, 0x0000FFF0, 0, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
/* Get the bus for the following initialisation commands */
acquire_bus();
GDISP_CS_HIGH;
GDISP_RD_HIGH;
GDISP_WR_HIGH;
GDISP_BL_LOW;
write_reg(0x11,0x2004);
write_reg(0x13,0xCC00);
write_reg(0x15,0x2600);
write_reg(0x14,0x252A);
write_reg(0x12,0x0033);
write_reg(0x13,0xCC04);
#elif defined(GDISP_USE_FSMC)
#if defined(STM32F1XX)
/* FSMC setup. TODO: this only works for STM32F1 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
delayms(1);
/* TODO: pin setup */
#elif defined(STM32F4XX)
/* STM32F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
write_reg(0x13,0xCC06);
/* set pins to FSMC mode */
IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
(1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
delayms(1);
IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
(1 << 13) | (1 << 14) | (1 << 15), 0};
write_reg(0x13,0xCC4F);
palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
#else
#error "FSMC not implemented for this device"
#endif
delayms(1);
int FSMC_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
write_reg(0x13,0x674F);
write_reg(0x11,0x2003);
/* Bank1 NOR/SRAM control register configuration */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
#endif
lld_lcdWriteReg(0x11,0x2004);
lld_lcdWriteReg(0x13,0xCC00);
lld_lcdWriteReg(0x15,0x2600);
lld_lcdWriteReg(0x14,0x252A);
lld_lcdWriteReg(0x12,0x0033);
lld_lcdWriteReg(0x13,0xCC04);
s6d1121_delay(1);
lld_lcdWriteReg(0x13,0xCC06);
s6d1121_delay(1);
lld_lcdWriteReg(0x13,0xCC4F);
s6d1121_delay(1);
lld_lcdWriteReg(0x13,0x674F);
lld_lcdWriteReg(0x11,0x2003);
s6d1121_delay(1);
delayms(1);
// Gamma Setting
lld_lcdWriteReg(0x30,0x2609);
lld_lcdWriteReg(0x31,0x242C);
lld_lcdWriteReg(0x32,0x1F23);
lld_lcdWriteReg(0x33,0x2425);
lld_lcdWriteReg(0x34,0x2226);
lld_lcdWriteReg(0x35,0x2523);
lld_lcdWriteReg(0x36,0x1C1A);
lld_lcdWriteReg(0x37,0x131D);
lld_lcdWriteReg(0x38,0x0B11);
lld_lcdWriteReg(0x39,0x1210);
lld_lcdWriteReg(0x3A,0x1315);
lld_lcdWriteReg(0x3B,0x3619);
lld_lcdWriteReg(0x3C,0x0D00);
lld_lcdWriteReg(0x3D,0x000D);
write_reg(0x30,0x2609);
write_reg(0x31,0x242C);
write_reg(0x32,0x1F23);
write_reg(0x33,0x2425);
write_reg(0x34,0x2226);
write_reg(0x35,0x2523);
write_reg(0x36,0x1C1A);
write_reg(0x37,0x131D);
write_reg(0x38,0x0B11);
write_reg(0x39,0x1210);
write_reg(0x3A,0x1315);
write_reg(0x3B,0x3619);
write_reg(0x3C,0x0D00);
write_reg(0x3D,0x000D);
lld_lcdWriteReg(0x16,0x0007);
lld_lcdWriteReg(0x02,0x0013);
lld_lcdWriteReg(0x03,0x0003);
lld_lcdWriteReg(0x01,0x0127);
write_reg(0x16,0x0007);
write_reg(0x02,0x0013);
write_reg(0x03,0x0003);
write_reg(0x01,0x0127);
s6d1121_delay(1);
delayms(1);
lld_lcdWriteReg(0x08,0x0303);
lld_lcdWriteReg(0x0A,0x000B);
lld_lcdWriteReg(0x0B,0x0003);
lld_lcdWriteReg(0x0C,0x0000);
lld_lcdWriteReg(0x41,0x0000);
lld_lcdWriteReg(0x50,0x0000);
lld_lcdWriteReg(0x60,0x0005);
lld_lcdWriteReg(0x70,0x000B);
lld_lcdWriteReg(0x71,0x0000);
lld_lcdWriteReg(0x78,0x0000);
lld_lcdWriteReg(0x7A,0x0000);
lld_lcdWriteReg(0x79,0x0007);
lld_lcdWriteReg(0x07,0x0051);
write_reg(0x08,0x0303);
write_reg(0x0A,0x000B);
write_reg(0x0B,0x0003);
write_reg(0x0C,0x0000);
write_reg(0x41,0x0000);
write_reg(0x50,0x0000);
write_reg(0x60,0x0005);
write_reg(0x70,0x000B);
write_reg(0x71,0x0000);
write_reg(0x78,0x0000);
write_reg(0x7A,0x0000);
write_reg(0x79,0x0007);
write_reg(0x07,0x0051);
s6d1121_delay(1);
delayms(1);
lld_lcdWriteReg(0x07,0x0053);
lld_lcdWriteReg(0x79,0x0000);
write_reg(0x07,0x0053);
write_reg(0x79,0x0000);
lld_lcdResetViewPort();
reset_viewport();
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Now initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
@ -206,8 +254,11 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
#endif
lld_lcdSetCursor(x, y);
lld_lcdWriteReg(0x0022, color);
acquire_bus();
set_cursor(x, y);
write_reg(0x0022, color);
release_bus();
}
/* ---- Optional Routines ---- */
@ -224,13 +275,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
void GDISP_LLD(clear)(color_t color) {
unsigned i;
lld_lcdSetCursor(0, 0);
lld_lcdWriteStreamStart();
acquire_bus();
set_cursor(0, 0);
stream_start();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
lld_lcdWriteData(color);
write_data(color);
lld_lcdWriteStreamStop();
stream_stop();
release_bus();
}
#endif
@ -257,12 +310,14 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#endif
area = cx*cy;
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
for(i = 0; i < area; i++)
lld_lcdWriteData(color);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
write_data(color);
stream_stop();
reset_viewport();
release_bus();
}
#endif
@ -292,8 +347,9 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
endx = srcx + cx;
endy = y + cy;
@ -301,9 +357,10 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
lld_lcdWriteData(*buffer++);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
write_data(*buffer++);
stream_stop();
reset_viewport();
release_bus();
}
#endif
@ -328,13 +385,15 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
lld_lcdSetCursor(x, y);
lld_lcdWriteStreamStart();
aquire_bus();
set_cursor(x, y);
stream_start();
color = lld_lcdReadData();
color = lld_lcdReadData();
lld_lcdWriteStreamStop();
stream_stop();
release_bus();
return color;
}
@ -371,6 +430,8 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
#endif
abslines = lines < 0 ? -lines : lines;
acquire_bus();
if (abslines >= cy) {
abslines = cy;
gap = 0;
@ -386,25 +447,26 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
}
/* read row0 into the buffer and then write at row1*/
lld_lcdSetViewPort(x, row0, cx, 1);
set_viewport(x, row0, cx, 1);
lld_lcdReadStreamStart();
lld_lcdReadStream(buf, cx);
lld_lcdReadStreamStop();
lld_lcdSetViewPort(x, row1, cx, 1);
lld_lcdWriteStreamStart();
lld_lcdWriteStream(buf, cx);
lld_lcdWriteStreamStop();
set_viewport(x, row1, cx, 1);
stream_start();
write_data(buf, cx);
stream_stop();
}
}
/* fill the remaining gap */
lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines);
lld_lcdWriteStreamStart();
set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines);
stream_start();
gap = cx*abslines;
for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
for(i = 0; i < gap; i++) write_data(bgcolor);
stream_stop();
reset_viewport();
release_bus();
}
#endif
@ -457,26 +519,26 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0001,0x0127);
lld_lcdWriteReg(0x03, 0b0011);
write_reg(0x0001,0x0127);
write_reg(0x03, 0b0011);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0001,0x0027);
lld_lcdWriteReg(0x0003, 0b1011);
write_reg(0x0001,0x0027);
write_reg(0x0003, 0b1011);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x0001,0x0127);
lld_lcdWriteReg(0x0003, 0b0000);
write_reg(0x0001,0x0127);
write_reg(0x0003, 0b0000);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x0001,0x0027);
lld_lcdWriteReg(0x0003, 0b1000);
write_reg(0x0001,0x0027);
write_reg(0x0003, 0b1000);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;

View File

@ -0,0 +1,125 @@
/*
ChibiOS/RT - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file drivers/gdisp/SSD1289/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
/**
* @brief Initialise the board for the display.
*
* @notapi
*/
static __inline void init_board(void) {
/* Code here */
#error "SSD1289: You must supply a definition for init_board for your board"
}
/**
* @brief Set or clear the lcd reset pin.
*
* @param[in] state TRUE = lcd in reset, FALSE = normal operation
*
* @notapi
*/
static __inline void setpin_reset(bool_t state) {
/* Code here */
#error "SSD1289: You must supply a definition for setpin_reset for your board"
}
/**
* @brief Set the lcd back-light level.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
/* Code here */
#error "SSD1289: You must supply a definition for set_backlight for your board"
}
/**
* @brief Take exclusive control of the bus
*
* @notapi
*/
static __inline void acquire_bus(void) {
#error "SSD1289: You must supply a definition for acquire_bus for your board"
}
/**
* @brief Release exclusive control of the bus
*
* @notapi
*/
static __inline void release_bus(void) {
#error "SSD1289: You must supply a definition for release_bus for your board"
}
/**
* @brief Send data to the index register.
*
* @param[in] index The index register to set
*
* @notapi
*/
static __inline void write_index(uint16_t index) {
/* Code here */
#error "SSD1289: You must supply a definition for write_index for your board"
}
/**
* @brief Send data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
/* Code here */
#error "SSD1289: You must supply a definition for write_data for your board"
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
/**
* @brief Read data from the lcd.
*
* @return The data from the lcd
* @note The chip select may need to be asserted/de-asserted
* around the actual spi read
*
* @notapi
*/
static __inline uint16_t read_data(void) {
/* Code here */
#error "SSD1289: You must supply a definition for read_data for your board"
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,94 @@
/*
ChibiOS/RT - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h
* @brief GDISP Graphic Driver subsystem board interface for the SSD1289 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
static __inline void init_board(void) {
int FSMC_Bank = 0;
/* STM32F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
/* set pins to FSMC mode */
IOBus busD = {GPIOD, (1 << 0) | (1 << 1) | (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8) |
(1 << 9) | (1 << 10) | (1 << 11) | (1 << 14) | (1 << 15), 0};
IOBus busE = {GPIOE, (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10) | (1 << 11) | (1 << 12) |
(1 << 13) | (1 << 14) | (1 << 15), 0};
palSetBusMode(&busD, PAL_MODE_ALTERNATE(12));
palSetBusMode(&busE, PAL_MODE_ALTERNATE(12));
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
/* Bank1 NOR/SRAM control register configuration */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
}
static __inline void setpin_reset(bool_t state) {
(void)state;
/* Nothing to do here */
}
static __inline void set_backlight(uint8_t percent) {
(void)percent;
/* Nothing to do here */
}
static __inline void acquire_bus(void) {
/* Nothing to do here */
}
static __inline void release_bus(void) {
/* Nothing to do here */
}
static __inline void write_index(uint16_t index) {
GDISP_REG = index;
}
static __inline void write_data(uint16_t data) {
GDISP_RAM = data;
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
static __inline uint16_t read_data(void) {
return GDISP_RAM;
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -20,7 +20,7 @@
/**
* @file drivers/gdisp/S6D1121/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the S6d1121 display.
* @brief GDISP Graphic Driver subsystem low level driver header for the S6D1121 display.
*
* @addtogroup GDISP
* @{

View File

@ -3,13 +3,7 @@ To use this driver:
1. Add in your halconf.h:
a) #define GFX_USE_GDISP TRUE
b) Any optional high level driver defines (see gdisp.h) eg: GDISP_NEED_MULTITHREAD
c) One (only) of:
#define GDISP_USE_GPIO
#define GDISP_USE_SPI
#define GDISP_USE_FSMC
d) All of the following (with appropriate values):
#define GDISP_SCREEN_WIDTH 320
#define GDISP_SCREEN_HEIGHT 240
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld.mk

View File

@ -1,254 +0,0 @@
/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef S6D1121_H
#define S6D1121_H
// I/O assignments
#define GDISP_BL_GPIO GPIOB
#define GDISP_BL_PIN 8
#define GDISP_CS_GPIO GPIOD
#define GDISP_CS_PIN 7
#define GDISP_RS_GPIO GPIOD
#define GDISP_RS_PIN 11
#define GDISP_RST_GPIO GPIOD
#define GDISP_RST_PIN 10
#define GDISP_RD_GPIO GPIOD
#define GDISP_RD_PIN 9
#define GDISP_WR_GPIO GPIOD
#define GDISP_WR_PIN 8
#define GDISP_D0_GPIO GPIOD
#define GDISP_D4_GPIO GPIOE
/* all interfaces use RST via GPIO */
/* TODO: option to disable RST; assumes RST is tied high */
#define GDISP_RST_LOW palClearPad(GDISP_RST_GPIO, GDISP_RST_PIN)
#define GDISP_RST_HIGH palSetPad(GDISP_RST_GPIO, GDISP_RST_PIN)
#define s6d1121_delay(n) halPolledDelay(MS2RTT(n));
#if defined(GDISP_USE_GPIO)
#define GDISP_CS_LOW palClearPad(GDISP_CS_GPIO, GDISP_CS_PIN)
#define GDISP_CS_HIGH palSetPad(GDISP_CS_GPIO, GDISP_CS_PIN)
#define GDISP_RS_LOW palClearPad(GDISP_RS_GPIO, GDISP_RS_PIN)
#define GDISP_RS_HIGH palSetPad(GDISP_RS_GPIO, GDISP_RS_PIN)
#define GDISP_RD_LOW palClearPad(GDISP_RD_GPIO, GDISP_RD_PIN)
#define GDISP_RD_HIGH palSetPad(GDISP_RD_GPIO, GDISP_RD_PIN)
#define GDISP_WR_LOW palClearPad(GDISP_WR_GPIO, GDISP_WR_PIN)
#define GDISP_WR_HIGH palSetPad(GDISP_WR_GPIO, GDISP_WR_PIN)
#define GDISP_BL_LOW palClearPad(GDISP_BL_GPIO, GDISP_BL_PIN)
#define GDISP_BL_HIGH palSetPad(GDISP_BL_GPIO, GDISP_BL_PIN)
static inline void lld_lcddelay(void) { asm volatile ("nop"); asm volatile ("nop"); }
static inline void lld_lcdwrite(uint16_t db) {
GDISP_D4_GPIO->BSRR.W=((~db&0xFFF0)<<16)|(db&0xFFF0);
GDISP_D0_GPIO->BSRR.W=((~db&0x000F)<<16)|(db&0x000F);
GDISP_WR_LOW;
lld_lcddelay();
GDISP_WR_HIGH;
}
static __inline uint16_t lld_lcdReadData(void) {
uint16_t value=0;
GDISP_RS_HIGH; GDISP_WR_HIGH; GDISP_RD_LOW;
#ifndef STM32F4XX
// change pin mode to digital input
GDISP_DATA_PORT->CRH = 0x47444444;
GDISP_DATA_PORT->CRL = 0x47444444;
#endif
#ifndef STM32F4XX
// change pin mode back to digital output
GDISP_DATA_PORT->CRH = 0x33333333;
GDISP_DATA_PORT->CRL = 0x33333333;
#endif
GDISP_RD_HIGH;
return value;
}
static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
uint16_t lcdRAM;
GDISP_CS_LOW; GDISP_RS_LOW;
lld_lcdwrite(lcdReg);
GDISP_RS_HIGH;
lcdRAM = lld_lcdReadData();
GDISP_CS_HIGH;
return lcdRAM;
}
static void lld_lcdWriteIndex(uint16_t lcdReg) {
GDISP_RS_LOW;
lld_lcdwrite(lcdReg);
GDISP_RS_HIGH;
}
static void lld_lcdWriteData(uint16_t lcdData) {
lld_lcdwrite(lcdData);
}
static void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) {
GDISP_CS_LOW;
lld_lcdWriteIndex(lcdReg);
lld_lcdWriteData(lcdRegValue);
GDISP_CS_HIGH;
}
static __inline void lld_lcdWriteStreamStart(void) {
GDISP_CS_LOW;
lld_lcdWriteIndex(0x0022);
}
static __inline void lld_lcdWriteStreamStop(void) {
GDISP_CS_HIGH;
}
static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) {
uint16_t i;
for(i = 0; i < size; i++) { lld_lcdwrite(buffer[i]); }
}
static __inline void lld_lcdReadStreamStart(void) { /* TODO */ }
static __inline void lld_lcdReadStreamStop(void) { /* TODO */ }
static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) {
(void)buffer;
(void)size;
/* TODO */
}
#elif defined(GDISP_USE_FSMC)
#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
static __inline void lld_lcdWriteIndex(uint16_t index) { GDISP_REG = index; }
static __inline void lld_lcdWriteData(uint16_t data) { GDISP_RAM = data; }
static __inline void lld_lcdWriteReg(uint16_t lcdReg,uint16_t lcdRegValue) {
GDISP_REG = lcdReg;
GDISP_RAM = lcdRegValue;
}
static __inline uint16_t lld_lcdReadData(void) { return (GDISP_RAM); }
static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
GDISP_REG = lcdReg;
return GDISP_RAM;
}
static __inline void lld_lcdWriteStreamStart(void) { GDISP_REG = 0x0022; }
static __inline void lld_lcdWriteStreamStop(void) {}
static __inline void lld_lcdWriteStream(uint16_t *buffer, uint16_t size) {
uint16_t i;
for(i = 0; i < size; i++) GDISP_RAM = buffer[i];
}
static __inline void lld_lcdReadStreamStart(void) { GDISP_REG = 0x0022; }
static __inline void lld_lcdReadStreamStop(void) {}
static __inline void lld_lcdReadStream(uint16_t *buffer, size_t size) {
uint16_t i;
volatile uint16_t dummy;
/* throw away first value read */
dummy = GDISP_RAM;
for(i = 0; i < size; i++) buffer[i] = GDISP_RAM;
}
#elif defined(GDISP_USE_SPI)
#error "gdispS6d1121: GDISP_USE_SPI not implemented yet"
#endif
static void lld_lcdSetCursor(coord_t x, coord_t y) {
/* R20h - 8 bit
* R21h - 9 bit
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0020, x & 0x00FF);
lld_lcdWriteReg(0x0021, y & 0x01FF);
break;
case GDISP_ROTATE_90:
/* Note X has already been mirrored, so we do it directly */
lld_lcdWriteReg(0x0020, y & 0x00FF);
lld_lcdWriteReg(0x0021, x & 0x01FF);
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x0020, (GDISP_SCREEN_WIDTH - 1 - x) & 0x00FF);
lld_lcdWriteReg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - y) & 0x01FF);
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x0020, (GDISP_SCREEN_WIDTH - 1 - y) & 0x00FF);
lld_lcdWriteReg(0x0021, (GDISP_SCREEN_HEIGHT - 1 - x) & 0x01FF);
break;
}
}
static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) {
/* HSA / HEA are 8 bit
* VSA / VEA are 9 bit
* use masks 0x00FF and 0x01FF to enforce this
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x46, (((x + cx - 1) << 8) & 0xFF00 ) |
(x & 0x00FF));
lld_lcdWriteReg(0x48, y & 0x01FF);
lld_lcdWriteReg(0x47, (y + cy - 1) & 0x01FF);
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x46, (((y + cy - 1) << 8) & 0xFF00) |
(y & 0x00FF));
lld_lcdWriteReg(0x48, x & 0x01FF);
lld_lcdWriteReg(0x47, (x + cx - 1) & 0x01FF);
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x46, (((GDISP_SCREEN_WIDTH - x - 1) & 0x00FF) << 8) |
((GDISP_SCREEN_WIDTH - (x + cx)) & 0x00FF));
lld_lcdWriteReg(0x48, (GDISP_SCREEN_HEIGHT - (y + cy)) & 0x01FF);
lld_lcdWriteReg(0x47, (GDISP_SCREEN_HEIGHT- y - 1) & 0x01FF);
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x46, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) |
((GDISP_SCREEN_WIDTH - (y + cy)) & 0x00FF));
lld_lcdWriteReg(0x48, (GDISP_SCREEN_HEIGHT - (x + cx)) & 0x01FF);
lld_lcdWriteReg(0x47, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
break;
}
lld_lcdSetCursor(x, y);
}
static void lld_lcdResetViewPort(void) {
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
case GDISP_ROTATE_180:
lld_lcdSetViewPort(0, 0, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
break;
case GDISP_ROTATE_90:
case GDISP_ROTATE_270:
lld_lcdSetViewPort(0, 0, GDISP_SCREEN_HEIGHT, GDISP_SCREEN_WIDTH);
break;
}
}
#endif /* S6D1121_H */

View File

@ -40,10 +40,10 @@
/*===========================================================================*/
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 240
#define GDISP_SCREEN_HEIGHT 320
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 320
#define GDISP_SCREEN_WIDTH 240
#endif
#define GDISP_INITIAL_CONTRAST 50
@ -62,7 +62,7 @@
// Some common routines and macros
#define write_reg(reg, data) { write_index(reg); write_data(data); }
#define stream_start() write_reg(0x0022);
#define stream_start() write_index(0x0022);
#define stream_stop()
#define delay(us) chThdSleepMicroseconds(us)
#define delayms(ms) chThdSleepMilliseconds(ms)
@ -161,7 +161,7 @@ bool_t GDISP_LLD(init)(void) {
delayms(20);
// Get the bus for the following initialisation commands
get_bus();
acquire_bus();
write_reg(0x0000,0x0001); delay(5);
write_reg(0x0003,0xA8A4); delay(5);
@ -241,7 +241,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (x < GDISP.clipx0 || y < GDISP.clipy0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
#endif
get_bus();
acquire_bus();
set_cursor(x, y);
write_reg(0x0022, color);
release_bus();
@ -276,7 +276,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
void GDISP_LLD(clear)(color_t color) {
unsigned i;
get_bus();
acquire_bus();
set_cursor(0, 0);
stream_start();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
@ -310,7 +310,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
area = cx*cy;
get_bus();
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
for(i = 0; i < area; i++)
@ -346,7 +346,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
get_bus();
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
@ -368,7 +368,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
* @note Optional.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The start of the text
* @param[in] x, y The pixel to be read
*
* @notapi
*/
@ -379,13 +379,14 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
get_bus();
acquire_bus();
set_cursor(x, y);
stream_start();
color = read_data(); // dummy read
color = read_data();
stream_stop();
release_bus();
return color;
}
#endif
@ -419,7 +420,7 @@ void GDISP_LLD(drawpixel)(coord_t x, coord_t y, color_t color) {
abslines = lines < 0 ? -lines : lines;
get_bus();
acquire_bus();
if (abslines >= cy) {
abslines = cy;
gap = 0;

View File

@ -68,8 +68,8 @@ static __inline void set_backlight(uint8_t percent) {
*
* @notapi
*/
static __inline void get_bus(void) {
#error "SSD1289: You must supply a definition for get_bus for your board"
static __inline void acquire_bus(void) {
#error "SSD1289: You must supply a definition for acquire_bus for your board"
}
/**

View File

@ -116,7 +116,7 @@ static __inline void set_backlight(uint8_t percent) {
*
* @notapi
*/
static __inline void get_bus(void) {
static __inline void acquire_bus(void) {
/* Nothing to do here */
}

View File

@ -29,14 +29,14 @@
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
#define SET_CS palSetPad(GDISP_CMD_PORT, GDISP_CS);
#define CLR_CS palClearPad(GDISP_CMD_PORT, GDISP_CS);
#define SET_RS palSetPad(GDISP_CMD_PORT, GDISP_RS);
#define CLR_RS palClearPad(GDISP_CMD_PORT, GDISP_RS);
#define SET_WR palSetPad(GDISP_CMD_PORT, GDISP_WR);
#define CLR_WR palClearPad(GDISP_CMD_PORT, GDISP_WR);
#define SET_RD palSetPad(GDISP_CMD_PORT, GDISP_RD);
#define CLR_RD palClearPad(GDISP_CMD_PORT, GDISP_RD);
#define SET_CS palSetPad(GPIOD, 12);
#define CLR_CS palClearPad(GPIOD, 12);
#define SET_RS palSetPad(GPIOD, 13);
#define CLR_RS palClearPad(GPIOD, 13);
#define SET_WR palSetPad(GPIOD, 14);
#define CLR_WR palClearPad(GPIOD, 14);
#define SET_RD palSetPad(GPIOD, 15);
#define CLR_RD palClearPad(GPIOD, 15);
/**
* @brief Initialise the board for the display.
@ -45,10 +45,17 @@
* @notapi
*/
static __inline void init_board(void) {
// This should set the GPIO port up for the correct hardware config here
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 12, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 13, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 14, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, 15, PAL_MODE_OUTPUT_PUSHPULL);
// Configure the pins to a well know state
SET_RS; SET_RD; SET_RW; CLR_CS;
SET_RS;
SET_RD;
SET_WR;
CLR_CS;
}
@ -61,7 +68,7 @@ static __inline void init_board(void) {
*/
static __inline void setpin_reset(bool_t state) {
(void) state;
/* Nothing to do here */
/* Nothing to do here - reset pin tied to Vcc */
}
/**
@ -73,7 +80,7 @@ static __inline void setpin_reset(bool_t state) {
*/
static __inline void set_backlight(uint8_t percent) {
(void) percent;
/* Nothing to do here */
/* Nothing to do here - Backlight always on */
}
/**
@ -81,8 +88,8 @@ static __inline void set_backlight(uint8_t percent) {
*
* @notapi
*/
static __inline void get_bus(void) {
/* Nothing to do here */
static __inline void acquire_bus(void) {
/* Nothing to do here since LCD is the only device on that bus */
}
/**
@ -91,7 +98,7 @@ static __inline void get_bus(void) {
* @notapi
*/
static __inline void release_bus(void) {
/* Nothing to do here */
/* Nothing to do here since LCD is the only device on that bus */
}
/**
@ -102,7 +109,7 @@ static __inline void release_bus(void) {
* @notapi
*/
static __inline void write_index(uint16_t index) {
palWritePort(GDISP_DATA_PORT, index);
palWritePort(GPIOE, index);
CLR_RS; CLR_WR; SET_WR; SET_RS;
}
@ -114,7 +121,7 @@ static __inline void write_index(uint16_t index) {
* @notapi
*/
static __inline void write_data(uint16_t data) {
palWritePort(GDISP_DATA_PORT, data);
palWritePort(GPIOE, data);
CLR_WR; SET_WR;
}
@ -132,16 +139,16 @@ static __inline uint16_t read_data(void) {
uint16_t value;
// change pin mode to digital input
GDISP_DATA_PORT->CRH = 0x44444444;
GDISP_DATA_PORT->CRL = 0x44444444;
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
CLR_RD;
value = palReadPort(GDISP_DATA_PORT);
value = palReadPort(GPIOE);
value = palReadPort(GPIOE);
SET_RD;
// change pin mode back to digital output
GDISP_DATA_PORT->CRH = 0x33333333;
GDISP_DATA_PORT->CRL = 0x33333333;
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
return value;
}
#endif

View File

@ -32,16 +32,38 @@
#if GFX_USE_TOUCHSCREEN /*|| defined(__DOXYGEN__)*/
#define ADC_NUM_CHANNELS 2
#define ADC_BUF_DEPTH 1
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
/* Local copy of the current touchpad driver */
static const TouchscreenDriver *tsDriver;
static const TouchscreenDriver *ts;
#endif
static const ADCConversionGroup adc_y_config = {
FALSE,
ADC_NUM_CHANNELS,
NULL,
NULL,
0, 0,
0, 0,
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
0,
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN12) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN13)
};
static const ADCConversionGroup adc_x_config = {
FALSE,
ADC_NUM_CHANNELS,
NULL,
NULL,
0, 0,
0, 0,
ADC_SQR1_NUM_CH(ADC_NUM_CHANNELS),
0,
ADC_SQR3_SQ2_N(ADC_CHANNEL_IN10) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN11)
};
/**
* @brief Low level Touchscreen driver initialization.
@ -50,31 +72,10 @@
*
* @notapi
*/
void ts_lld_init(const TouchscreenDriver *ts) {
tsDriver = ts;
void ts_lld_init(const TouchscreenDriver *ts_init) {
ts = ts_init;
/* set pins to analog input */
palSetPadMode(ts->ts_yd_port, ts->ts_yd_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->ts_yu_port, ts->ts_yu_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->ts_xl_port, ts->ts_xl_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->ts_xr_port, ts->ts_xr_pin, PAL_MODE_INPUT_ANALOG);
}
/**
* @brief Reads a conversion from the touchscreen
*
* @param[in] cmd The command bits to send to the touchscreen
*
* @return The read value 12-bit right-justified
*
* @note This function only reads data, it is assumed that the pins are
* configured properly and the bus has been acquired beforehand
*
* @notapi
*/
uint16_t ts_lld_read_value(uint8_t cmd) {
return 0;
adcStart(ts->adc_driver, NULL);
}
/**
@ -85,6 +86,7 @@ uint16_t ts_lld_read_value(uint8_t cmd) {
* @notapi
*/
static void ts_lld_filter(void) {
return 0;
}
@ -96,7 +98,27 @@ static void ts_lld_filter(void) {
* @notapi
*/
uint16_t ts_lld_read_x(void) {
return 0;
uint16_t val1, val2;
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(ts->xl_port, ts->xl_pin);
palClearPad(ts->xr_port, ts->xr_pin);
chThdSleepMilliseconds(1);
adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);
val1 = ((samples[0] + samples[1])/2);
palClearPad(ts->xl_port, ts->xl_pin);
palSetPad(ts->xr_port, ts->xr_pin);
chThdSleepMilliseconds(1);
adcConvert(ts->adc_driver, &adc_x_config, samples, ADC_BUF_DEPTH);
val2 = ((samples[0] + samples[1])/2);
return ((val1+((1<<12)-val2))/4);
}
/**
@ -105,7 +127,27 @@ uint16_t ts_lld_read_x(void) {
* @notapi
*/
uint16_t ts_lld_read_y(void) {
return 0;
uint16_t val1, val2;
adcsample_t samples[ADC_NUM_CHANNELS * ADC_BUF_DEPTH];
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_INPUT_ANALOG);
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(ts->yu_port, ts->yu_pin);
palClearPad(ts->yd_port, ts->yd_pin);
chThdSleepMilliseconds(1);
adcConvert(ts->adc_driver, &adc_y_config, samples, ADC_BUF_DEPTH);
val1 = ((samples[0] + samples[1])/2);
palClearPad(ts->yu_port, ts->yu_pin);
palSetPad(ts->yd_port, ts->yd_pin);
chThdSleepMilliseconds(1);
adcConvert(ts->adc_driver, &adc_y_config, samples, ADC_BUF_DEPTH);
val2 = ((samples[0] + samples[1])/2);
return ((val1+((1<<12)-val2))/4);
}
/*
@ -116,9 +158,14 @@ uint16_t ts_lld_read_y(void) {
* @notapi
*/
uint8_t ts_lld_pressed(void) {
return 0;
}
palSetPadMode(ts->yd_port, ts->yd_pin, PAL_MODE_INPUT_PULLDOWN);
palSetPadMode(ts->yu_port, ts->yu_pin, PAL_MODE_INPUT);
palSetPadMode(ts->xl_port, ts->xl_pin, PAL_MODE_INPUT);
palSetPadMode(ts->xr_port, ts->xr_pin, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(ts->xr_port, ts->xr_pin);
return palReadPad(ts->yd_port, ts->yd_pin);
}
#endif /* GFX_USE_TOUCHSCREEN */
/** @} */

View File

@ -38,15 +38,20 @@
#define TOUCHSCREEN_HAS_PRESSED TRUE
#define TOUCHSCREEN_HAS_PRESSURE FALSE
/**
* @brief The touchscreen driver struct
* @details Pointer to this will be passed to tsInit()
*/
struct TouchscreenDriver {
ioportid_t ts_yd_port;
ioportmask_t ts_yd_pin;
ioportid_t ts_yu_port;
ioportmask_t ts_yu_pin;
ioportid_t ts_xl_port;
ioportmask_t ts_xl_pin;
ioportid_t ts_xr_port;
ioportmask_t ts_xr_pin;
ADCDriver *adc_driver;
ioportid_t yd_port;
ioportmask_t yd_pin;
ioportid_t yu_port;
ioportmask_t yu_pin;
ioportid_t xl_port;
ioportmask_t xl_pin;
ioportid_t xr_port;
ioportmask_t xr_pin;
};
#endif /* GFX_USE_TOUCHSCREEN */

View File

@ -21,7 +21,7 @@
* @file gtimer.h
* @brief GTIMER GFX User Timer subsystem header file.
*
* @addtogroup GEVENT
* @addtogroup GTIMER
* @{
*/
#ifndef _GTIMER_H
@ -69,7 +69,9 @@
// A callback function (executed in a thread context)
typedef void (*GTimerFunction)(void *param);
// A GTimer structure.
/**
* @brief A GTimer structure
*/
typedef struct GTimer_t {
GTimerFunction fn;
void *param;
@ -78,7 +80,7 @@ typedef struct GTimer_t {
uint16_t flags;
struct GTimer_t *next;
struct GTimer_t *prev;
} GTimer;
} GTimer;
/*===========================================================================*/
/* External declarations. */
@ -88,85 +90,10 @@ typedef struct GTimer_t {
extern "C" {
#endif
/**
* @brief Initialise a timer.
*
* @param[in] pt pointer to a GTimer structure
*
* @api
*/
void gtimerInit(GTimer *pt);
/**
* @brief Set a timer going or alter its properties if it is already going.
*
* @param[in] pt Pointer to a GTimer structure
* @param[in] fn The callback function
* @param[in] param The parameter to pass to the callback function
* @param[in] periodic Is the timer a periodic timer? FALSE is a once-only timer.
* @param[in] millisec The timer period. The following special values are allowed:
* TIME_IMMEDIATE causes the callback function to be called asap.
* A periodic timer with this value will fire once only.
* TIME_INFINITE never timeout (unless triggered by gtimerJab or gtimerJabI)
*
* @note If the timer is already active its properties are updated with the new parameters.
* The current period will be immediately canceled (without the callback function being
* called) and the timer will be restart with the new timer properties.
* @note The callback function should be careful not to over-run the thread stack.
* Define a new value for the macro GTIME_THREAD_STACK_SIZE if you want to
* change the default size.
* @note The callback function should return as quickly as possible as all
* timer callbacks are performed by a single thread. If a callback function
* takes too long it could affect the timer response for other timers.
* @note A timer callback function is not a replacement for a dedicated thread if the
* function wants to perform computationally expensive stuff.
* @note As the callback function is called on GTIMER's thread, the function must make sure it uses
* appropriate synchronisation controls such as semaphores or mutexes around any data
* structures it shares with other threads such as the main application thread.
*
* @api
*/
void gtimerStart(GTimer *pt, GTimerFunction fn, void *param, bool_t periodic, systime_t millisec);
/**
* @brief Stop a timer (periodic or otherwise)
*
* @param[in] pt Pointer to a GTimer structure
*
* @note If the timer is not active this does nothing.
*
* @api
*/
void gtimerStop(GTimer *pt);
/**
* @brief Jab a timer causing the current period to immediate expire
* @details The callback function will be called as soon as possible.
*
* @pre Use from a normal thread context.
*
* @param[in] pt Pointer to a GTimer structure
*
* @note If the timer is not active this does nothing.
* @note Repeated Jabs before the callback function actually happens are ignored.
*
* @api
*/
void gtimerJab(GTimer *pt);
/**
* @brief Jab a timer causing the current period to immediate expire
* @details The callback function will be called as soon as possible.
*
* @pre Use from an interrupt routine context.
*
* @param[in] pt Pointer to a GTimer structure
*
* @note If the timer is not active this does nothing.
* @note Repeated Jabs before the callback function actually happens are ignored.
*
* @api
*/
void gtimerJabI(GTimer *pt);
#ifdef __cplusplus
@ -177,3 +104,4 @@ void gtimerJabI(GTimer *pt);
#endif /* _GTIMER_H */
/** @} */

View File

@ -171,14 +171,55 @@ extern "C" {
GHandle gwinCreateWindow(GWindowObject *gw, coord_t x, coord_t y, coord_t width, coord_t height);
void gwinDestroyWindow(GHandle gh);
/* Status Functions */
/**
* @brief Get the X coordinate of the window
* @details Returns the X coordinate of the origin of the window.
* The coordinate is relative to the physical screen zero point.
*
* @param[in] gh The window
*/
#define gwinGetScreenX(gh) ((gh)->x)
/**
* @brief Get the Y coordinate of the window
* @details Returns the Y coordinate of the origin of the window.
* The coordinate is relative to the physical screen zero point.
*
* @param[in] gh The window
*/
#define gwinGetScreenY(gh) ((gh)->y)
/**
* @brief Get the width of the window
*
* @param[in] gh The window
*/
#define gwinGetWidth(gh) ((gh)->width)
/**
* @brief Get the height of the window
*
* @param[in] gh The window
*/
#define gwinGetHeight(gh) ((gh)->height)
/* Set up for drawing */
/**
* @brief Set foreground color
* @details Set the color which will be used to draw
*
* @param[in] gh The window
* @param[in] clr The color to be set
*/
#define gwinSetColor(gh, clr) (gh)->color = (clr)
/**
* @brief Set background color
* @details Set the color which will be used as background
* @note gwinClear() must be called to set the background color
*
* @param[in] gh The window
* @param[in] bgclr The background color
*/
#define gwinSetBgColor(gh, bgclr) (gh)->bgcolor = (bgclr)
/* Set up for text */

View File

@ -29,9 +29,6 @@
#include "hal.h"
#include "gdisp.h"
#ifndef _GDISP_C
#define _GDISP_C
#if GFX_USE_GDISP || defined(__DOXYGEN__)
#ifdef GDISP_NEED_TEXT
@ -1244,7 +1241,7 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
/**
* @brief Pack a pixel into a pixel buffer.
* @note This function performs no buffer boundary checking
* regardless of whether GDISP_NEED_CLIPPING has been specified.
* regardless of whether GDISP_NEED_CLIP has been specified.
*
* @param[in] buf The buffer to put the pixel in
* @param[in] cx The width of a pixel line
@ -1268,7 +1265,5 @@ void gdispDrawBox(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#endif
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_C */
/** @} */

View File

@ -31,7 +31,6 @@
#include "gdisp_fonts.h"
/* fontSmall - for side buttons */
#if 1
/* Forward Declarations of internal arrays */

View File

@ -29,9 +29,6 @@
#include "hal.h"
#include "gevent.h"
#ifndef _GEVENT_C
#define _GEVENT_C
#if GFX_USE_GEVENT || defined(__DOXYGEN__)
#if GEVENT_ASSERT_NO_RESOURCE
@ -40,14 +37,14 @@
#define GEVENT_ASSERT(x)
#endif
// This mutex protects access to our tables
/* This mutex protects access to our tables */
static MUTEX_DECL(geventMutex);
// Our table of listener/source pairs
/* Our table of listener/source pairs */
static GSourceListener Assignments[MAX_SOURCE_LISTENERS];
// Loop through the assignment table deleting this listener/source pair.
// Null is treated as a wildcard.
/* Loop through the assignment table deleting this listener/source pair. */
/* Null is treated as a wildcard. */
static void deleteAssignments(GListener *pl, GSourceHandle gsh) {
GSourceListener *psl;
@ -64,9 +61,12 @@ static void deleteAssignments(GListener *pl, GSourceHandle gsh) {
}
}
/* Create a Listener.
* If insufficient resources are available it will either assert or return NULL
* depending on the value of GEVENT_ASSERT_NO_RESOURCE.
/**
* @brief Create a Listener
* @details If insufficient resources are available it will either assert or return NULL
* depending on the value of GEVENT_ASSERT_NO_RESOURCE.
*
* @param[in] pl A listener
*/
void geventListenerInit(GListener *pl) {
chSemInit(&pl->waitqueue, 0); // Next wait'er will block
@ -74,11 +74,18 @@ void geventListenerInit(GListener *pl) {
pl->event.type = GEVENT_NULL; // Always safety
}
/* Attach a source to a listener.
* Flags are interpreted by the source when generating events for each listener.
* If this source is already assigned to the listener it will update the flags.
* If insufficient resources are available it will either assert or return FALSE
* depending on the value of GEVENT_ASSERT_NO_RESOURCE.
/**
* @brief Attach a source to a listener
* @details Flags are interpreted by the source when generating events for each listener.
* If this source is already assigned to the listener it will update the flags.
* If insufficient resources are available it will either assert or return FALSE
* depending on the value of GEVENT_ASSERT_NO_RESOURCE.
*
* @param[in] pl The listener
* @param[in] gsh The source which has to be attached to the listener
* @param[in] flags The flags
*
* @return TRUE if succeeded, FALSE otherwise
*/
bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags) {
GSourceListener *psl, *pslfree;
@ -119,9 +126,13 @@ bool_t geventAttachSource(GListener *pl, GSourceHandle gsh, unsigned flags) {
return pslfree != 0;
}
/* Detach a source from a listener
* If gsh is NULL detach all sources from this listener and if there is still
* a thread waiting for events on this listener, it is sent the exit event.
/**
* @brief Detach a source from a listener
* @details If gsh is NULL detach all sources from this listener and if there is still
* a thread waiting for events on this listener, it is sent the exit event.
*
* @param[in] pl The listener
* @param[in] gsh The source
*/
void geventDetachSource(GListener *pl, GSourceHandle gsh) {
if (pl && gsh) {
@ -137,24 +148,34 @@ void geventDetachSource(GListener *pl, GSourceHandle gsh) {
}
}
/* Wait for an event on a listener from an assigned source.
* The type of the event should be checked (pevent->type) and then pevent should be typecast to the
* actual event type if it needs to be processed.
* timeout specifies the time to wait in system ticks.
* TIME_INFINITE means no timeout - wait forever for an event.
* TIME_IMMEDIATE means return immediately
* Returns NULL on timeout.
* Note: The GEvent buffer is staticly allocated within the GListener so the event does not
/**
* @brief Wait for an event on a listener from an assigned source.
* @details The type of the event should be checked (pevent->type) and then pevent should
* be typecast to the actual event type if it needs to be processed.
* timeout specifies the time to wait in system ticks.
* TIME_INFINITE means no timeout - wait forever for an event.
* TIME_IMMEDIATE means return immediately
* @note The GEvent buffer is staticly allocated within the GListener so the event does not
* need to be dynamicly freed however it will get overwritten by the next call to
* this routine.
*
* @param[in] pl The listener
* @param[in] timeout The timeout
*
* @return NULL on timeout
*/
GEvent *geventEventWait(GListener *pl, systime_t timeout) {
return chSemWaitTimeout(&pl->waitqueue, timeout) == RDY_OK ? &pl->event : 0;
}
/* Called by a source with a possible event to get a listener record.
* 'lastlr' should be NULL on the first call and thereafter the result of the previous call.
* It will return NULL when there are no more listeners for this source.
/**
* @brief Called by a source with a possible event to get a listener record.
* @details @p lastlr should be NULL on the first call and thereafter the result of the previous call.
*
* @param[in] gsh The source handler
* @param[in] lastlr The source listener
*
* @return NULL when there are no more listeners for this source
*/
GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *lastlr) {
GSourceListener *psl;
@ -181,19 +202,27 @@ GSourceListener *geventGetSourceListener(GSourceHandle gsh, GSourceListener *las
return 0;
}
/* Get the event buffer from the GSourceListener.
* Returns NULL if the listener is not currently listening.
* A NULL return allows the source to record (perhaps in glr->scrflags) that the listener has missed events.
* This can then be notified as part of the next event for the listener.
* The buffer can only be accessed untill the next call to geventGetSourceListener or geventSendEvent
/**
* @brief Get the event buffer from the GSourceListener.
* @details A NULL return allows the source to record (perhaps in glr->scrflags) that the listener
* has missed events. This can then be notified as part of the next event for the listener.
* The buffer can only be accessed untill the next call to geventGetSourceListener
* or geventSendEvent
*
* @param[in] psl The source listener
*
* @return NULL if the listener is not currently listening.
*/
GEvent *geventGetEventBuffer(GSourceListener *psl) {
// We already know we have the event lock
return chSemGetCounterI(&psl->pListener->waitqueue) < 0 ? &psl->pListener->event : 0;
}
/* Called by a source to indicate the listener's event buffer has been filled.
* After calling this function the source must not reference in fields in the GSourceListener or the event buffer.
/**
* @brief Called by a source to indicate the listener's event buffer has been filled.
* @details After calling this function the source must not reference in fields in the GSourceListener or the event buffer.
*
* @param[in] psl The source listener
*/
void geventSendEvent(GSourceListener *psl) {
chMtxLock(&geventMutex);
@ -203,7 +232,11 @@ void geventSendEvent(GSourceListener *psl) {
chMtxUnlock();
}
/* Detach any listener that has this source attached */
/**
* @brief Detach any listener that has this source attached
*
* @param[in] gsh The source handle
*/
void geventDetachSourceListeners(GSourceHandle gsh) {
chMtxLock(&geventMutex);
deleteAssignments(0, gsh);
@ -211,6 +244,4 @@ void geventDetachSourceListeners(GSourceHandle gsh) {
}
#endif /* GFX_USE_GEVENT */
#endif /* _GEVENT_C */
/** @} */

View File

@ -29,14 +29,9 @@
#include "hal.h"
#include "ginput.h"
#ifndef _GINPUT_C
#define _GINPUT_C
#if GFX_USE_GINPUT || defined(__DOXYGEN__)
#error "GINPUT: Not Implemented Yet"
#endif /* GFX_USE_GINPUT */
#endif /* _GINPUT_C */
/** @} */

View File

@ -29,9 +29,6 @@
#include "hal.h"
#include "gtimer.h"
#ifndef _GTIMER_C
#define _GTIMER_C
#if GFX_USE_GTIMER || defined(__DOXYGEN__)
#define GTIMER_FLG_PERIODIC 0x0001
@ -286,6 +283,7 @@ void gtimerJab(GTimer *pt) {
* @note If the timer is not active this does nothing.
* @note Repeated Jabs before the callback function actually happens are ignored.
*
* @iclass
* @api
*/
void gtimerJabI(GTimer *pt) {
@ -297,6 +295,4 @@ void gtimerJabI(GTimer *pt) {
}
#endif /* GFX_USE_GTIMER */
#endif /* _GTIMER_C */
/** @} */

View File

@ -29,9 +29,6 @@
#include "hal.h"
#include "gwin.h"
#ifndef _GWIN_C
#define _GWIN_C
#if GFX_USE_GWIN || defined(__DOXYGEN__)
#include <string.h>
@ -157,7 +154,7 @@ void gwinSetFont(GHandle gh, font_t font) {
* @api
*/
void gwinClear(GHandle gh) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillArea(gh->x, gh->y, gh->width, gh->height, gh->bgcolor);
@ -174,7 +171,7 @@ void gwinClear(GHandle gh) {
* @api
*/
void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawPixel(gh->x+x, gh->y+y, gh->color);
@ -192,7 +189,7 @@ void gwinDrawPixel(GHandle gh, coord_t x, coord_t y) {
* @api
*/
void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawLine(gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color);
@ -210,7 +207,7 @@ void gwinDrawLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
* @api
*/
void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawBox(gh->x+x, gh->y+y, cx, cy, gh->color);
@ -228,7 +225,7 @@ void gwinDrawBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
* @api
*/
void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillArea(gh->x+x, gh->y+y, cx, cy, gh->color);
@ -252,7 +249,7 @@ void gwinFillArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy) {
* @api
*/
void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coord_t srcx, coord_t srcy, coord_t srccx, const pixel_t *buffer) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispBlitAreaEx(gh->x+x, gh->y+y, cx, cy, srcx, srcy, srccx, buffer);
@ -271,7 +268,7 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
* @api
*/
void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawCircle(gh->x+x, gh->y+y, radius, gh->color);
@ -291,7 +288,7 @@ void gwinDrawCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
* @api
*/
void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillCircle(gh->x+x, gh->y+y, radius, gh->color);
@ -311,7 +308,7 @@ void gwinFillCircle(GHandle gh, coord_t x, coord_t y, coord_t radius) {
* @api
*/
void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawEllipse(gh->x+x, gh->y+y, a, b, gh->color);
@ -331,7 +328,7 @@ void gwinDrawEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
* @api
*/
void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillEllipse(gh->x+x, gh->y+y, a, b, gh->color);
@ -353,7 +350,7 @@ void gwinFillEllipse(GHandle gh, coord_t x, coord_t y, coord_t a, coord_t b) {
* @api
*/
void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
@ -375,7 +372,7 @@ void gwinDrawArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t start
* @api
*/
void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillArc(gh->x+x, gh->y+y, radius, startangle, endangle, gh->color);
@ -394,7 +391,7 @@ void gwinFillArc(GHandle gh, coord_t x, coord_t y, coord_t radius, coord_t start
* @api
*/
color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
return gdispGetPixelColor(gh->x+x, gh->y+y);
@ -416,7 +413,7 @@ color_t gwinGetPixelColor(GHandle gh, coord_t x, coord_t y) {
*/
void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawChar(gh->x+x, gh->y+y, c, gh->font, gh->color);
@ -438,7 +435,7 @@ void gwinDrawChar(GHandle gh, coord_t x, coord_t y, char c) {
*/
void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillChar(gh->x+x, gh->y+y, c, gh->font, gh->color, gh->bgcolor);
@ -460,7 +457,7 @@ void gwinFillChar(GHandle gh, coord_t x, coord_t y, char c) {
*/
void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawString(gh->x+x, gh->y+y, str, gh->font, gh->color);
@ -482,7 +479,7 @@ void gwinDrawString(GHandle gh, coord_t x, coord_t y, const char *str) {
*/
void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillString(gh->x+x, gh->y+y, str, gh->font, gh->color, gh->bgcolor);
@ -507,7 +504,7 @@ void gwinFillString(GHandle gh, coord_t x, coord_t y, const char *str) {
*/
void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispDrawStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, justify);
@ -532,7 +529,7 @@ void gwinDrawStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy,
*/
void gwinFillStringBox(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, const char* str, justify_t justify) {
if (!gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
gdispFillStringBox(gh->x+x, gh->y+y, cx, cy, str, gh->font, gh->color, gh->bgcolor, justify);
@ -631,7 +628,7 @@ void gwinPutChar(GHandle gh, char c) {
if (gh->type != GW_CONSOLE || !gh->font) return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
@ -836,7 +833,7 @@ void gwinButtonDraw(GHandle gh) {
if (gh->type != GW_BUTTON)
return;
#if GDISP_SET_CLIP
#if GDISP_NEED_CLIP
gdispSetClip(gh->x, gh->y, gh->width, gh->height);
#endif
@ -894,7 +891,5 @@ void gwinButtonDraw(GHandle gh) {
#endif
#endif /* GFX_USE_GWIN */
#endif /* _GWIN_C */
/** @} */

View File

@ -32,14 +32,6 @@
#if GFX_USE_TOUCHSCREEN || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
@ -294,7 +286,10 @@ void tsCalibrate(void) {
int32_t px, py;
uint8_t i, j;
#if GDISP_NEED_CONTROL
gdispSetOrientation(GDISP_ROTATE_0);
#endif
gdispClear(Blue);
gdispFillStringBox(0, 5, gdispGetWidth(), 30, "Calibration", &fontUI2Double, White, Blue, justifyCenter);

View File

@ -1,7 +0,0 @@
This directory contains serval different tools, which might be helpful
for developing and using this GLCD library.
Tools:
- foo
- bar