removed GDISP_LLD() macro - fix

ugfx_release_2.6
Joel Bodenmann 2013-02-11 09:25:45 +01:00
parent 885b3d53b3
commit 1bfc5a9f85
184 changed files with 25628 additions and 0 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
docs/html

1824
Doxygenfile 100644

File diff suppressed because it is too large Load Diff

289
codingstyle.txt 100644
View File

@ -0,0 +1,289 @@
ChibiOS/GFX coding style
To provide an easy-to-read code, we want to have a uniform
coding style within ChibiOS/GFX.
Because I personally like the widley used linux kernel coding style,
I decided to use it for ChibiOS/GFX as well.
Therefore, the coding style documentation is a 1:1 copy from the
codingstyle.txt of the linux kernel source code.
Please make sure you match these coding styles before you contribute
any code. If you find any existing code which dosen't match these rules,
please feel free to submit a patch.
There are only two rules which are not similar to the following
documentation:
- Prefered tabsize is 4, not 8
- We don't use 80 character columns
Please read through the following carefully:
Linux kernel coding style
This is a short document describing the preferred coding style for the
linux kernel. Coding style is very personal, and I won't _force_ my
views on anybody, but this is what goes for anything that I have to be
able to maintain, and I'd prefer it for most other things too. Please
at least consider the points made here.
First off, I'd suggest printing out a copy of the GNU coding standards,
and NOT read it. Burn them, it's a great symbolic gesture.
Anyway, here goes:
Chapter 1: Indentation
Tabs are 8 characters, and thus indentations are also 8 characters.
There are heretic movements that try to make indentations 4 (or even 2!)
characters deep, and that is akin to trying to define the value of PI to
be 3.
Rationale: The whole idea behind indentation is to clearly define where
a block of control starts and ends. Especially when you've been looking
at your screen for 20 straight hours, you'll find it a lot easier to see
how the indentation works if you have large indentations.
Now, some people will claim that having 8-character indentations makes
the code move too far to the right, and makes it hard to read on a
80-character terminal screen. The answer to that is that if you need
more than 3 levels of indentation, you're screwed anyway, and should fix
your program.
In short, 8-char indents make things easier to read, and have the added
benefit of warning you when you're nesting your functions too deep.
Heed that warning.
Chapter 2: Placing Braces
The other issue that always comes up in C styling is the placement of
braces. Unlike the indent size, there are few technical reasons to
choose one placement strategy over the other, but the preferred way, as
shown to us by the prophets Kernighan and Ritchie, is to put the opening
brace last on the line, and put the closing brace first, thusly:
if (x is true) {
we do y
}
However, there is one special case, namely functions: they have the
opening brace at the beginning of the next line, thus:
int function(int x)
{
body of function
}
Heretic people all over the world have claimed that this inconsistency
is ... well ... inconsistent, but all right-thinking people know that
(a) K&R are _right_ and (b) K&R are right. Besides, functions are
special anyway (you can't nest them in C).
Note that the closing brace is empty on a line of its own, _except_ in
the cases where it is followed by a continuation of the same statement,
ie a "while" in a do-statement or an "else" in an if-statement, like
this:
do {
body of do-loop
} while (condition);
and
if (x == y) {
..
} else if (x > y) {
...
} else {
....
}
Rationale: K&R.
Also, note that this brace-placement also minimizes the number of empty
(or almost empty) lines, without any loss of readability. Thus, as the
supply of new-lines on your screen is not a renewable resource (think
25-line terminal screens here), you have more empty lines to put
comments on.
Chapter 3: Naming
C is a Spartan language, and so should your naming be. Unlike Modula-2
and Pascal programmers, C programmers do not use cute names like
ThisVariableIsATemporaryCounter. A C programmer would call that
variable "tmp", which is much easier to write, and not the least more
difficult to understand.
HOWEVER, while mixed-case names are frowned upon, descriptive names for
global variables are a must. To call a global function "foo" is a
shooting offense.
GLOBAL variables (to be used only if you _really_ need them) need to
have descriptive names, as do global functions. If you have a function
that counts the number of active users, you should call that
"count_active_users()" or similar, you should _not_ call it "cntusr()".
Encoding the type of a function into the name (so-called Hungarian
notation) is brain damaged - the compiler knows the types anyway and can
check those, and it only confuses the programmer. No wonder MicroSoft
makes buggy programs.
LOCAL variable names should be short, and to the point. If you have
some random integer loop counter, it should probably be called "i".
Calling it "loop_counter" is non-productive, if there is no chance of it
being mis-understood. Similarly, "tmp" can be just about any type of
variable that is used to hold a temporary value.
If you are afraid to mix up your local variable names, you have another
problem, which is called the function-growth-hormone-imbalance syndrome.
See next chapter.
Chapter 4: Functions
Functions should be short and sweet, and do just one thing. They should
fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24,
as we all know), and do one thing and do that well.
The maximum length of a function is inversely proportional to the
complexity and indentation level of that function. So, if you have a
conceptually simple function that is just one long (but simple)
case-statement, where you have to do lots of small things for a lot of
different cases, it's OK to have a longer function.
However, if you have a complex function, and you suspect that a
less-than-gifted first-year high-school student might not even
understand what the function is all about, you should adhere to the
maximum limits all the more closely. Use helper functions with
descriptive names (you can ask the compiler to in-line them if you think
it's performance-critical, and it will probably do a better job of it
that you would have done).
Another measure of the function is the number of local variables. They
shouldn't exceed 5-10, or you're doing something wrong. Re-think the
function, and split it into smaller pieces. A human brain can
generally easily keep track of about 7 different things, anything more
and it gets confused. You know you're brilliant, but maybe you'd like
to understand what you did 2 weeks from now.
Chapter 5: Commenting
Comments are good, but there is also a danger of over-commenting. NEVER
try to explain HOW your code works in a comment: it's much better to
write the code so that the _working_ is obvious, and it's a waste of
time to explain badly written code.
Generally, you want your comments to tell WHAT your code does, not HOW.
Also, try to avoid putting comments inside a function body: if the
function is so complex that you need to separately comment parts of it,
you should probably go back to chapter 4 for a while. You can make
small comments to note or warn about something particularly clever (or
ugly), but try to avoid excess. Instead, put the comments at the head
of the function, telling people what it does, and possibly WHY it does
it.
Chapter 6: You've made a mess of it
That's OK, we all do. You've probably been told by your long-time Unix
user helper that "GNU emacs" automatically formats the C sources for
you, and you've noticed that yes, it does do that, but the defaults it
uses are less than desirable (in fact, they are worse than random
typing - a infinite number of monkeys typing into GNU emacs would never
make a good program).
So, you can either get rid of GNU emacs, or change it to use saner
values. To do the latter, you can stick the following in your .emacs file:
(defun linux-c-mode ()
"C mode with adjusted defaults for use with the Linux kernel."
(interactive)
(c-mode)
(c-set-style "K&R")
(setq c-basic-offset 8))
This will define the M-x linux-c-mode command. When hacking on a
module, if you put the string -*- linux-c -*- somewhere on the first
two lines, this mode will be automatically invoked. Also, you may want
to add
(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode)
auto-mode-alist))
to your .emacs file if you want to have linux-c-mode switched on
automagically when you edit source files under /usr/src/linux.
But even if you fail in getting emacs to do sane formatting, not
everything is lost: use "indent".
Now, again, GNU indent has the same brain dead settings that GNU emacs
has, which is why you need to give it a few command line options.
However, that's not too bad, because even the makers of GNU indent
recognize the authority of K&R (the GNU people aren't evil, they are
just severely misguided in this matter), so you just give indent the
options "-kr -i8" (stands for "K&R, 8 character indents").
"indent" has a lot of options, and especially when it comes to comment
re-formatting you may want to take a look at the manual page. But
remember: "indent" is not a fix for bad programming.
Chapter 7: Configuration-files
For configuration options (arch/xxx/config.in, and all the Config.in files),
somewhat different indentation is used.
An indention level of 3 is used in the code, while the text in the config-
options should have an indention-level of 2 to indicate dependencies. The
latter only applies to bool/tristate options. For other options, just use
common sense. An example:
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM
if [ "$CONFIG_BOOM" != "n" ]; then
bool ' Output nice messages when you explode' CONFIG_CHEER
fi
fi
Generally, CONFIG_EXPERIMENTAL should surround all options not considered
stable. All options that are known to trash data (experimental write-
support for file-systems, for instance) should be denoted (DANGEROUS), other
Experimental options should be denoted (EXPERIMENTAL).
Chapter 8: Data structures
Data structures that have visibility outside the single-threaded
environment they are created and destroyed in should always have
reference counts. In the kernel, garbage collection doesn't exist (and
outside the kernel garbage collection is slow and inefficient), which
means that you absolutely _have_ to reference count all your uses.
Reference counting means that you can avoid locking, and allows multiple
users to have access to the data structure in parallel - and not having
to worry about the structure suddenly going away from under them just
because they slept or did something else for a while.
Note that locking is _not_ a replacement for reference counting.
Locking is used to keep data structures coherent, while reference
counting is a memory management technique. Usually both are needed, and
they are not to be confused with each other.
Many data structures can indeed have two levels of reference counting,
when there are users of different "classes". The subclass count counts
the number of subclass users, and decrements the global count just once
when the subclass count goes to zero.
Examples of this kind of "multi-reference-counting" can be found in
memory management ("struct mm_struct": mm_users and mm_count), and in
filesystem code ("struct super_block": s_count and s_active).
Remember: if another thread can find your data structure, and you don't
have a reference count on it, you almost certainly have a bug.

View File

@ -0,0 +1,33 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP FALSE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,79 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
void mandelbrot(float x1, float y1, float x2, float y2) {
unsigned int i,j, width, height;
uint16_t iter;
color_t color;
float fwidth, fheight;
float sy = y2 - y1;
float sx = x2 - x1;
const int MAX = 512;
width = (unsigned int)gdispGetWidth();
height = (unsigned int)gdispGetHeight();
fwidth = width;
fheight = height;
for(i = 0; i < width; i++) {
for(j = 0; j < height; j++) {
float cy = j * sy / fheight + y1;
float cx = i * sx / fwidth + x1;
float x=0.0f, y=0.0f, xx=0.0f, yy=0.0f;
for(iter=0; iter <= MAX && xx+yy<4.0f; iter++) {
xx = x*x;
yy = y*y;
y = 2.0f*x*y + cy;
x = xx - yy + cx;
}
//color = ((iter << 8) | (iter&0xFF));
color = RGB2COLOR(iter<<7, iter<<4, iter);
gdispDrawPixel(i, j, color);
}
}
}
int main(void) {
float cx, cy;
float zoom = 1.0f;
halInit();
chSysInit();
gdispInit();
/* where to zoom in */
cx = -0.086f;
cy = 0.85f;
while(TRUE) {
mandelbrot(-2.0f*zoom+cx, -1.5f*zoom+cy, 2.0f*zoom+cx, 1.5f*zoom+cy);
zoom *= 0.7f;
if(zoom <= 0.00001f)
zoom = 1.0f;
}
}

View File

@ -0,0 +1,43 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT TRUE
#define GFX_USE_GTIMER TRUE
#define GFX_USE_GINPUT TRUE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_MULTITHREAD TRUE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL FALSE
#define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS TRUE
/* Features for the GINPUT sub-system. */
#define GINPUT_NEED_MOUSE TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,113 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#define COLOR_SIZE 20
#define PEN_SIZE 20
#define OFFSET 3
#define COLOR_BOX(a) (ev.x >= a && ev.x <= a + COLOR_SIZE)
#define PEN_BOX(a) (ev.y >= a && ev.y <= a + COLOR_SIZE)
#define GET_COLOR(a) (COLOR_BOX(a * COLOR_SIZE + OFFSET))
#define GET_PEN(a) (PEN_BOX(a * 2 * PEN_SIZE + OFFSET))
#define DRAW_COLOR(a) (a * COLOR_SIZE + OFFSET)
#define DRAW_PEN(a) (a * 2 * PEN_SIZE + OFFSET)
#define DRAW_AREA(x, y) (x >= PEN_SIZE + OFFSET + 3 && x <= gdispGetWidth() && \
y >= COLOR_SIZE + OFFSET + 3 && y <= gdispGetHeight())
void drawScreen(void) {
char *msg = "ChibiOS/GFX";
font_t font1, font2;
font1 = gdispOpenFont("UI2 Double");
font2 = gdispOpenFont("LargeNumbers");
gdispClear(White);
gdispDrawString(gdispGetWidth()-gdispGetStringWidth(msg, font1)-3, 3, msg, font1, Black);
/* colors */
gdispFillArea(0 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Black); /* Black */
gdispFillArea(1 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Red); /* Red */
gdispFillArea(2 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Yellow); /* Yellow */
gdispFillArea(3 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Green); /* Green */
gdispFillArea(4 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Blue); /* Blue */
gdispDrawBox (5 * COLOR_SIZE + 3, 3, COLOR_SIZE, COLOR_SIZE, Black); /* White */
/* pens */
gdispDrawString(OFFSET * 2, DRAW_PEN(1), "1", font2, Black);
gdispDrawString(OFFSET * 2, DRAW_PEN(2), "2", font2, Black);
gdispDrawString(OFFSET * 2, DRAW_PEN(3), "3", font2, Black);
gdispDrawString(OFFSET * 2, DRAW_PEN(4), "4", font2, Black);
gdispDrawString(OFFSET * 2, DRAW_PEN(5), "5", font2, Black);
gdispCloseFont(font1);
gdispCloseFont(font2);
}
GEventMouse ev;
int main(void) {
color_t color = Black;
uint16_t pen = 0;
halInit();
chSysInit();
gdispInit();
ginputGetMouse(0);
gdispSetOrientation(GDISP_ROTATE_90);
drawScreen();
while (TRUE) {
ginputGetMouseStatus(0, &ev);
if (!(ev.current_buttons & GINPUT_MOUSE_BTN_LEFT))
continue;
/* inside color box ? */
if(ev.y >= OFFSET && ev.y <= COLOR_SIZE) {
if(GET_COLOR(0)) color = Black;
else if(GET_COLOR(1)) color = Red;
else if(GET_COLOR(2)) color = Yellow;
else if(GET_COLOR(3)) color = Green;
else if(GET_COLOR(4)) color = Blue;
else if(GET_COLOR(5)) color = White;
/* inside pen box ? */
} else if(ev.x >= OFFSET && ev.x <= PEN_SIZE) {
if(GET_PEN(1)) pen = 0;
else if(GET_PEN(2)) pen = 1;
else if(GET_PEN(3)) pen = 2;
else if(GET_PEN(4)) pen = 3;
else if(GET_PEN(5)) pen = 4;
/* inside drawing area ? */
} else if(DRAW_AREA(ev.x, ev.y)) {
if(pen == 0)
gdispDrawPixel(ev.x, ev.y, color);
else
gdispFillCircle(ev.x, ev.y, pen, color);
}
}
}

View File

@ -0,0 +1,41 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION FALSE
#define GDISP_NEED_CLIP FALSE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL TRUE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL FALSE
#define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,146 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "stdlib.h"
#include "string.h"
#include "gfx.h"
#define SCB_DEMCR (*(volatile unsigned *)0xE000EDFC)
#define CPU_RESET_CYCLECOUNTER do { SCB_DEMCR = SCB_DEMCR | 0x01000000; \
DWT_CYCCNT = 0; \
DWT_CTRL = DWT_CTRL | 1 ; } while(0)
static int uitoa(unsigned int value, char * buf, int max) {
int n = 0;
int i = 0;
unsigned int tmp = 0;
if (NULL == buf)
return -3;
if (2 > max)
return -4;
i=1;
tmp = value;
if (0 > tmp) {
tmp *= -1;
i++;
}
for (;;) {
tmp /= 10;
if (0 >= tmp)
break;
i++;
}
if (i >= max) {
buf[0] = '?';
buf[1] = 0x0;
return 2;
}
n = i;
tmp = value;
if (0 > tmp) {
tmp *= -1;
}
buf[i--] = 0x0;
for (;;) {
buf[i--] = (tmp % 10) + '0';
tmp /= 10;
if (0 >= tmp) {
break;
}
}
if (-1 != i) {
buf[i--] = '-';
}
return n;
}
void benchmark(void) {
uint32_t i, pixels, ms, pps;
char pps_str[25];
coord_t height, width, rx, ry, rcx, rcy;
color_t random_color;
font_t font;
gdispSetOrientation(GDISP_ROTATE_90);
gdispClear(Black);
width = gdispGetWidth();
height = gdispGetHeight();
font = gdispOpenFont("UI2 Double");
gdispDrawStringBox(0, 0, width, 30, "ChibiOS/GFX - Benchmark", font, White, justifyCenter);
font = gdispOpenFont("UI2");
gdispDrawStringBox(0, height/2, width, 30, "5000 random rectangles", font, White, justifyCenter);
chThdSleepMilliseconds(3000);
/* seed for the rand() */
srand(DWT_CYCCNT);
pixels = 0;
CPU_RESET_CYCLECOUNTER;
for (i = 0; i < 5000; i++) {
random_color = (rand() % 65535);
rx = (rand() % (width-10));
ry = (rand() % (height-10));
rcx = (rand() % ((width-rx)-10))+10;
rcy = (rand() % ((height-ry)-10))+10;
gdispFillArea(rx, ry, rcx, rcy, random_color);
pixels += (rcx+1)*(rcy+1);
}
ms = DWT_CYCCNT / 168000;
pps = (float)pixels/((float)ms/1000.0f);
memset (pps_str, 0, sizeof(pps_str));
uitoa(pps, pps_str, sizeof(pps_str));
strcat(pps_str, " Pixels/s");
font = gdispOpenFont("UI2 Double");
gdispClear(Black);
gdispDrawStringBox(0, 0, width, 30, "ChibiOS/GFX - Benchmark", font, White, justifyCenter);
gdispDrawStringBox(0, height/2, width, 30, pps_str, font, White, justifyCenter);
//gdispDrawString(20, height/2, pps_str, font, White);
}
int main(void) {
halInit();
chSysInit();
gdispInit();
benchmark();
while(TRUE) {
chThdSleepMilliseconds(500);
}
return 0;
}

View File

@ -0,0 +1,43 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL TRUE
#define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* Features for the GWIN sub-system. */
#define GWIN_NEED_CONSOLE TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,87 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "gfx.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;
font_t font1, font2;
halInit();
chSysInit();
/* initialize and clear the display */
gdispInit();
gdispClear(Black);
font1 = gdispOpenFont("UI2 Double");
font2 = gdispOpenFont("Small");
/* create the three console windows and set a font for each */
GW1 = gwinCreateConsole(NULL, 0, 0, gdispGetWidth(), gdispGetHeight()/2, font1);
GW2 = gwinCreateConsole(NULL, 0, gdispGetHeight()/2, gdispGetWidth()/2, gdispGetHeight(), font2);
GW3 = gwinCreateConsole(NULL, gdispGetWidth()/2, gdispGetHeight()/2, gdispGetWidth(), gdispGetHeight(), font2);
/* 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,33 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,52 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
int main(void) {
coord_t width, height;
coord_t i, j;
halInit();
chSysInit();
/* Initialize and clear the display */
gdispInit();
gdispClear(Black);
// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();
// Code Here
gdispDrawBox(10, 10, width/2, height/2, Yellow);
gdispFillArea(width/2, height/2, width/2-10, height/2-10, Blue);
gdispDrawLine(5, 30, width-50, height-40, Red);
for(i = 5, j = 0; i < width && j < height; i += 7, j += i/20)
gdispDrawPixel (i, j, White);
while(TRUE) {
chThdSleepMilliseconds(500);
}
}

View File

@ -0,0 +1,33 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_ELLIPSE TRUE
#define GDISP_NEED_ARC TRUE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,51 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
int main(void) {
coord_t width, height;
halInit();
chSysInit();
/* Initialize and clear the display */
gdispInit();
gdispClear(Black);
// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();
// Code Here
gdispDrawCircle(width/2, height/2, 20, Yellow);
gdispFillCircle (width/4, height/4, 50, Blue);
gdispFillEllipse (width-100, height-100, 30, 60, Red);
gdispDrawEllipse (width-100, height-100, 50, 20, Yellow);
gdispDrawArc(width-width/8, height/8, 30, 10, 70, Gray);
gdispFillArc(width/8, height/8, 30, 10, 70, Gray);
while(TRUE) {
chThdSleepMilliseconds(500);
}
}

View File

@ -0,0 +1,33 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */

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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
int main(void) {
coord_t width, height;
font_t font1, font2, font3, font4;
const char *msg;
halInit();
chSysInit();
/* Initialize and clear the display */
gdispInit();
gdispClear(Black);
// Get the screen size
width = gdispGetWidth();
height = gdispGetHeight();
// Get the fonts we want to use
font1 = gdispOpenFont("UI2");
font2 = gdispOpenFont("UI2 Double");
font3 = gdispOpenFont("UI2 Narrow");
font4 = gdispOpenFont("LargeNumbers");
// Display large numbers on the right (measuring the string)
msg = "123456";
gdispDrawString(width-gdispGetStringWidth(msg, font4)-3, 3, msg, font4, Green);
// Display the font name under it.
msg = gdispGetFontName(font4);
gdispDrawString(width-gdispGetStringWidth(msg, font1)-3, 20, msg, font1, Green);
// Demonstrate our other fonts
gdispDrawString(10, 10, "Writing with Font 'UI2'", font1, Yellow);
gdispFillString(10, 35, "Writing with Font 'UI2 Double'", font2, Red, White);
gdispDrawStringBox(0, 50, width, 40, "Writing with Font 'UI2 Narrow'", font3, Red, justifyCenter);
gdispFillStringBox(0, 90, width, 40, "Filled Centered", font3, Pink, Gray, justifyCenter);
// Clean up the fonts
gdispCloseFont(font1);
gdispCloseFont(font2);
gdispCloseFont(font3);
gdispCloseFont(font4);
// Wait forever
while(TRUE) {
chThdSleepMilliseconds(500);
}
}

View File

@ -0,0 +1,47 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT TRUE
#define GFX_USE_GTIMER TRUE
#define GFX_USE_GINPUT TRUE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT TRUE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD TRUE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL FALSE
#define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 TRUE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* Features for the GWIN sub-system. */
#define GWIN_NEED_BUTTON TRUE
#define GWIN_NEED_CONSOLE TRUE
/* Features for the GINPUT sub-system. */
#define GINPUT_NEED_MOUSE TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,349 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "chprintf.h"
#include "gfx.h"
static GConsoleObject gc;
static GButtonObject gNext;
static GButtonObject gPrev;
static GListener gl;
/*------------------------------------------------------------------------*
* GINPUT Touch Driver Calibrator. *
*------------------------------------------------------------------------*/
int main(void) {
GSourceHandle gs, gsNext, gsPrev;
GEvent *pe;
GEventMouse *pem;
GEventGWinButton *peb;
coord_t swidth, sheight;
GHandle ghc, ghNext, ghPrev;
BaseSequentialStream *gp;
GEventType deviceType;
font_t font;
halInit(); // Initialise the Hardware
chSysInit(); // Initialize the OS
gdispInit(); // Initialize the display
// Get the display dimensions
swidth = gdispGetWidth();
sheight = gdispGetHeight();
ghNext = ghPrev = 0;
// Create our title
font = gdispOpenFont("UI2");
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Red, White, justifyLeft);
// Create our main display window
ghc = gwinCreateConsole(&gc, 0, 20, swidth, sheight-20, font);
gwinClear(ghc);
gp = gwinGetConsoleStream(ghc);
// Initialize the mouse in our special no calibration mode.
geventListenerInit(&gl);
gs = ginputGetMouse(9999);
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
/*
* Test: Device Type
*/
StepDeviceType:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n1. DEVICE TYPE\n\n");
pem = (GEventMouse *)&gl.event;
ginputGetMouseStatus(0, pem);
deviceType = pem->type;
gwinSetColor(ghc, White);
chprintf(gp, "This is detected as a %s device\n\n",
deviceType == GEVENT_MOUSE ? "MOUSE" : (pem->type == GEVENT_TOUCH ? "TOUCH" : "UNKNOWN"));
if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to move on to the next test.\n");
else
chprintf(gp, "Press and release your finger to move on to the next test.\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepClickJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
/*
* Test: Mouse raw reading jitter
*/
StepRawJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n2. GINPUT_MOUSE_READ_CYCLES\n\n");
gwinSetColor(ghc, White);
if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button.\n\n");
else
chprintf(gp, "Press and hold on the surface.\n\n");
chprintf(gp, "Numbers will display in this window.\n"
"Ensure that values don't jump around very much when your finger is stationary.\n\n"
"Increasing GINPUT_MOUSE_READ_CYCLES helps reduce jitter but increases CPU usage.\n\n");
if (ghNext)
chprintf(gp, "Press Next or Back to continue.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Release the mouse button to move on to the next test.\n");
else
chprintf(gp, "Release your finger to move on to the next test.\n");
// For this test turn on ALL mouse movement events
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA|GLISTEN_MOUSENOFILTER);
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepDeviceType;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, "%u:%u\n", pem->x, pem->y);
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
// Reset to just changed movements.
geventAttachSource(&gl, gs, GLISTEN_MOUSEDOWNMOVES|GLISTEN_MOUSEMETA);
/*
* Test: Calibration
*/
StepCalibrate:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n3. GINPUT_MOUSE_CALIBRATION_ERROR\n\n");
gwinSetColor(ghc, Gray);
chprintf(gp, "Ensure GINPUT_MOUSE_NEED_CALIBRATION = TRUE and GINPUT_MOUSE_CALIBRATION_ERROR is >= 0\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "You will be presented with a number of points to touch.\nPress them in turn.\n\n"
"If the calibration repeatedly fails, increase GINPUT_MOUSE_CALIBRATION_ERROR and try again.\n\n");
if (ghNext)
chprintf(gp, "Press Next to start the calibration.\n");
else if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Click the mouse button to start the calibration.\n");
else
chprintf(gp, "Press and release your finger to start the calibration.\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepRawJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if (!ghNext && (pem->meta & GMETA_MOUSE_UP))
break;
}
}
// Calibrate
ginputCalibrateMouse(0);
/* From now on we can use Next and Previous Buttons */
if (!ghNext) {
ghNext = gwinCreateButton(&gNext, swidth-50, 0, 50, 20, font, GBTN_NORMAL);
gwinSetButtonText(ghNext, "Next", FALSE);
gsNext = gwinGetButtonSource(ghNext);
geventAttachSource(&gl, gsNext, 0);
gwinAttachButtonMouseSource(ghNext, gs);
ghPrev = gwinCreateButton(&gPrev, swidth-100, 0, 50, 20, font, GBTN_NORMAL);
gwinSetButtonText(ghPrev, "Back", FALSE);
gsPrev = gwinGetButtonSource(ghPrev);
geventAttachSource(&gl, gsPrev, 0);
gwinAttachButtonMouseSource(ghPrev, gs);
#if 0
{
GSourceHandle gsButton1, gsButton2;
// Attach a couple of hardware toggle buttons to our Next and Back buttons as well.
// We can always use the mouse to trigger the buttons if you don't want to use hardware toggles.
// This code depends on your hardware. Turn it on only if you have
// defined a board definition for your toggle driver. Then change
// the next two lines to be correct for your hardware. The values
// below are correct for the Win32 toggle driver.
gsButton1 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY1);
gsButton2 = ginputGetToggle(GINPUT_TOGGLE_MOMENTARY2);
gwinAttachButtonToggleSource(ghNext, gsButton2);
gwinAttachButtonToggleSource(ghPrev, gsButton1);
}
#endif
}
// Calibration used the whole screen - re-establish our title
gdispFillStringBox(0, 0, swidth, 20, "Touch Calibration", font, Green, White, justifyLeft);
gwinButtonDraw(ghNext);
gwinButtonDraw(ghPrev);
/*
* Test: Mouse movement jitter
*/
StepJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n4. GINPUT_MOUSE_MOVE_JITTER\n\n");
gwinSetColor(ghc, White);
if (deviceType == GEVENT_MOUSE)
chprintf(gp, "Press and hold the mouse button and move around as if to draw.\n\n");
else
chprintf(gp, "Press firmly on the surface and move around as if to draw.\n\n");
chprintf(gp, "Dots will display in this window. Ensure that when you stop moving your finger that "
"new dots stop displaying.\nNew dots should only display when your finger is moving.\n\n"
"Adjust GINPUT_MOUSE_MOVE_JITTER to the smallest value that this reliably works for.\n\n");
chprintf(gp, "Press Next or Back to continue.\n\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepCalibrate;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
chprintf(gp, ".");
}
}
/*
* Test: Polling frequency
*/
StepPolling:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n5. GINPUT_MOUSE_POLL_PERIOD\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press firmly on the surface (or press and hold the mouse button) and move around as if to draw.\n\n");
chprintf(gp, "A green line will follow your finger.\n"
"Adjust GINPUT_MOUSE_POLL_PERIOD to the highest value that provides a line without "
"gaps that are too big.\nDecreasing the value increases CPU usage.\n"
"About 25 (millisecs) normally produces good results."
"This test can be ignored for interrupt driven drivers.\n\n");
chprintf(gp, "Press Next or Back to continue.\n\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepJitter;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->current_buttons & GINPUT_MOUSE_BTN_LEFT))
gdispDrawPixel(pem->x, pem->y, Green);
}
}
/*
* Test: Click Jitter
*/
StepClickJitter:
gwinClear(ghc);
gwinSetColor(ghc, Yellow);
chprintf(gp, "\n6. GINPUT_MOUSE_MAX_CLICK_JITTER\n\n");
gwinSetColor(ghc, White);
chprintf(gp, "Press and release the touch surface to \"click\".\nTry both short and long presses.\n");
chprintf(gp, "For a mouse click with the left and right buttons.\n\n");
chprintf(gp, "Dots will display in this window. A yellow dash is a left (or short) click. "
"A red x is a right (or long) click.\n\n"
"Adjust GINPUT_MOUSE_CLICK_JITTER to the smallest value that this reliably works for.\n"
"Adjust GINPUT_MOUSE_CLICK_TIME to adjust distinguishing short vs long presses.\n"
"TIME_INFINITE means there are no long presses (although a right mouse button will still work).\n\n"
"Note: moving your finger (mouse) during a click cancels it.\n\n");
chprintf(gp, "This is the last test but you can press Next or Back to continue.\n\n");
while(1) {
pe = geventEventWait(&gl, TIME_INFINITE);
if (pe->type == GEVENT_GWIN_BUTTON) {
peb = (GEventGWinButton *)pe;
if (peb->button == ghPrev)
goto StepPolling;
if (peb->button == ghNext)
break;
}
if (pe->type == GEVENT_MOUSE || pe->type == GEVENT_TOUCH) {
pem = (GEventMouse *)pe;
if ((pem->meta & GMETA_MOUSE_CLICK)) {
gwinSetColor(ghc, Yellow);
chprintf(gp, "-");
}
if ((pem->meta & GMETA_MOUSE_CXTCLICK)) {
gwinSetColor(ghc, Red);
chprintf(gp, "x");
}
}
}
// Can't let this really exit
goto StepDeviceType;
}

View File

@ -0,0 +1,36 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Features for the GWIN sub-system. */
#define GWIN_NEED_GRAPH TRUE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,71 @@
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#include "math.h"
const GGraphPoint data[5] = {
{ -40, -40 },
{ 70, 40 },
{ 140, 60 },
{ 210, 60 },
{ 280, 200 }
};
GGraphObject g;
GGraphStyle GraphStyle1 = {
{ GGRAPH_POINT_DOT, 0, Blue }, // point
{ GGRAPH_LINE_NONE, 2, Gray }, // line
{ GGRAPH_LINE_SOLID, 0, White }, // x axis
{ GGRAPH_LINE_SOLID, 0, White }, // y axis
{ GGRAPH_LINE_DASH, 5, Gray, 50 }, // x grid
{ GGRAPH_LINE_DOT, 7, Yellow, 50 }, // y grid
GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS // flags
};
GGraphStyle GraphStyle2 = {
{ GGRAPH_POINT_SQUARE, 5, Red }, // point
{ GGRAPH_LINE_DOT, 2, Pink }, // line
{ GGRAPH_LINE_SOLID, 0, White }, // x axis
{ GGRAPH_LINE_SOLID, 0, White }, // y axis
{ GGRAPH_LINE_DASH, 5, Gray, 50 }, // x grid
{ GGRAPH_LINE_DOT, 7, Yellow, 50 }, // y grid
GWIN_GRAPH_STYLE_POSITIVE_AXIS_ARROWS // flags
};
int main(void) {
GHandle gh;
uint16_t i;
halInit();
chSysInit();
gdispInit();
gdispClear(Black);
gh = gwinCreateGraph(&g, 0, 0, gdispGetWidth(), gdispGetHeight());
gwinGraphSetOrigin(gh, gwinGetWidth(gh)/2, gwinGetHeight(gh)/2);
gwinGraphSetStyle(gh, &GraphStyle1);
gwinGraphDrawAxis(gh);
for(i = 0; i < gwinGetWidth(gh); i++)
gwinGraphDrawPoint(gh, i-gwinGetWidth(gh)/2, 80*sin(2*0.2*M_PI*i/180));
gwinGraphStartSet(gh);
GraphStyle1.point.color = Green;
gwinGraphSetStyle(gh, &GraphStyle1);
for(i = 0; i < gwinGetWidth(gh)*5; i++)
gwinGraphDrawPoint(gh, i/5-gwinGetWidth(gh)/2, 95*sin(2*0.2*M_PI*i/180));
gwinGraphStartSet(gh);
gwinGraphSetStyle(gh, &GraphStyle2);
gwinGraphDrawPoints(gh, data, sizeof(data)/sizeof(data[0]));
while(TRUE) {
chThdSleepMilliseconds(100);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,19 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP FALSE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER TRUE
#define GFX_USE_GINPUT FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,59 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.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,55 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_TDISP TRUE
#define GFX_USE_GDISP FALSE
#define GFX_USE_GWIN FALSE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP subsystem */
#define GDISP_NEED_VALIDATION FALSE
#define GDISP_NEED_CLIP FALSE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE FALSE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
/* Features for the TDISP subsystem */
#define TDISP_NEED_4BIT_MODE TRUE
#define TDISP_NEED_8BIT_MODE FALSE
/* Builtin Fonts */
#define GDISP_INCLUDE_FONT_SMALL FALSE
#define GDISP_INCLUDE_FONT_LARGER FALSE
#define GDISP_INCLUDE_FONT_UI1 FALSE
#define GDISP_INCLUDE_FONT_UI2 FALSE
#define GDISP_INCLUDE_FONT_LARGENUMBERS FALSE
/* GWIN */
#define GWIN_NEED_CONSOLE FALSE
#define GWIN_NEED_GRAPH FALSE
#define GWIN_NEED_BUTTON FALSE
#define GWIN_NEED_DIAL FALSE
/* GINPUT */
#define GINPUT_NEED_MOUSE FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,67 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
int main(void) {
char charmap[8];
halInit();
chSysInit();
tdispInit();
/* reset cursor position and clear the screen */
tdispHome();
tdispClear();
/* set cursor position and draw single characters */
tdispSetCursor(4, 0);
tdispDrawChar('H');
tdispDrawChar('D');
tdispDrawChar('4');
tdispDrawChar('4');
tdispDrawChar('7');
tdispDrawChar('8');
tdispDrawChar('0');
/* draw a string to a given location */
tdispDrawStringLocation(0, 1, "chibios-gfx.com");
/* create and display a custom made character */
charmap[0] = 0b00000;
charmap[1] = 0b00100;
charmap[2] = 0b00010;
charmap[3] = 0b11111;
charmap[4] = 0b00010;
charmap[5] = 0b00100;
charmap[6] = 0b00000;
charmap[7] = 0b00000;
tdispCreateChar(0, charmap);
tdispHome();
tdispDrawChar(0);
while(TRUE) {
chThdSleepMilliseconds(250);
}
}

View File

@ -0,0 +1,33 @@
/**
* This file has a different license to the rest of the GFX system.
* You can copy, modify and distribute this file as you see fit.
* You do not need to publish your source modifications to this file.
* The only thing you are not permitted to do is to relicense it
* under a different license.
*/
#ifndef _GFXCONF_H
#define _GFXCONF_H
/* GFX sub-systems to turn on */
#define GFX_USE_GDISP TRUE
#define GFX_USE_GWIN TRUE
#define GFX_USE_GEVENT FALSE
#define GFX_USE_GTIMER FALSE
#define GFX_USE_GINPUT FALSE
/* Features for the GDISP sub-system. */
#define GDISP_NEED_VALIDATION TRUE
#define GDISP_NEED_CLIP TRUE
#define GDISP_NEED_TEXT FALSE
#define GDISP_NEED_CIRCLE TRUE
#define GDISP_NEED_ELLIPSE FALSE
#define GDISP_NEED_ARC FALSE
#define GDISP_NEED_SCROLL FALSE
#define GDISP_NEED_PIXELREAD FALSE
#define GDISP_NEED_CONTROL FALSE
#define GDISP_NEED_MULTITHREAD FALSE
#define GDISP_NEED_ASYNC FALSE
#define GDISP_NEED_MSGAPI FALSE
#endif /* _GFXCONF_H */

View File

@ -0,0 +1,67 @@
/*
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/>.
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
/* The handles for our two Windows */
GHandle GW1, GW2;
int main(void) {
halInit();
chSysInit();
coord_t i, j;
/* 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);
gwinDrawLine (GW1, 5, 30, 150, 110);
for(i=5, j=0; i < 200 && j < 150; i+=3, j+=i/20)
gwinDrawPixel (GW1, i, j);
/*
* 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);
}
}

4
demos/readme.txt 100644
View File

@ -0,0 +1,4 @@
This folder contains a few demos which explain how to use the library.
Only the main files are contained. No compile-able projects

184
docs/rsc/layout.xml 100644
View File

@ -0,0 +1,184 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="">
<tab type="namespaces" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="yes" title="">
<tab type="classes" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="files" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<!--<tab type="dirs" visible="yes" title="" intro=""/>-->
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="no"/>
<detaileddescription title=""/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<functions title=""/>
<variables title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<functions title=""/>
<variables title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="no"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<dirs visible="yes" title=""/>
<nestedgroups visible="yes" title=""/>
<files visible="yes" title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdecl>
<memberdef>
<pagedocs/>
<functions title=""/>
<variables title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="no"/>
<directorygraph visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
</directory>
</doxygenlayout>

37
docs/src/main.dox 100644
View File

@ -0,0 +1,37 @@
/*
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/>.
*/
/**
* @mainpage ChibiOS/GFX
* @author Joel Bodenmann (joel@unormal.org).
*
* <h2>ChibiOS/GFX</h2>
* ChibiOS/GFX is an official add-on library for ChibiOS/RT to
* interface all different types of LCDs and touchscreens.
*
* <h2>Features</h2>
* - Modular design to reduce memory footprint
* - HAL abstractions allows it to easily write new drivers
* - Completely written in C, usable in C++ without any modifications
* - Supports hardware accelerated drawing by LCDs
* - Very flexible interfaces for calibration storage and more
* - We are having our own homepage: http://chibios-gfx.com
*/

View File

@ -0,0 +1,570 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9320/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the ILI9320 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_OLIMEX_STM32_LCD)
#include "gdisp_lld_board_olimex_stm32_lcd.h"
#else
#include "gdisp_lld_board.h"
#endif
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/* This controller is only ever used with a 240 x 320 display */
#if defined(GDISP_SCREEN_HEIGHT)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_WIDTH
#endif
#define GDISP_SCREEN_WIDTH 240
#define GDISP_SCREEN_HEIGHT 320
#define GDISP_INITIAL_CONTRAST 50
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
uint32_t DISPLAY_CODE;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static __inline void lld_lcdDelay(uint16_t us) {
chThdSleepMicroseconds(us);
}
static __inline void lld_lcdWriteIndex(uint16_t index) {
GDISP_LLD(write_index)(index);
}
static __inline void lld_lcdWriteData(uint16_t data) {
GDISP_LLD(write_data)(data);
}
static __inline void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) {
GDISP_LLD(write_index)(lcdReg);
GDISP_LLD(write_data)(lcdRegValue);
}
static __inline uint16_t lld_lcdReadData(void) {
/* fix this! */
//return GDISP_LLD(read_data);
return GDISP_RAM;
}
static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
volatile uint16_t dummy;
GDISP_LLD(write_index)(lcdReg);
dummy = lld_lcdReadData();
(void)dummy;
return lld_lcdReadData();
}
static __inline void lld_lcdWriteStreamStart(void) {
lld_lcdWriteIndex(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++)
lld_lcdWriteData(buffer[i]);
}
static __inline void lld_lcdReadStreamStart(void) {
lld_lcdWriteIndex(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;
dummy = lld_lcdReadData();
(void)dummy;
for(i = 0; i < size; i++)
buffer[i] = lld_lcdReadData();
}
bool_t lld_gdisp_init(void) {
/* Initialise your display */
GDISP_LLD(init_board)();
/* Hardware reset */
GDISP_LLD(setpin_reset)(TRUE);
lld_lcdDelay(1000);
GDISP_LLD(setpin_reset)(FALSE);
lld_lcdDelay(1000);
DISPLAY_CODE = lld_lcdReadReg(0);
lld_lcdWriteReg(0x0000, 0x0001); //start Int. osc
lld_lcdDelay(500);
lld_lcdWriteReg(0x0001, 0x0100); //Set SS bit (shift direction of outputs is from S720 to S1)
lld_lcdWriteReg(0x0002, 0x0700); //select the line inversion
lld_lcdWriteReg(0x0003, 0x1038); //Entry mode(Horizontal : increment,Vertical : increment, AM=1)
lld_lcdWriteReg(0x0004, 0x0000); //Resize control(No resizing)
lld_lcdWriteReg(0x0008, 0x0202); //front and back porch 2 lines
lld_lcdWriteReg(0x0009, 0x0000); //select normal scan
lld_lcdWriteReg(0x000A, 0x0000); //display control 4
lld_lcdWriteReg(0x000C, 0x0000); //system interface(2 transfer /pixel), internal sys clock,
lld_lcdWriteReg(0x000D, 0x0000); //Frame marker position
lld_lcdWriteReg(0x000F, 0x0000); //selects clk, enable and sync signal polarity,
lld_lcdWriteReg(0x0010, 0x0000); //
lld_lcdWriteReg(0x0011, 0x0000); //power control 2 reference voltages = 1:1,
lld_lcdWriteReg(0x0012, 0x0000); //power control 3 VRH
lld_lcdWriteReg(0x0013, 0x0000); //power control 4 VCOM amplitude
lld_lcdDelay(500);
lld_lcdWriteReg(0x0010, 0x17B0); //power control 1 BT,AP
lld_lcdWriteReg(0x0011, 0x0137); //power control 2 DC,VC
lld_lcdDelay(500);
lld_lcdWriteReg(0x0012, 0x0139); //power control 3 VRH
lld_lcdDelay(500);
lld_lcdWriteReg(0x0013, 0x1d00); //power control 4 vcom amplitude
lld_lcdWriteReg(0x0029, 0x0011); //power control 7 VCOMH
lld_lcdDelay(500);
lld_lcdWriteReg(0x0030, 0x0007);
lld_lcdWriteReg(0x0031, 0x0403);
lld_lcdWriteReg(0x0032, 0x0404);
lld_lcdWriteReg(0x0035, 0x0002);
lld_lcdWriteReg(0x0036, 0x0707);
lld_lcdWriteReg(0x0037, 0x0606);
lld_lcdWriteReg(0x0038, 0x0106);
lld_lcdWriteReg(0x0039, 0x0007);
lld_lcdWriteReg(0x003c, 0x0700);
lld_lcdWriteReg(0x003d, 0x0707);
lld_lcdWriteReg(0x0020, 0x0000); //starting Horizontal GRAM Address
lld_lcdWriteReg(0x0021, 0x0000); //starting Vertical GRAM Address
lld_lcdWriteReg(0x0050, 0x0000); //Horizontal GRAM Start Position
lld_lcdWriteReg(0x0051, 0x00EF); //Horizontal GRAM end Position
lld_lcdWriteReg(0x0052, 0x0000); //Vertical GRAM Start Position
lld_lcdWriteReg(0x0053, 0x013F); //Vertical GRAM end Position
switch (DISPLAY_CODE) {
case 0x9320:
lld_lcdWriteReg(0x0060, 0x2700); //starts scanning from G1, and 320 drive lines
break;
case 0x9325:
lld_lcdWriteReg(0x0060, 0xA700); //starts scanning from G1, and 320 drive lines
break;
}
lld_lcdWriteReg(0x0061, 0x0001); //fixed base display
lld_lcdWriteReg(0x006a, 0x0000); //no scroll
lld_lcdWriteReg(0x0090, 0x0010); //set Clocks/Line =16, Internal Operation Clock Frequency=fosc/1,
lld_lcdWriteReg(0x0092, 0x0000); //set gate output non-overlap period=0
lld_lcdWriteReg(0x0093, 0x0003); //set Source Output Position=3
lld_lcdWriteReg(0x0095, 0x0110); //RGB interface(Clocks per line period=16 clocks)
lld_lcdWriteReg(0x0097, 0x0110); //set Gate Non-overlap Period 0 locksc
lld_lcdWriteReg(0x0098, 0x0110); //
lld_lcdWriteReg(0x0007, 0x0173); //display On
// Turn on the backlight
GDISP_LLD(set_backlight)(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
static void lld_lcdSetCursor(uint16_t x, uint16_t y) {
uint32_t addr;
addr = y * 0x100 + x;
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0020, addr & 0xff); /* low addr */
lld_lcdWriteReg(0x0021, (addr >> 8) & 0x1ff); /* high addr */
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0020, (addr >> 8) & 0x1ff); /* low addr */
lld_lcdWriteReg(0x0021, addr & 0xff); /* high addr */
break;
case GDISP_ROTATE_180:
break;
case GDISP_ROTATE_270:
break;
}
}
static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) {
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0050, x);
lld_lcdWriteReg(0x0051, x + cx - 1);
lld_lcdWriteReg(0x0052, y);
lld_lcdWriteReg(0x0053, y + cy - 1);
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0050, y);
lld_lcdWriteReg(0x0051, y + cy - 1);
lld_lcdWriteReg(0x0052, x);
lld_lcdWriteReg(0x0053, x + cx - 1);
break;
case GDISP_ROTATE_180:
break;
case GDISP_ROTATE_270:
break;
}
lld_lcdSetCursor(x, y);
}
static __inline 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;
}
}
void lld_gdisp_draw_pixel(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);
}
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
void lld_gdisp_clear(color_t color) {
unsigned i;
lld_lcdSetCursor(0, 0);
lld_lcdWriteStreamStart();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
lld_lcdWriteData(color);
lld_lcdWriteStreamStop();
}
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
unsigned i, area;
area = cx*cy;
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
for(i = 0; i < area; i++)
lld_lcdWriteData(color);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
lld_lcdWriteData(*buffer++);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
color_t color;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
lld_lcdSetCursor(x, y);
lld_lcdWriteStreamStart();
color = lld_lcdReadData();
color = lld_lcdReadData();
lld_lcdWriteStreamStop();
return color;
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
coord_t row0, row1;
unsigned i, gap, abslines;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
abslines = lines < 0 ? -lines : lines;
if (abslines >= cy) {
abslines = cy;
gap = 0;
} else {
gap = cy - abslines;
for(i = 0; i < gap; i++) {
if(lines > 0) {
row0 = y + i + lines;
row1 = y + i;
} else {
row0 = (y - i - 1) + lines;
row1 = (y - i - 1);
}
/* read row0 into the buffer and then write at row1*/
lld_lcdSetViewPort(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();
}
}
/* fill the remaining gap */
lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines);
lld_lcdWriteStreamStart();
gap = cx*abslines;
for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
void lld_gdisp_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_POWER:
if(GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
lld_lcdWriteReg(0x0007, 0x0000);
lld_lcdWriteReg(0x0010, 0x0000);
lld_lcdWriteReg(0x0011, 0x0000);
lld_lcdWriteReg(0x0012, 0x0000);
lld_lcdWriteReg(0x0013, 0x0000);
GDISP_LLD(set_backlight)(0);
break;
case powerOn:
//*************Power On sequence ******************//
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
lld_lcdWriteReg(0x0011, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0012, 0x013C); /* VREG1OUT voltage */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0013, 0x0E00); /* VDV[4:0] for VCOM amplitude */
lld_lcdWriteReg(0x0029, 0x0009); /* VCM[4:0] for VCOMH */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0007, 0x0173); /* 262K color and display ON */
GDISP_LLD(set_backlight)(GDISP.Backlight);
if(GDISP.Powermode != powerSleep || GDISP.Powermode != powerDeepSleep)
lld_gdisp_init();
break;
case powerSleep:
lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
GDISP_LLD(set_backlight)(0);
break;
case powerDeepSleep:
lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
GDISP_LLD(set_backlight)(0);
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
case GDISP_CONTROL_ORIENTATION:
if(GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0001, 0x0100);
lld_lcdWriteReg(0x0003, 0x1038);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0001, 0x0000);
lld_lcdWriteReg(0x0003, 0x1030);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
/* ToDo */
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
/* ToDo */
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
case GDISP_CONTROL_BACKLIGHT:
if((unsigned)value > 100) value = (void *)100;
GDISP_LLD(set_backlight)((unsigned)value);
GDISP.Backlight = (unsigned)value;
break;
default:
return;
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9320/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ILI9320

View File

@ -0,0 +1,59 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9320/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the ILI9320 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef GDISP_LLD_BOARD_H
#define GDISP_LLD_BOARD_H
static __inline void GDISP_LLD(init_board)(void) {
#error "ILI9320: You must implement the init_board routine for your board"
}
static __inline void GDISP_LLD(setpin_reset)(bool_t state) {
#error "ILI9320: You must implement setpin_reset routine for your board"
}
static __inline void GDISP_LLD(write_index)(uint16_t data) {
#error "ILI9320: You must implement write_index routine for your board"
}
static __inline void GDISP_LLD(write_data)(uint16_t data) {
#error "ILI9320: You must implement write_data routine for your board"
}
static __inline uint16_t GDISP_LLD(read_data)(void) {
#error "ILI9320: You must implement read_data routine for your board"
}
/* if not available, just ignore the argument and return */
static __inline uint16_t GDISP_LLD(set_backlight)(uint8_t percentage) {
#error "ILI9320: You must implement set_backlight routine for your board"
}
#endif /* GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,85 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9320/gdisp_lld_board_olimex_stm32_lcd.h
* @brief GDISP Graphic Driver subsystem board interface for the ILI9320 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 *) 0x60100000)) /* RS = 1 */
static __inline void GDISP_LLD(init_board)(void) {
/* FSMC setup for F1 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
/* set pin modes */
IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL);
const unsigned char FSMC_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
/* Bank1 NOR/SRAM control register configuration
* This is actually not needed as already set by default after reset */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
}
static __inline void GDISP_LLD(setpin_reset)(bool_t state) {
if(state)
palClearPad(GPIOE, GPIOE_TFT_RST);
else
palSetPad(GPIOE, GPIOE_TFT_RST);
}
static __inline void GDISP_LLD(write_index)(uint16_t reg) {
GDISP_REG = reg;
}
static __inline void GDISP_LLD(write_data)(uint16_t data) {
GDISP_RAM = data;
}
static __inline uint16_t GDISP_LLD(read_data)(void) {
return GDISP_RAM;
}
static __inline void GDISP_LLD(set_backlight)(uint8_t percent) {
if(percent == 100)
palClearPad(GPIOD, GPIOD_TFT_LIGHT);
else
palSetPad(GPIOD, GPIOD_TFT_LIGHT);
}
#endif /* GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,54 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9320/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the ILI9320 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef GDISP_LLD_CONFIG_H
#define GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "ILI9320"
#define GDISP_LLD(x) gdisp_lld_##x##_ILI9320
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS FALSE
#define GDISP_HARDWARE_SCROLL FALSE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,15 @@
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
d) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_example.h file as a basis.
Currently known boards are:
Olimex STM32-LCD
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/ILI9320/gdisp_lld.mk

View File

@ -0,0 +1,580 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9325/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the ILI9325 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_HY_STM32_100P)
#include "gdisp_lld_board_hy_stm32_100p.h"
#else
#include "gdisp_lld_board.h"
#endif
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/* This controller is only ever used with a 240 x 320 display */
#if defined(GDISP_SCREEN_HEIGHT)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_WIDTH
#endif
#define GDISP_SCREEN_WIDTH 240
#define GDISP_SCREEN_HEIGHT 320
#define GDISP_INITIAL_CONTRAST 50
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
uint32_t DISPLAY_CODE;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static __inline void lld_lcdDelay(uint16_t us) {
chThdSleepMicroseconds(us);
}
static __inline void lld_lcdWriteIndex(uint16_t index) {
GDISP_LLD(write_index)(index);
}
static __inline void lld_lcdWriteData(uint16_t data) {
GDISP_LLD(write_data)(data);
}
static __inline void lld_lcdWriteReg(uint16_t lcdReg, uint16_t lcdRegValue) {
GDISP_LLD(write_index)(lcdReg);
GDISP_LLD(write_data)(lcdRegValue);
}
static __inline uint16_t lld_lcdReadData(void) {
/* fix this! */
//return GDISP_LLD(read_data);
return GDISP_RAM;
}
static __inline uint16_t lld_lcdReadReg(uint16_t lcdReg) {
volatile uint16_t dummy;
GDISP_LLD(write_index)(lcdReg);
dummy = lld_lcdReadData();
(void)dummy;
return lld_lcdReadData();
}
static __inline void lld_lcdWriteStreamStart(void) {
lld_lcdWriteIndex(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++)
lld_lcdWriteData(buffer[i]);
}
static __inline void lld_lcdReadStreamStart(void) {
lld_lcdWriteIndex(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;
dummy = lld_lcdReadData();
(void)dummy;
for(i = 0; i < size; i++)
buffer[i] = lld_lcdReadData();
}
bool_t lld_gdisp_init(void) {
/* Initialise your display */
GDISP_LLD(init_board)();
/* Hardware reset */
GDISP_LLD(setpin_reset)(TRUE);
lld_lcdDelay(1000);
GDISP_LLD(setpin_reset)(FALSE);
lld_lcdDelay(1000);
// chinese code starts here
lld_lcdWriteReg(0x0000,0x0001);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0015,0x0030);
lld_lcdWriteReg(0x0011,0x0040);
lld_lcdWriteReg(0x0010,0x1628);
lld_lcdWriteReg(0x0012,0x0000);
lld_lcdWriteReg(0x0013,0x104d);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0012,0x0010);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0010,0x2620);
lld_lcdWriteReg(0x0013,0x344d); //304d
lld_lcdDelay(10);
lld_lcdWriteReg(0x0001,0x0100);
lld_lcdWriteReg(0x0002,0x0300);
lld_lcdWriteReg(0x0003,0x1038);//0x1030
lld_lcdWriteReg(0x0008,0x0604);
lld_lcdWriteReg(0x0009,0x0000);
lld_lcdWriteReg(0x000A,0x0008);
lld_lcdWriteReg(0x0041,0x0002);
lld_lcdWriteReg(0x0060,0x2700);
lld_lcdWriteReg(0x0061,0x0001);
lld_lcdWriteReg(0x0090,0x0182);
lld_lcdWriteReg(0x0093,0x0001);
lld_lcdWriteReg(0x00a3,0x0010);
lld_lcdDelay(10);
//################# void Gamma_Set(void) ####################//
lld_lcdWriteReg(0x30,0x0000);
lld_lcdWriteReg(0x31,0x0502);
lld_lcdWriteReg(0x32,0x0307);
lld_lcdWriteReg(0x33,0x0305);
lld_lcdWriteReg(0x34,0x0004);
lld_lcdWriteReg(0x35,0x0402);
lld_lcdWriteReg(0x36,0x0707);
lld_lcdWriteReg(0x37,0x0503);
lld_lcdWriteReg(0x38,0x1505);
lld_lcdWriteReg(0x39,0x1505);
lld_lcdDelay(10);
//################## void Display_ON(void) ####################//
lld_lcdWriteReg(0x0007,0x0001);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0007,0x0021);
lld_lcdWriteReg(0x0007,0x0023);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0007,0x0033);
lld_lcdDelay(10);
lld_lcdWriteReg(0x0007,0x0133);
// chinese code ends here
// Turn on the backlight
GDISP_LLD(set_backlight)(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
static void lld_lcdSetCursor(uint16_t x, uint16_t y) {
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0020, x);
lld_lcdWriteReg(0x0021, y);
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0020, y);
lld_lcdWriteReg(0x0021, x);
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x0020, x);
lld_lcdWriteReg(0x0021, y);
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x0020, y);
lld_lcdWriteReg(0x0021, x);
break;
}
}
static void lld_lcdSetViewPort(uint16_t x, uint16_t y, uint16_t cx, uint16_t cy) {
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0050, x);
lld_lcdWriteReg(0x0051, x + cx - 1);
lld_lcdWriteReg(0x0052, y);
lld_lcdWriteReg(0x0053, y + cy - 1);
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0050, y);
lld_lcdWriteReg(0x0051, y + cy - 1);
lld_lcdWriteReg(0x0052, x);
lld_lcdWriteReg(0x0053, x + cx - 1);
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x0050, x);
lld_lcdWriteReg(0x0051, x + cx - 1);
lld_lcdWriteReg(0x0052, y);
lld_lcdWriteReg(0x0053, y + cy - 1);
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x0050, y);
lld_lcdWriteReg(0x0051, y + cy - 1);
lld_lcdWriteReg(0x0052, x);
lld_lcdWriteReg(0x0053, x + cx - 1);
break;
}
lld_lcdSetCursor(x, y);
}
static __inline 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;
}
}
void lld_gdisp_draw_pixel(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);
}
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
void lld_gdisp_clear(color_t color) {
unsigned i;
lld_lcdSetCursor(0, 0);
lld_lcdWriteStreamStart();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
lld_lcdWriteData(color);
lld_lcdWriteStreamStop();
}
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
unsigned i, area;
area = cx*cy;
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
for(i = 0; i < area; i++)
lld_lcdWriteData(color);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
lld_lcdSetViewPort(x, y, cx, cy);
lld_lcdWriteStreamStart();
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
lld_lcdWriteData(*buffer++);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
color_t color;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
lld_lcdSetCursor(x, y);
lld_lcdWriteStreamStart();
color = lld_lcdReadData();
color = lld_lcdReadData();
lld_lcdWriteStreamStop();
return color;
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
coord_t row0, row1;
unsigned i, gap, abslines;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
abslines = lines < 0 ? -lines : lines;
if (abslines >= cy) {
abslines = cy;
gap = 0;
} else {
gap = cy - abslines;
for(i = 0; i < gap; i++) {
if(lines > 0) {
row0 = y + i + lines;
row1 = y + i;
} else {
row0 = (y - i - 1) + lines;
row1 = (y - i - 1);
}
/* read row0 into the buffer and then write at row1*/
lld_lcdSetViewPort(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();
}
}
/* fill the remaining gap */
lld_lcdSetViewPort(x, lines > 0 ? (y+gap) : y, cx, abslines);
lld_lcdWriteStreamStart();
gap = cx*abslines;
for(i = 0; i < gap; i++) lld_lcdWriteData(bgcolor);
lld_lcdWriteStreamStop();
lld_lcdResetViewPort();
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
void lld_gdisp_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_POWER:
if(GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
lld_lcdWriteReg(0x0007, 0x0000);
lld_lcdWriteReg(0x0010, 0x0000);
lld_lcdWriteReg(0x0011, 0x0000);
lld_lcdWriteReg(0x0012, 0x0000);
lld_lcdWriteReg(0x0013, 0x0000);
GDISP_LLD(set_backlight)(0);
break;
case powerOn:
//*************Power On sequence ******************//
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
lld_lcdWriteReg(0x0011, 0x0147); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0012, 0x013C); /* VREG1OUT voltage */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0013, 0x0E00); /* VDV[4:0] for VCOM amplitude */
lld_lcdWriteReg(0x0029, 0x0009); /* VCM[4:0] for VCOMH */
lld_lcdDelay(500);
lld_lcdWriteReg(0x0007, 0x0173); /* 262K color and display ON */
GDISP_LLD(set_backlight)(GDISP.Backlight);
if(GDISP.Powermode != powerSleep || GDISP.Powermode != powerDeepSleep)
lld_gdisp_init();
break;
case powerSleep:
lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x0002); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
GDISP_LLD(set_backlight)(0);
break;
case powerDeepSleep:
lld_lcdWriteReg(0x0007, 0x0000); /* display OFF */
lld_lcdWriteReg(0x0010, 0x0000); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
lld_lcdWriteReg(0x0011, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
lld_lcdWriteReg(0x0012, 0x0000); /* VREG1OUT voltage */
lld_lcdWriteReg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */
lld_lcdDelay(2000); /* Dis-charge capacitor power voltage */
lld_lcdWriteReg(0x0010, 0x0004); /* SAP, BT[3:0], APE, AP, DSTB, SLP */
GDISP_LLD(set_backlight)(0);
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
case GDISP_CONTROL_ORIENTATION:
if(GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
lld_lcdWriteReg(0x0001, 0x0100);
lld_lcdWriteReg(0x0003, 0x1038);
lld_lcdWriteReg(0x0060, 0x2700);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
lld_lcdWriteReg(0x0001, 0x0000);
lld_lcdWriteReg(0x0003, 0x1030);
lld_lcdWriteReg(0x0060, 0x2700);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
lld_lcdWriteReg(0x0001, 0x0000);
lld_lcdWriteReg(0x0003, 0x1038);
lld_lcdWriteReg(0x0060, 0xa700);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
lld_lcdWriteReg(0x0001, 0x0100);
lld_lcdWriteReg(0x0003, 0x1030);
lld_lcdWriteReg(0x0060, 0xA700);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
case GDISP_CONTROL_BACKLIGHT:
if((unsigned)value > 100) value = (void *)100;
GDISP_LLD(set_backlight)((unsigned)value);
GDISP.Backlight = (unsigned)value;
break;
default:
return;
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/ILI9325/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/ILI9325

View File

@ -0,0 +1,59 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9325/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the ILI9325 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef GDISP_LLD_BOARD_H
#define GDISP_LLD_BOARD_H
static __inline void GDISP_LLD(init_board)(void) {
#error "ILI9325: You must implement the init_board routine for your board"
}
static __inline void GDISP_LLD(setpin_reset)(bool_t state) {
#error "ILI9325: You must implement setpin_reset routine for your board"
}
static __inline void GDISP_LLD(write_index)(uint16_t data) {
#error "ILI9325: You must implement write_index routine for your board"
}
static __inline void GDISP_LLD(write_data)(uint16_t data) {
#error "ILI9325: You must implement write_data routine for your board"
}
static __inline uint16_t GDISP_LLD(read_data)(void) {
#error "ILI9325: You must implement read_data routine for your board"
}
/* if not available, just ignore the argument and return */
static __inline uint16_t GDISP_LLD(set_backlight)(uint8_t percentage) {
#error "ILI9325: You must implement set_backlight routine for your board"
}
#endif /* GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,96 @@
/*
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/>.
*/
/*
driver quickly hacked together from a chinese sourcecode that came
with the board and existing ili9320 code by Chris van Dongen (sjaak)
(sjaak2002 at msn.com)
Also added rotation for 180 and 270 degrees and minor tweaks to
setcursor
Added code comes without warranty and free bugs. Feel free to use
or misuse the added code :D
*/
/**
* @file drivers/gdisp/ILI9325/gdisp_lld_board_hy_stm32_100p.h
* @brief GDISP Graphic Driver subsystem board interface for the ILI9325 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 GDISP_LLD(init_board)(void) {
/* FSMC setup for F1 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
/* set pin modes */
/* IOBus busD = {GPIOD, PAL_WHOLE_PORT, 0};
IOBus busE = {GPIOE, PAL_WHOLE_PORT, 0};
palSetBusMode(&busD, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetBusMode(&busE, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
palSetPadMode(GPIOE, GPIOE_TFT_RST, PAL_MODE_OUTPUT_PUSHPULL);
palSetPadMode(GPIOD, GPIOD_TFT_LIGHT, PAL_MODE_OUTPUT_PUSHPULL); */
const unsigned char FSMC_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (6) | (10 << 8) | (10 << 16);
/* Bank1 NOR/SRAM control register configuration
* This is actually not needed as already set by default after reset */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
}
static __inline void GDISP_LLD(setpin_reset)(bool_t state) {
if(state)
palClearPad(GPIOE, GPIOE_TFT_RST);
else
palSetPad(GPIOE, GPIOE_TFT_RST);
}
static __inline void GDISP_LLD(write_index)(uint16_t reg) {
GDISP_REG = reg;
}
static __inline void GDISP_LLD(write_data)(uint16_t data) {
GDISP_RAM = data;
}
static __inline uint16_t GDISP_LLD(read_data)(void) {
return GDISP_RAM;
}
static __inline void GDISP_LLD(set_backlight)(uint8_t percent) {
percent=percent; // avoid a warning
}
#endif /* GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,54 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/ILI9325/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the ILI9325 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef GDISP_LLD_CONFIG_H
#define GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "ILI9325"
#define GDISP_LLD(x) gdisp_lld_##x##_ILI9325
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS FALSE
#define GDISP_HARDWARE_SCROLL FALSE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,15 @@
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
d) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_example.h file as a basis.
Currently known boards are:
HY_STM32_100p
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/ILI9325/gdisp_lld.mk

View File

@ -0,0 +1,81 @@
/*
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 GE12_H
#define GE12_H
// *************************************************************************************
// LCD Include File for Philips PCF8833 STN RGB- 132x132x3 Driver (GE12)
//
// Taken from Philips data sheet Feb 14, 2003
// *************************************************************************************
// Philips PCF8833 LCD controller command codes
#define NOP 0x00 // nop
#define SWRESET 0x01 // software reset
#define BSTROFF 0x02 // booster voltage OFF
#define BSTRON 0x03 // booster voltage ON
#define RDDIDIF 0x04 // read display identification
#define RDDST 0x09 // read display status
#define SLEEPIN 0x10 // sleep in
#define SLEEPOUT 0x11 // sleep out
#define PTLON 0x12 // partial display mode
#define NORON 0x13 // display normal mode
#define INVOFF 0x20 // inversion OFF
#define INVON 0x21 // inversion ON
#define DALO 0x22 // all pixel OFF
#define DAL 0x23 // all pixel ON
#define SETCON 0x25 // write contrast
#define DISPOFF 0x28 // display OFF
#define DISPON 0x29 // display ON
#define CASET 0x2A // column address set
#define PASET 0x2B // page address set
#define RAMWR 0x2C // memory write
#define RGBSET 0x2D // colour set
#define PTLAR 0x30 // partial area
#define VSCRDEF 0x33 // vertical scrolling definition
#define TEOFF 0x34 // test mode
#define TEON 0x35 // test mode
#define MADCTL 0x36 // memory access control
#define SEP 0x37 // vertical scrolling start address
#define IDMOFF 0x38 // idle mode OFF
#define IDMON 0x39 // idle mode ON
#define COLMOD 0x3A // interface pixel format
#define SETVOP 0xB0 // set Vop
#define BRS 0xB4 // bottom row swap
#define TRS 0xB6 // top row swap
#define DISCTR 0xB9 // display control
#define DOR 0xBA // data order
#define TCDFE 0xBD // enable/disable DF temperature compensation
#define TCVOPE 0xBF // enable/disable Vop temp comp
#define EC 0xC0 // internal or external oscillator
#define SETMUL 0xC2 // set multiplication factor
#define TCVOPAB 0xC3 // set TCVOP slopes A and B
#define TCVOPCD 0xC4 // set TCVOP slopes c and d
#define TCDF 0xC5 // set divider frequency
#define DF8COLOR 0xC6 // set divider frequency 8-color mode
#define SETBS 0xC7 // set bias system
#define RDTEMP 0xC8 // temperature read back
#define NLI 0xC9 // n-line inversion
#define RDID1 0xDA // read ID1
#define RDID2 0xDB // read ID2
#define RDID3 0xDC // read ID3
#endif /* GE12_H */

View File

@ -0,0 +1,528 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE12/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE12 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/* Controller definitions */
#include "GE12.h"
/* This controller is only ever used with a 132 x 132 display */
#if defined(GDISP_SCREEN_HEIGHT)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_WIDTH
#endif
#define GDISP_SCREEN_HEIGHT 132
#define GDISP_SCREEN_WIDTH 132
#define GDISP_INITIAL_CONTRAST 38
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_OLIMEX_SAM7_EX256)
#include "gdisp_lld_board_olimexsam7ex256.h"
#else
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#endif
// Some macros just to make reading the code easier
#define delayms(ms) chThdSleepMilliseconds(ms)
#define write_data2(d1, d2) { write_data(d1); write_data(d2); }
#define write_data3(d1, d2, d3) { write_data(d1); write_data(d2); write_data(d3); }
#define write_cmd1(cmd, d1) { write_cmd(cmd); write_data(d1); }
#define write_cmd2(cmd, d1, d2) { write_cmd(cmd); write_data2(d1, d2); }
#define write_cmd3(cmd, d1, d2, d3) { write_cmd(cmd); write_data3(d1, d2, d3); }
// A very common thing to do.
// An inline function has been used here incase the parameters have side effects with the internal calculations.
static __inline void setviewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
write_cmd2(CASET, x, x+cx-1); // Column address set
write_cmd2(PASET, y, y+cy-1); // Page address set
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t lld_gdisp_init(void) {
/* Initialise your display */
init_board();
// Hardware reset
setpin_reset(TRUE);
delayms(20);
setpin_reset(FALSE);
delayms(20);
// Get the bus for the following initialisation commands
acquire_bus();
// UNTESTED
#if 1
write_cmd(SLEEPOUT); // Sleep out
write_cmd(INVON); // Inversion on: seems to be required for this controller
write_cmd1(COLMOD, 0x03); // Color Interface Pixel Format - 0x03 = 12 bits-per-pixel
write_cmd1(MADCTL, 0xC8); // Memory access controler - 0xC0 = mirror x and y, reverse rgb
write_cmd1(SETCON, GDISP_INITIAL_CONTRAST); // Write contrast
delayms(20);
write_cmd(DISPON); // Display On
#else
// Alternative
write_cmd(SOFTRST); // Software Reset
delayms(20);
write_cmd(INITESC); // Initial escape
delayms(20);
write_cmd1(REFSET, 0x00); // Refresh set
write_cmd(DISPCTRL); // Set Display control - really 7 bytes of data
write_data(128); // Set the lenght of one selection term
write_data(128); // Set N inversion -> no N inversion
write_data(134); // Set frame frequence and bias rate -> 2 devision of frequency and 1/8 bias, 1/67 duty, 96x67 size
write_data(84); // Set duty parameter
write_data(69); // Set duty parameter
write_data(82); // Set duty parameter
write_data(67); // Set duty parameter
write_cmd(GRAYSCALE0); // Grey scale 0 position set - really 15 bytes of data
write_data(1); // GCP1 - gray lavel to be output when the RAM data is "0001"
write_data(2); // GCP2 - gray lavel to be output when the RAM data is "0010"
write_data(4); // GCP3 - gray lavel to be output when the RAM data is "0011"
write_data(8); // GCP4 - gray lavel to be output when the RAM data is "0100"
write_data(16); // GCP5 - gray lavel to be output when the RAM data is "0101"
write_data(30); // GCP6 - gray lavel to be output when the RAM data is "0110"
write_data(40); // GCP7 - gray lavel to be output when the RAM data is "0111"
write_data(50); // GCP8 - gray lavel to be output when the RAM data is "1000"
write_data(60); // GCP9 - gray lavel to be output when the RAM data is "1001"
write_data(70); // GCP10 - gray lavel to be output when the RAM data is "1010"
write_data(80); // GCP11 - gray lavel to be output when the RAM data is "1011"
write_data(90); // GCP12 - gray lavel to be output when the RAM data is "1100"
write_data(100); // GCP13 - gray lavel to be output when the RAM data is "1101"
write_data(110); // GCP14 - gray lavel to be output when the RAM data is "1110"
write_data(127); // GCP15 - gray lavel to be output when the RAM data is "1111"
write_cmd1(GAMMA, 0x01); // Gamma curve set - select gray scale - GRAYSCALE 0 or GREYSCALE 1 - Select grey scale 0
write_cmd1(COMMONDRV, 0x00); // Command driver output - Set COM1-COM41 side come first, normal mod
write_cmd(NORMALMODE); // Set Normal mode (my)
// write_cmd(INVERSIONOFF); // Inversion off
write_cmd2(COLADDRSET, 0, 131); // Column address set
write_cmd2(PAGEADDRSET, 0, 131); // Page address set
write_cmd1(ACCESSCTRL, 0x40); // Memory access controler - 0x40 horizontal
// write_data(0x20); // vertical
write_cmd1(PWRCTRL, 0x04); // Power control - Internal resistance, V1OUT -> high power mode, oscilator devision rate
write_cmd(SLEEPOUT); // Sleep out
write_cmd(VOLTCTRL); // Voltage control - voltage control and write contrast define LCD electronic volume
// write_data(0x7f); // full voltage control
// write_data(0x03); // must be "1"
write_cmd1(CONTRAST, GDISP_INITIAL_CONTRAST); // Write contrast
delayms(20);
write_cmd(TEMPGRADIENT); // Temperature gradient - really 14 bytes of data
for(i=0; i<14; i++)
write_data(0);
write_cmd(BOOSTVON); // Booster voltage ON
write_cmd(DISPLAYON); // Finally - Display On
#endif
// Release the bus
release_bus();
/* Turn on the back-light */
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure to match */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(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
acquire_bus();
setviewport(x, y, 1, 1);
write_cmd3(RAMWR, 0, (color>>8) & 0x0F, color & 0xFF);
release_bus();
}
/* ---- Optional Routines ---- */
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
unsigned i, tuples;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
tuples = (cx*cy+1)/2; // With an odd sized area we over-print by one pixel.
// This extra pixel is ignored by the controller.
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
for(i=0; i < tuples; i++)
write_data3(((color >> 4) & 0xFF), (((color << 4) & 0xF0)|((color >> 8) & 0x0F)), (color & 0xFF));
release_bus();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy, lg;
color_t c1, c2;
#if GDISP_PACKED_PIXELS
coord_t pos;
const uint8_t *p;
#endif
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
/* What are our end points */
endx = srcx + cx;
endy = y + cy;
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
#if !GDISP_PACKED_PIXELS
// Although this controller uses packed pixels we support unpacked pixel
// formats in this blit by packing the data as we feed it to the controller.
lg = srccx - cx;
buffer += srcy * srccx + srcx;
x = srcx;
while (1) {
/* Get a pixel */
c1 = *buffer++;
if (++x >= endx) {
if (++y >= endy) {
/* Odd pixel at end */
write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
break;
}
x = srcx;
buffer += lg;
}
/* Get the next pixel */
c2 = *buffer++;
write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
if (++x >= endx) {
if (++y >= endy)
break;
x = srcx;
buffer += lg;
}
}
#else
// Although this controller uses packed pixels, we may have to feed it into
// the controller with different packing to the source bitmap
#if !GDISP_PACKED_LINES
srccx = (srccx + 1) & ~1;
#endif
pos = srcy*srccx;
lg = (srccx - cx)/2*3;
p = ((const uint8_t *)buffer) + ((pos+srcx)/2 * 3);
x = srcx;
while (1) {
/* Get a pixel */
switch((pos+x)&1) {
case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
}
if (++x >= endx) {
if (++y >= endy) {
/* Odd pixel at end */
write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
break;
}
x = srcx;
p += lg;
pos += srccx;
}
/* Get the next pixel */
switch((pos+x)&1) {
case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
}
write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
if (++x >= endx) {
if (++y >= endy)
break;
x = srcx;
p += lg;
pos += srccx;
}
}
#endif
release_bus();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD)
/**
* @brief Get the color of a particular pixel.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The start of the text
*
* @notapi
*/
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
/* NOT IMPLEMENTED */
/* Some board hardware might support this in the future.
* The Olimex board doesn't.
*/
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL)
/**
* @brief Scroll vertically a section of the screen.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
/* NOT IMPLEMENTED */
/* The hardware seems capable of doing this.
* It is just really complex so we leave it out for now.
*/
}
#endif
#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void lld_gdisp_control(unsigned what, void *value) {
/* The hardware is capable of supporting...
* GDISP_CONTROL_POWER - not implemented yet
* GDISP_CONTROL_ORIENTATION - not implemented yet
* GDISP_CONTROL_BACKLIGHT - supported (the OlimexSAM7EX256 board.h currently only implements off/on although PWM is supported by the hardware)
* GDISP_CONTROL_CONTRAST - supported
*/
switch(what) {
#if 0
// NOT IMPLEMENTED YET
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
// Code here
break;
case powerOn:
// Code here
/* You may need this ---
* if (GDISP.Powermode != powerSleep)
* lld_gdisp_init();
*/
break;
case powerSleep:
/* Code here */
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
#endif
#if 0
// NOT IMPLEMENTED YET
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
// WriteSpiData(0x48); // no mirror Y (temporary to satisfy Olimex bmptoarray utility)
// WriteSpiData(0xC8); // restore to (mirror x and y, reverse rgb)
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
// Code here
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
// Code here
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
// Code here
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
// Code here
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
#endif
case GDISP_CONTROL_BACKLIGHT:
if ((unsigned)value > 100) value = (void *)100;
set_backlight((unsigned)value);
GDISP.Backlight = (unsigned)value;
return;
case GDISP_CONTROL_CONTRAST:
if ((unsigned)value > 100) value = (void *)100;
acquire_bus();
write_cmd1(CONTRAST,(unsigned)value);
release_bus();
GDISP.Contrast = (unsigned)value;
return;
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE12/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/Nokia6610GE12

View File

@ -0,0 +1,135 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE12/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE12 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
/**
* @brief Initialise the board for the display.
* @notes Performs the following functions:
* 1. initialise the spi port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
*
* @notapi
*/
static __inline void init_board(void) {
/* Code here */
#error "gdispNokia6610GE12: 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 "gdispNokia6610GE12: You must supply a definition for setpin_reset for your board"
}
/**
* @brief Set the lcd back-light level.
* @note For now 0% turns the backlight off, anything else the backlight is on.
* While the hardware supports PWM backlight control, we are not using it
* yet.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
/* Code here */
#error "gdispNokia6610GE12: 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) {
/* Code here */
#error "gdispNokia6610GE12: 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) {
/* Code here */
#error "gdispNokia6610GE12: You must supply a definition for release_bus for your board"
}
/**
* @brief Send an 8 bit command to the lcd.
*
* @param[in] cmd The command to send
*
* @notapi
*/
static __inline void write_cmd(uint16_t cmd) {
/* Code here */
#error "gdispNokia6610GE12: You must supply a definition for write_cmd for your board"
}
/**
* @brief Send an 8 bit data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
/* Code here */
#error "gdispNokia6610GE12: 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 "gdispNokia6610GE12: You must supply a definition for read_data for your board"
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,196 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE12/gdisp_lld_board_olimexsam7ex256.h
* @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
// ******************************************************
// Pointers to AT91SAM7X256 peripheral data structures
// ******************************************************
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
/**
* @brief Initialise the board for the display.
* @notes Performs the following functions:
* 1. initialise the spi port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
*
* @notapi
*/
static __inline void init_board(void) {
// *********************************************************************************************
// InitSpi( )
//
// Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
//
// I/O ports used: PA2 = LCD Reset (set to low to reset)
// PA12 = LCD chip select (set to low to select the LCD chip)
// PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
// PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// PA18 = SPI0_SPCK Serial Clock (to LCD slave)
// PB20 = backlight control (normally PWM control, 1 = full on)
//
// *********************************************************************************************}
/* This code should really use the ChibiOS driver for these functions */
// Pin for backlight
pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
// Reset pin
pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
// CS pin - this seems to be ignored
// pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
// pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
// Init SPI0
// Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
// BIT12 = PA12 -> SPI0_NPCS0 chip select
// BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
// BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
pPIOA->PIO_BSR = 0;
//enable the clock of SPI
pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
// Fixed mode
pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset
pSPI->SPI_CR = 0x01; //SPI Enable
//pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
//pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above
}
/**
* @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) {
if (state)
palClearPad(IOPORT1, PIOA_LCD_RESET);
else
palSetPad(IOPORT1, PIOA_LCD_RESET);
}
/**
* @brief Set the lcd back-light level.
* @note For now 0% turns the backlight off, anything else the backlight is on.
* While the hardware supports PWM backlight control, we are not using it
* yet.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
if (percent)
palSetPad(IOPORT2, PIOB_LCD_BL);
else
palClearPad(IOPORT2, PIOB_LCD_BL);
}
/**
* @brief Take exclusive control of the bus
*
* @notapi
*/
static __inline void acquire_bus(void) {
/* Nothing to do for this board as the LCD is the only device on the SPI port */
}
/**
* @brief Release exclusive control of the bus
*
* @notapi
*/
static __inline void release_bus(void) {
// Nothing to do for this board as the LCD is the only device on the SPI port
}
/**
* @brief Send an 8 bit command to the lcd.
*
* @param[in] cmd The command to send
*
* @notapi
*/
static __inline void write_cmd(uint16_t cmd) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the command
pSPI->SPI_TDR = cmd & 0xFF;
}
/**
* @brief Send an 8 bit data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the data
pSPI->SPI_TDR = data | 0x0100;
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
/**
* @brief Read data from the lcd.
*
* @return The data from the lcd
*
* @notapi
*/
static __inline uint16_t read_data(void) {
#error "gdispNokia6610GE12: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board"
return 0;
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,58 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE12/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the Nokia6610 GE12 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "Nokia6610GE12"
#define GDISP_LLD(x) gdisp_lld_##x##_Nokia6610GE12
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
/* This driver supports both packed and unpacked pixel formats and line formats.
* By default we leave these as FALSE.
*/
#define GDISP_PACKED_PIXELS FALSE
#define GDISP_PACKED_LINES FALSE
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,15 @@
This driver is for the Nokia6610 Philips (GE12) controller
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) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_example.h file as a basis.
Currently known boards are:
Olimex SAM7-EX256
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/Nokia6610GE12/gdisp_lld.mk

View File

@ -0,0 +1,67 @@
/*
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 GE8_H
#define GE8_H
// *****************************************************************************
// Include file for Epson S1D15G00 LCD Controller (GE8)
//
// Author: James P Lynch August 30, 2007
// Modified for GDISP: Andrew Hannam August 2, 2012
//
// *****************************************************************************
#define DISON 0xAF // Display on
#define DISOFF 0xAE // Display off
#define DISNOR 0xA6 // Normal display
#define DISINV 0xA7 // Inverse display
#define COMSCN 0xBB // Common scan direction
#define DISCTL 0xCA // Display control
#define SLPIN 0x95 // Sleep in
#define SLPOUT 0x94 // Sleep out
#define PASET 0x75 // Page address set
#define CASET 0x15 // Column address set
#define DATCTL 0xBC // Data scan direction, etc.
#define RGBSET8 0xCE // 256-color position set
#define RAMWR 0x5C // Writing to memory
#define RAMRD 0x5D // Reading from memory
#define PTLIN 0xA8 // Partial display in
#define PTLOUT 0xA9 // Partial display out
#define RMWIN 0xE0 // Read and modify write
#define RMWOUT 0xEE // End
#define ASCSET 0xAA // Area scroll set
#define SCSTART 0xAB // Scroll start set
#define OSCON 0xD1 // Internal oscillation on
#define OSCOFF 0xD2 // Internal oscillation off
#define PWRCTR 0x20 // Power control
#define VOLCTR 0x81 // Electronic volume control
#define VOLUP 0xD6 // Increment electronic control by 1
#define VOLDOWN 0xD7 // Decrement electronic control by 1
#define TMPGRD 0x82 // Temperature gradient set
#define EPCTIN 0xCD // Control EEPROM
#define EPCOUT 0xCC // Cancel EEPROM control
#define EPMWR 0xFC // Write into EEPROM
#define EPMRD 0xFD // Read from EEPROM
#define EPSRRD1 0x7C // Read register 1
#define EPSRRD2 0x7D // Read register 2
#define NOP 0x25 // NOP instruction
#endif /* GE8_H */

View File

@ -0,0 +1,483 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE8/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the Nokia6610 GE8 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#include "GE8.h"
/* This controller is only ever used with a 132 x 132 display */
#if defined(GDISP_SCREEN_HEIGHT)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GDISP_SCREEN_WIDTH
#endif
#define GDISP_SCREEN_HEIGHT 132
#define GDISP_SCREEN_WIDTH 132
#define GDISP_INITIAL_CONTRAST 38
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_OLIMEX_SAM7_EX256)
#include "gdisp_lld_board_olimexsam7ex256.h"
#else
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#endif
// Some macros just to make reading the code easier
#define delayms(ms) chThdSleepMilliseconds(ms)
#define write_data2(d1, d2) { write_data(d1); write_data(d2); }
#define write_data3(d1, d2, d3) { write_data(d1); write_data(d2); write_data(d3); }
#define write_cmd1(cmd, d1) { write_cmd(cmd); write_data(d1); }
#define write_cmd2(cmd, d1, d2) { write_cmd(cmd); write_data2(d1, d2); }
#define write_cmd3(cmd, d1, d2, d3) { write_cmd(cmd); write_data3(d1, d2, d3); }
// A very common thing to do.
// An inline function has been used here incase the parameters have side effects with the internal calculations.
static __inline void setviewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
write_cmd2(CASET, x, x+cx-1); // Column address set
write_cmd2(PASET, y, y+cy-1); // Page address set
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t lld_gdisp_init(void) {
/* Initialise your display */
init_board();
// Hardware reset
setpin_reset(TRUE);
delayms(20);
setpin_reset(FALSE);
delayms(20);
// Get the bus for the following initialisation commands
acquire_bus();
write_cmd3(DISCTL, 0x00, 0x20, 0x00); // Display control
// P1: 0x00 = 2 divisions, switching period=8 (default)
// P2: 0x20 = nlines/4 - 1 = 132/4 - 1 = 32)
// P3: 0x00 = no inversely highlighted lines
write_cmd1(COMSCN, 0x01); // COM scan P1: 0x01 = Scan 1->80, 160<-81
write_cmd(OSCON); // Internal oscilator ON
write_cmd(SLPOUT); // Sleep out
write_cmd1(PWRCTR, 0x0F); // Power control - reference voltage regulator on, circuit voltage follower on, BOOST ON
write_cmd3(DATCTL, 0x48, 0x00, 0x02); // Data control
// P1: 0x01 = page address inverted, column address normal, address scan in column direction
// P2: 0x00 = RGB sequence (default value)
// P3: 0x02 = Grayscale -> 16 (selects 12-bit color, type A)
write_cmd2(VOLCTR, GDISP_INITIAL_CONTRAST, 0x03); // Voltage control (contrast setting)
// P1 = Contrast
// P2 = 3 resistance ratio (only value that works)
delayms(100); // allow power supply to stabilize
write_cmd(DISON); // Turn on the display
// Release the bus
release_bus();
/* Turn on the back-light */
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure to match */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(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
acquire_bus();
setviewport(x, y, 1, 1);
write_cmd3(RAMWR, 0, (color>>8) & 0x0F, color & 0xFF);
release_bus();
}
/* ---- Optional Routines ---- */
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
unsigned i, tuples;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
tuples = (cx*cy+1)/2; // With an odd sized area we over-print by one pixel.
// This extra pixel is ignored by the controller.
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
for(i=0; i < tuples; i++)
write_data3(((color >> 4) & 0xFF), (((color << 4) & 0xF0)|((color >> 8) & 0x0F)), (color & 0xFF));
release_bus();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy, lg;
color_t c1, c2;
#if GDISP_PACKED_PIXELS
coord_t pos;
const uint8_t *p;
#endif
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
/* What are our end points */
endx = srcx + cx;
endy = y + cy;
acquire_bus();
setviewport(x, y, cx, cy);
write_cmd(RAMWR);
#if !GDISP_PACKED_PIXELS
// Although this controller uses packed pixels we support unpacked pixel
// formats in this blit by packing the data as we feed it to the controller.
lg = srccx - cx;
buffer += srcy * srccx + srcx;
x = srcx;
while (1) {
/* Get a pixel */
c1 = *buffer++;
if (++x >= endx) {
if (++y >= endy) {
/* Odd pixel at end */
write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
break;
}
x = srcx;
buffer += lg;
}
/* Get the next pixel */
c2 = *buffer++;
write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
if (++x >= endx) {
if (++y >= endy)
break;
x = srcx;
buffer += lg;
}
}
#else
// Although this controller uses packed pixels, we may have to feed it into
// the controller with different packing to the source bitmap
#if !GDISP_PACKED_LINES
srccx = (srccx + 1) & ~1;
#endif
pos = srcy*srccx;
lg = (srccx - cx)/2*3;
p = ((const uint8_t *)buffer) + ((pos+srcx)/2 * 3);
x = srcx;
while (1) {
/* Get a pixel */
switch((pos+x)&1) {
case 0: c1 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
case 1: c1 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
}
if (++x >= endx) {
if (++y >= endy) {
/* Odd pixel at end */
write_data3(0, ((c1 >> 8) & 0x0F), (c1 & 0xFF));
break;
}
x = srcx;
p += lg;
pos += srccx;
}
/* Get the next pixel */
switch((pos+x)&1) {
case 0: c2 = (((color_t)p[0]) << 4)|(((color_t)p[1])>>4); break;
case 1: c2 = (((color_t)p[1]&0x0F) << 8)|((color_t)p[1]); break;
}
write_data3(((c1 >> 4) & 0xFF), (((c1 << 4) & 0xF0)|((c2 >> 8) & 0x0F)), (c2 & 0xFF));
if (++x >= endx) {
if (++y >= endy)
break;
x = srcx;
p += lg;
pos += srccx;
}
}
#endif
release_bus();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD)
/**
* @brief Get the color of a particular pixel.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The start of the text
*
* @notapi
*/
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
/* NOT IMPLEMENTED */
/* Some board hardware might support this in the future.
* The Olimex board doesn't.
*/
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL)
/**
* @brief Scroll vertically a section of the screen.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
/* NOT IMPLEMENTED */
/* The hardware seems capable of doing this.
* It is just really complex so we leave it out for now.
*/
}
#endif
#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void lld_gdisp_control(unsigned what, void *value) {
/* The hardware is capable of supporting...
* GDISP_CONTROL_POWER - not implemented yet
* GDISP_CONTROL_ORIENTATION - not implemented yet
* GDISP_CONTROL_BACKLIGHT - supported (the OlimexSAM7EX256 board.h currently only implements off/on although PWM is supported by the hardware)
* GDISP_CONTROL_CONTRAST - supported
*/
switch(what) {
#if 0
// NOT IMPLEMENTED YET
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
// Code here
break;
case powerOn:
// Code here
/* You may need this ---
* if (GDISP.Powermode != powerSleep)
* lld_gdisp_init();
*/
break;
case powerSleep:
/* Code here */
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
#endif
#if 0
// NOT IMPLEMENTED YET
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
// WriteSpiData(0x48); // no mirror Y (temporary to satisfy Olimex bmptoarray utility)
// WriteSpiData(0xC8); // restore to (mirror x and y, reverse rgb)
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
// Code here
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
// Code here
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
// Code here
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
// Code here
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
#endif
case GDISP_CONTROL_BACKLIGHT:
if ((unsigned)value > 100) value = (void *)100;
set_backlight((unsigned)value);
GDISP.Backlight = (unsigned)value;
return;
case GDISP_CONTROL_CONTRAST:
if ((unsigned)value > 100) value = (void *)100;
acquire_bus();
write_cmd2(VOLCTR, (unsigned)value, 0x03);
release_bus();
GDISP.Contrast = (unsigned)value;
return;
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/Nokia6610GE8/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/Nokia6610GE8

View File

@ -0,0 +1,135 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the Nokia6610 GE8 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
/**
* @brief Initialise the board for the display.
* @notes Performs the following functions:
* 1. initialise the spi port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
*
* @notapi
*/
static __inline void init_board(void) {
/* Code here */
#error "gdispNokia6610GE8: 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 "gdispNokia6610GE8: You must supply a definition for setpin_reset for your board"
}
/**
* @brief Set the lcd back-light level.
* @note For now 0% turns the backlight off, anything else the backlight is on.
* While the hardware supports PWM backlight control, we are not using it
* yet.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
/* Code here */
#error "gdispNokia6610GE8: 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) {
/* Code here */
#error "gdispNokia6610GE8: 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) {
/* Code here */
#error "gdispNokia6610GE8: You must supply a definition for release_bus for your board"
}
/**
* @brief Send an 8 bit command to the lcd.
*
* @param[in] cmd The command to send
*
* @notapi
*/
static __inline void write_cmd(uint16_t cmd) {
/* Code here */
#error "gdispNokia6610GE8: You must supply a definition for write_cmd for your board"
}
/**
* @brief Send an 8 bit data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
/* Code here */
#error "gdispNokia6610GE8: 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 "gdispNokia6610GE8: You must supply a definition for read_data for your board"
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,196 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE8/gdisp_lld_board_olimexsam7ex256.h
* @brief GDISP Graphic Driver subsystem board interface for the Olimex SAM7-EX256 board.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
// ******************************************************
// Pointers to AT91SAM7X256 peripheral data structures
// ******************************************************
volatile AT91PS_PIO pPIOA = AT91C_BASE_PIOA;
volatile AT91PS_PIO pPIOB = AT91C_BASE_PIOB;
volatile AT91PS_SPI pSPI = AT91C_BASE_SPI0;
volatile AT91PS_PMC pPMC = AT91C_BASE_PMC;
volatile AT91PS_PDC pPDC = AT91C_BASE_PDC_SPI0;
/**
* @brief Initialise the board for the display.
* @notes Performs the following functions:
* 1. initialise the spi port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
*
* @notapi
*/
static __inline void init_board(void) {
// *********************************************************************************************
// InitSpi( )
//
// Sets up SPI channel 0 for communications to Nokia 6610 LCD Display
//
// I/O ports used: PA2 = LCD Reset (set to low to reset)
// PA12 = LCD chip select (set to low to select the LCD chip)
// PA16 = SPI0_MISO Master In - Slave Out (not used in LCD interface)
// PA17 = SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// PA18 = SPI0_SPCK Serial Clock (to LCD slave)
// PB20 = backlight control (normally PWM control, 1 = full on)
//
// *********************************************************************************************}
/* This code should really use the ChibiOS driver for these functions */
// Pin for backlight
pPIOB->PIO_CODR = PIOB_LCD_BL_MASK; // Set PB20 to LOW
pPIOB->PIO_OER = PIOB_LCD_BL_MASK; // Configure PB20 as output
// Reset pin
pPIOA->PIO_SODR = PIOA_LCD_RESET_MASK; // Set PA2 to HIGH
pPIOA->PIO_OER = PIOA_LCD_RESET_MASK; // Configure PA2 as output
// CS pin - this seems to be ignored
// pPIOA->PIO_SODR = 1<<12; // Set PA2 to HIGH
// pPIOA->PIO_OER = 1<<12; // Configure PA2 as output
// Init SPI0
// Disable the following pins from PIO control (will be used instead by the SPI0 peripheral)
// BIT12 = PA12 -> SPI0_NPCS0 chip select
// BIT16 = PA16 -> SPI0_MISO Master In - Slave Out (not used in LCD interface)
// BIT17 = PA17 -> SPI0_MOSI Master Out - Slave In pin (Serial Data to LCD slave)
// BIT18 = PA18 -> SPI0_SPCK Serial Clock (to LCD slave)
pPIOA->PIO_PDR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
pPIOA->PIO_ASR = (1<<12) | (1<<16) | (1<<17) | (1<<18);
pPIOA->PIO_BSR = 0;
//enable the clock of SPI
pPMC->PMC_PCER = 1 << AT91C_ID_SPI0;
// Fixed mode
pSPI->SPI_CR = 0x81; //SPI Enable, Sowtware reset
pSPI->SPI_CR = 0x01; //SPI Enable
//pSPI->SPI_MR = 0xE0019; //Master mode, fixed select, disable decoder, FDIV=1 (MCK), PCS=1110
pSPI->SPI_MR = 0xE0011; //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
//pSPI->SPI_CSR[0] = 0x01010C11; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/32*12 = 125kHz
pSPI->SPI_CSR[0] = 0x01010311; //9bit, CPOL=1, ClockPhase=0, SCLK = 48Mhz/8 = 6MHz if using commented MR line above
}
/**
* @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) {
if (state)
palClearPad(IOPORT1, PIOA_LCD_RESET);
else
palSetPad(IOPORT1, PIOA_LCD_RESET);
}
/**
* @brief Set the lcd back-light level.
* @note For now 0% turns the backlight off, anything else the backlight is on.
* While the hardware supports PWM backlight control, we are not using it
* yet.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
if (percent)
palSetPad(IOPORT2, PIOB_LCD_BL);
else
palClearPad(IOPORT2, PIOB_LCD_BL);
}
/**
* @brief Take exclusive control of the bus
*
* @notapi
*/
static __inline void acquire_bus(void) {
/* Nothing to do for this board as the LCD is the only device on the SPI port */
}
/**
* @brief Release exclusive control of the bus
*
* @notapi
*/
static __inline void release_bus(void) {
// Nothing to do for this board as the LCD is the only device on the SPI port
}
/**
* @brief Send an 8 bit command to the lcd.
*
* @param[in] cmd The command to send
*
* @notapi
*/
static __inline void write_cmd(uint16_t cmd) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the command
pSPI->SPI_TDR = cmd & 0xFF;
}
/**
* @brief Send an 8 bit data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
// wait for the previous transfer to complete
while((pSPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
// send the data
pSPI->SPI_TDR = data | 0x0100;
}
#if GDISP_HARDWARE_READPIXEL || GDISP_HARDWARE_SCROLL || defined(__DOXYGEN__)
/**
* @brief Read data from the lcd.
*
* @return The data from the lcd
*
* @notapi
*/
static __inline uint16_t read_data(void) {
#error "gdispNokia6610GE8: GDISP_HARDWARE_READPIXEL and GDISP_HARDWARE_SCROLL are not supported on this board"
return 0;
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,58 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/Nokia6610GE8/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the Nokia6610 GE8 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "Nokia6610GE8"
#define GDISP_LLD(x) gdisp_lld_##x##_Nokia6610GE8
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB444
/* This driver supports both packed and unpacked pixel formats and line formats.
* By default we leave these as FALSE.
*/
#define GDISP_PACKED_PIXELS FALSE
#define GDISP_PACKED_LINES FALSE
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,15 @@
This driver is for the Nokia6610 Epson (GE8) controller
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) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_example.h file as a basis.
Currently known boards are:
Olimex SAM7-EX256
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/Nokia6610GE8/gdisp_lld.mk

View File

@ -0,0 +1,571 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/S6D1121/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the S6d1121 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#if defined(GDISP_SCREEN_HEIGHT)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#undef GISP_SCREEN_HEIGHT
#endif
#if defined(GDISP_SCREEN_WIDTH)
#warning "GDISP: This low level driver does not support setting a screen size. It is being ignored."
#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 local definitions. */
/*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif 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;
}
}
bool_t lld_gdisp_init(void) {
/* initialize the hardware */
init_board();
/* Hardware reset */
setpin_reset(TRUE);
delayms(20);
setpin_reset(TRUE);
delayms(20);
/* Get the bus for the following initialisation commands */
acquire_bus();
write_reg(0x11,0x2004);
write_reg(0x13,0xCC00);
write_reg(0x15,0x2600);
write_reg(0x14,0x252A);
write_reg(0x12,0x0033);
write_reg(0x13,0xCC04);
delayms(1);
write_reg(0x13,0xCC06);
delayms(1);
write_reg(0x13,0xCC4F);
delayms(1);
write_reg(0x13,0x674F);
write_reg(0x11,0x2003);
delayms(1);
// Gamma Setting
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);
write_reg(0x16,0x0007);
write_reg(0x02,0x0013);
write_reg(0x03,0x0003);
write_reg(0x01,0x0127);
delayms(1);
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);
delayms(1);
write_reg(0x07,0x0053);
write_reg(0x79,0x0000);
reset_viewport();
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Now initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = 100;
GDISP.Contrast = 50;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(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
acquire_bus();
set_cursor(x, y);
write_reg(0x0022, color);
release_bus();
}
/* ---- Optional Routines ---- */
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
/**
* @brief Clear the display.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_clear(color_t color) {
unsigned i;
acquire_bus();
set_cursor(0, 0);
stream_start();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
write_data(color);
stream_stop();
release_bus();
}
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
unsigned i, area;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
area = cx*cy;
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
for(i = 0; i < area; i++)
write_data(color);
stream_stop();
reset_viewport();
release_bus();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
write_data(*buffer++);
stream_stop();
reset_viewport();
release_bus();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
/**
* @brief Get the color of a particular pixel.
* @note Optional.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The start of the text
*
* @notapi
*/
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
/* This routine is marked "DO NOT USE" in the original
* GLCD driver. We just keep our GDISP_HARDWARE_READPIXEL
* turned off for now.
*/
color_t color;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
aquire_bus();
set_cursor(x, y);
stream_start();
color = lld_lcdReadData();
color = lld_lcdReadData();
stream_stop();
release_bus();
return color;
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
/**
* @brief Scroll vertically a section of the screen.
* @note Optional.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
/* This is marked as "TODO: Test this" in the original GLCD driver.
* For now we just leave the GDISP_HARDWARE_SCROLL off.
*/
static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
coord_t row0, row1;
unsigned i, gap, abslines;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
abslines = lines < 0 ? -lines : lines;
acquire_bus();
if (abslines >= cy) {
abslines = cy;
gap = 0;
} else {
gap = cy - abslines;
for(i = 0; i < gap; i++) {
if(lines > 0) {
row0 = y + i + lines;
row1 = y + i;
} else {
row0 = (y - i - 1) + lines;
row1 = (y - i - 1);
}
/* read row0 into the buffer and then write at row1*/
set_viewport(x, row0, cx, 1);
lld_lcdReadStreamStart();
lld_lcdReadStream(buf, cx);
lld_lcdReadStreamStop();
set_viewport(x, row1, cx, 1);
stream_start();
write_data(buf, cx);
stream_stop();
}
}
/* fill the remaining gap */
set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines);
stream_start();
gap = cx*abslines;
for(i = 0; i < gap; i++) write_data(bgcolor);
stream_stop();
reset_viewport();
release_bus();
}
#endif
#if GDISP_HARDWARE_CONTROL || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void lld_gdisp_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
/* Code here */
/* break; */
case powerOn:
/* Code here */
/* You may need this ---
if (GDISP.Powermode != powerSleep)
GDISP_LLD(init();
*/
/* break; */
case powerSleep:
/* Code here */
/* break; */
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
write_reg(0x0001,0x0127);
write_reg(0x03, 0b0011);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
write_reg(0x0001,0x0027);
write_reg(0x0003, 0b1011);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
write_reg(0x0001,0x0127);
write_reg(0x0003, 0b0000);
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
write_reg(0x0001,0x0027);
write_reg(0x0003, 0b1000);
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
/*
case GDISP_CONTROL_BACKLIGHT:
case GDISP_CONTROL_CONTRAST:
*/
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/S6D1121

View File

@ -0,0 +1,125 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/S6D1121/gdisp_lld_board_example.h
* @brief GDISP Graphic Driver subsystem board interface for the S6D1121 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/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/>.
*/
/**
* @file drivers/gdisp/S6D1121/gdisp_lld_board_olimex_e407.h
* @brief GDISP Graphic Driver subsystem board interface for the S6D1121 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

@ -0,0 +1,54 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/S6D1121/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the S6D1121 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "S6D1121"
#define GDISP_LLD(x) gdisp_lld_##x##_S6D1121
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
#define GDISP_HARDWARE_PIXELREAD FALSE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,9 @@
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
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/S6D1121/gdisp_lld.mk

View File

@ -0,0 +1,583 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1289/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for the SSD1289 display.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 320
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 240
#endif
#define GDISP_INITIAL_CONTRAST 50
#define GDISP_INITIAL_BACKLIGHT 100
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
#if defined(GDISP_USE_CUSTOM_BOARD) && GDISP_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "gdisp_lld_board.h"
#elif defined(BOARD_FIREBULL_STM32_F103)
#include "gdisp_lld_board_firebullstm32f103.h"
#else
/* Include the user supplied board definitions */
#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) {
/* Reg 0x004E is an 8 bit value
* Reg 0x004F is 9 bit
* Use a bit mask to make sure they are not set too high
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_180:
write_reg(0x004e, (GDISP_SCREEN_WIDTH-1-x) & 0x00FF);
write_reg(0x004f, (GDISP_SCREEN_HEIGHT-1-y) & 0x01FF);
break;
case GDISP_ROTATE_0:
write_reg(0x004e, x & 0x00FF);
write_reg(0x004f, y & 0x01FF);
break;
case GDISP_ROTATE_270:
write_reg(0x004e, y & 0x00FF);
write_reg(0x004f, x & 0x01FF);
break;
case GDISP_ROTATE_90:
write_reg(0x004e, (GDISP_SCREEN_WIDTH - y - 1) & 0x00FF);
write_reg(0x004f, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
break;
}
}
static void set_viewport(coord_t x, coord_t y, coord_t cx, coord_t cy) {
set_cursor(x, y);
/* Reg 0x44 - Horizontal RAM address position
* Upper Byte - HEA
* Lower Byte - HSA
* 0 <= HSA <= HEA <= 0xEF
* Reg 0x45,0x46 - Vertical RAM address position
* Lower 9 bits gives 0-511 range in each value
* 0 <= Reg(0x45) <= Reg(0x46) <= 0x13F
*/
switch(GDISP.Orientation) {
case GDISP_ROTATE_0:
write_reg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (x & 0x00FF));
write_reg(0x45, y & 0x01FF);
write_reg(0x46, (y+cy-1) & 0x01FF);
break;
case GDISP_ROTATE_270:
write_reg(0x44, (((x+cx-1) << 8) & 0xFF00 ) | (y & 0x00FF));
write_reg(0x45, x & 0x01FF);
write_reg(0x46, (x+cx-1) & 0x01FF);
break;
case GDISP_ROTATE_180:
write_reg(0x44, (((GDISP_SCREEN_WIDTH-x-1) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH - (x+cx)) & 0x00FF));
write_reg(0x45, (GDISP_SCREEN_HEIGHT-(y+cy)) & 0x01FF);
write_reg(0x46, (GDISP_SCREEN_HEIGHT-y-1) & 0x01FF);
break;
case GDISP_ROTATE_90:
write_reg(0x44, (((GDISP_SCREEN_WIDTH - y - 1) & 0x00FF) << 8) | ((GDISP_SCREEN_WIDTH - (y+cy)) & 0x00FF));
write_reg(0x45, (GDISP_SCREEN_HEIGHT - (x+cx)) & 0x01FF);
write_reg(0x46, (GDISP_SCREEN_HEIGHT - x - 1) & 0x01FF);
break;
}
set_cursor(x, y);
}
static __inline void reset_viewport(void) {
set_viewport(0, 0, GDISP.Width, GDISP.Height);
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t lld_gdisp_init(void) {
/* Initialise your display */
init_board();
// Hardware reset
setpin_reset(TRUE);
delayms(20);
setpin_reset(FALSE);
delayms(20);
// Get the bus for the following initialisation commands
acquire_bus();
write_reg(0x0000,0x0001); delay(5);
write_reg(0x0003,0xA8A4); delay(5);
write_reg(0x000C,0x0000); delay(5);
write_reg(0x000D,0x080C); delay(5);
write_reg(0x000E,0x2B00); delay(5);
write_reg(0x001E,0x00B0); delay(5);
write_reg(0x0001,0x2B3F); delay(5);
write_reg(0x0002,0x0600); delay(5);
write_reg(0x0010,0x0000); delay(5);
write_reg(0x0011,0x6070); delay(5);
write_reg(0x0005,0x0000); delay(5);
write_reg(0x0006,0x0000); delay(5);
write_reg(0x0016,0xEF1C); delay(5);
write_reg(0x0017,0x0003); delay(5);
write_reg(0x0007,0x0133); delay(5);
write_reg(0x000B,0x0000); delay(5);
write_reg(0x000F,0x0000); delay(5);
write_reg(0x0041,0x0000); delay(5);
write_reg(0x0042,0x0000); delay(5);
write_reg(0x0048,0x0000); delay(5);
write_reg(0x0049,0x013F); delay(5);
write_reg(0x004A,0x0000); delay(5);
write_reg(0x004B,0x0000); delay(5);
write_reg(0x0044,0xEF00); delay(5);
write_reg(0x0045,0x0000); delay(5);
write_reg(0x0046,0x013F); delay(5);
write_reg(0x0030,0x0707); delay(5);
write_reg(0x0031,0x0204); delay(5);
write_reg(0x0032,0x0204); delay(5);
write_reg(0x0033,0x0502); delay(5);
write_reg(0x0034,0x0507); delay(5);
write_reg(0x0035,0x0204); delay(5);
write_reg(0x0036,0x0204); delay(5);
write_reg(0x0037,0x0502); delay(5);
write_reg(0x003A,0x0302); delay(5);
write_reg(0x003B,0x0302); delay(5);
write_reg(0x0023,0x0000); delay(5);
write_reg(0x0024,0x0000); delay(5);
write_reg(0x0025,0x8000); delay(5);
write_reg(0x004f,0x0000); delay(5);
write_reg(0x004e,0x0000); delay(5);
// Release the bus
release_bus();
/* Turn on the back-light */
set_backlight(GDISP_INITIAL_BACKLIGHT);
/* Initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = GDISP_INITIAL_BACKLIGHT;
GDISP.Contrast = GDISP_INITIAL_CONTRAST;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(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
acquire_bus();
set_cursor(x, y);
write_reg(0x0022, color);
release_bus();
}
/* ---- Optional Routines ---- */
/*
All the below routines are optional.
Defining them will increase speed but everything
will work if they are not defined.
If you are not using a routine - turn it off using
the appropriate GDISP_HARDWARE_XXXX macro.
Don't bother coding for obvious similar routines if
there is no performance penalty as the emulation software
makes a good job of using similar routines.
eg. If gfillarea() is defined there is little
point in defining clear() unless the
performance bonus is significant.
For good performance it is suggested to implement
fillarea() and blitarea().
*/
#if GDISP_HARDWARE_CLEARS || defined(__DOXYGEN__)
/**
* @brief Clear the display.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_clear(color_t color) {
unsigned i;
acquire_bus();
reset_viewport();
set_cursor(0, 0);
stream_start();
for(i = 0; i < GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT; i++)
write_data(color);
stream_stop();
release_bus();
}
#endif
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
unsigned i, area;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
area = cx*cy;
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
for(i = 0; i < area; i++)
write_data(color);
stream_stop();
release_bus();
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void lld_gdisp_blit_area_ex(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) {
coord_t endx, endy;
unsigned lg;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
acquire_bus();
set_viewport(x, y, cx, cy);
stream_start();
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
buffer += srcx + srcy * srccx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
write_data(*buffer++);
stream_stop();
release_bus();
}
#endif
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
/**
* @brief Get the color of a particular pixel.
* @note Optional.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The pixel to be read
*
* @notapi
*/
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
color_t color;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < 0 || x >= GDISP.Width || y < 0 || y >= GDISP.Height) return 0;
#endif
acquire_bus();
set_cursor(x, y);
stream_start();
color = read_data(); // dummy read
color = read_data();
stream_stop();
release_bus();
return color;
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
/**
* @brief Scroll vertically a section of the screen.
* @note Optional.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
static color_t buf[((GDISP_SCREEN_HEIGHT > GDISP_SCREEN_WIDTH ) ? GDISP_SCREEN_HEIGHT : GDISP_SCREEN_WIDTH)];
coord_t row0, row1;
unsigned i, gap, abslines, j;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
abslines = lines < 0 ? -lines : lines;
acquire_bus();
if (abslines >= cy) {
abslines = cy;
gap = 0;
} else {
gap = cy - abslines;
for(i = 0; i < gap; i++) {
if(lines > 0) {
row0 = y + i + lines;
row1 = y + i;
} else {
row0 = (y - i - 1) + lines;
row1 = (y - i - 1);
}
/* read row0 into the buffer and then write at row1*/
set_viewport(x, row0, cx, 1);
stream_start();
j = read_data(); // dummy read
for (j = 0; j < cx; j++)
buf[j] = read_data();
stream_stop();
set_viewport(x, row1, cx, 1);
stream_start();
for (j = 0; j < cx; j++)
write_data(buf[j]);
stream_stop();
}
}
/* fill the remaining gap */
set_viewport(x, lines > 0 ? (y+gap) : y, cx, abslines);
stream_start();
gap = cx*abslines;
for(i = 0; i < gap; i++) write_data(bgcolor);
stream_stop();
release_bus();
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void lld_gdisp_control(unsigned what, void *value) {
switch(what) {
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
acquire_bus();
write_reg(0x0010, 0x0000); // leave sleep mode
write_reg(0x0007, 0x0000); // halt operation
write_reg(0x0000, 0x0000); // turn off oszillator
write_reg(0x0010, 0x0001); // enter sleepmode
release_bus();
break;
case powerOn:
acquire_bus();
write_reg(0x0010, 0x0000); // leave sleep mode
release_bus();
if (GDISP.Powermode != powerSleep)
lld_gdisp_init();
break;
case powerSleep:
acquire_bus();
write_reg(0x0010, 0x0001); // enter sleep mode
release_bus();
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
acquire_bus();
write_reg(0x0001, 0x2B3F);
/* ID = 11 AM = 0 */
write_reg(0x0011, 0x6070);
release_bus();
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
acquire_bus();
write_reg(0x0001, 0x293F);
/* ID = 11 AM = 1 */
write_reg(0x0011, 0x6078);
release_bus();
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
acquire_bus();
write_reg(0x0001, 0x2B3F);
/* ID = 01 AM = 0 */
write_reg(0x0011, 0x6040);
release_bus();
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
acquire_bus();
write_reg(0x0001, 0x293F);
/* ID = 01 AM = 1 */
write_reg(0x0011, 0x6048);
release_bus();
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
/*
case GDISP_CONTROL_BACKLIGHT:
case GDISP_CONTROL_CONTRAST:
*/
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1289/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD1289

View File

@ -0,0 +1,125 @@
/*
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/>.
*/
/**
* @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,164 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1289/gdisp_lld_board_example_fsmc.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)[0] /* RS = 0 */
#define GDISP_RAM ((volatile uint16_t *) 0x60020000)[0] /* RS = 1 */
/**
* @brief Initialise the board for the display.
* @notes Performs the following functions:
* 1. initialise the io port used by your display
* 2. initialise the reset pin (initial state not-in-reset)
* 3. initialise the chip select pin (initial state not-active)
* 4. initialise the backlight pin (initial state back-light off)
*
* @notapi
*/
static __inline void init_board(void) {
const unsigned char FSMC_Bank;
#if defined(STM32F1XX) || defined(STM32F3XX)
/* FSMC setup for F1/F3 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
#if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
#error "DMA not implemented for F1/F3 Devices"
#endif
#elif defined(STM32F4XX) || defined(STM32F2XX)
/* STM32F2-F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
#if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt();
dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
#endif
#else
#error "FSMC not implemented for this device"
#endif
/* 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_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
| (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
| (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
/* Bank1 NOR/SRAM control register configuration
* This is actually not needed as already set by default after reset */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
}
/**
* @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) {
(void) state;
/* Nothing to do here */
}
/**
* @brief Set the lcd back-light level.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
(void) percent;
/* Nothing to do here */
}
/**
* @brief Take exclusive control of the bus
*
* @notapi
*/
static __inline void acquire_bus(void) {
/* Nothing to do here */
}
/**
* @brief Release exclusive control of the bus
*
* @notapi
*/
static __inline void release_bus(void) {
/* Nothing to do here */
}
/**
* @brief Send data to the index register.
*
* @param[in] index The index register to set
*
* @notapi
*/
static __inline void write_index(uint16_t index) { GDISP_REG = index; }
/**
* @brief Send data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) { GDISP_RAM = data; }
#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) { return GDISP_RAM; }
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,157 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1289/gdisp_lld_board_firebullstm32f103.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 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.
* @notes This board definition uses GPIO and assumes exclusive access to these GPIO pins
*
* @notapi
*/
static __inline void init_board(void) {
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_WR;
CLR_CS;
}
/**
* @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) {
(void) state;
/* Nothing to do here - reset pin tied to Vcc */
}
/**
* @brief Set the lcd back-light level.
*
* @param[in] percent 0 to 100%
*
* @notapi
*/
static __inline void set_backlight(uint8_t percent) {
(void) percent;
/* Nothing to do here - Backlight always on */
}
/**
* @brief Take exclusive control of the bus
*
* @notapi
*/
static __inline void acquire_bus(void) {
/* Nothing to do here since LCD is the only device on that bus */
}
/**
* @brief Release exclusive control of the bus
*
* @notapi
*/
static __inline void release_bus(void) {
/* Nothing to do here since LCD is the only device on that bus */
}
/**
* @brief Send data to the index register.
*
* @param[in] index The index register to set
*
* @notapi
*/
static __inline void write_index(uint16_t index) {
palWritePort(GPIOE, index);
CLR_RS; CLR_WR; SET_WR; SET_RS;
}
/**
* @brief Send data to the lcd.
*
* @param[in] data The data to send
*
* @notapi
*/
static __inline void write_data(uint16_t data) {
palWritePort(GPIOE, data);
CLR_WR; SET_WR;
}
#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) {
uint16_t value;
// change pin mode to digital input
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_INPUT);
CLR_RD;
value = palReadPort(GPIOE);
value = palReadPort(GPIOE);
SET_RD;
// change pin mode back to digital output
palSetGroupMode(GPIOE, PAL_WHOLE_PORT, 0, PAL_MODE_OUTPUT_PUSHPULL);
return value;
}
#endif
#endif /* _GDISP_LLD_BOARD_H */
/** @} */

View File

@ -0,0 +1,53 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1289/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header for the SSD1289 display.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "SSD1289"
#define GDISP_LLD(x) gdisp_lld_##x##_SSD1289
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,19 @@
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) If you are not using a known board then create a gdisp_lld_board.h file
and ensure it is on your include path.
Use the gdisp_lld_board_example.h or gdisp_lld_board_fsmc.h file as a basis.
Currently known boards are:
BOARD_FIREBULL_STM32_F103 - GPIO interface: requires GDISP_CMD_PORT and GDISP_DATA_PORT to be defined
d) The following are optional - define them if you are not using the defaults below:
#define GDISP_SCREEN_WIDTH 320
#define GDISP_SCREEN_HEIGHT 240
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/SSD1289/gdisp_lld.mk

View File

@ -0,0 +1,613 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1963/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 320
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 240
#endif
/* All the board specific code should go in these include file so the driver
* can be ported to another board just by creating a suitable file.
*/
//#if defined(BOARD_YOURBOARDNAME)
// #include "gdisp_lld_board_yourboardname.h"
//#else
// /* Include the user supplied board definitions */
// #include "gdisp_lld_board.h"
//#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
#include "ssd1963.h"
#if defined(GDISP_USE_FSMC)
__inline void GDISP_LLD(writeindex)(uint8_t cmd) {
GDISP_REG = cmd;
}
__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) {
GDISP_REG = lcdReg;
GDISP_RAM = lcdRegValue;
}
__inline void GDISP_LLD(writedata)(uint16_t data) {
GDISP_RAM = data;
}
__inline uint16_t GDISP_LLD(readdata)(void) {
return (GDISP_RAM);
}
__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) {
GDISP_REG = lcdReg;
return (GDISP_RAM);
}
__inline void GDISP_LLD(writestreamstart)(void) {
GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START);
}
__inline void GDISP_LLD(readstreamstart)(void) {
GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START);
}
__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) {
uint16_t i;
for(i = 0; i < size; i++)
GDISP_RAM = buffer[i];
}
__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) {
uint16_t i;
for(i = 0; i < size; i++) {
buffer[i] = GDISP_RAM;
}
}
#elif defined(GDISP_USE_GPIO)
__inline void GDISP_LLD(writeindex)(uint8_t cmd) {
Set_CS; Set_RS; Set_WR; Clr_RD;
palWritePort(GDISP_DATA_PORT, cmd);
Clr_CS;
}
__inline void GDISP_LLD(writereg)(uint16_t lcdReg,uint16_t lcdRegValue) {
Set_CS; Set_RS; Set_WR; Clr_RD;
palWritePort(GDISP_DATA_PORT, lcdReg);
Clr_RS;
palWritePort(GDISP_DATA_PORT, lcdRegValue);
Clr_CS;
}
__inline void GDISP_LLD(writedata)(uint16_t data) {
Set_CS; Clr_RS; Set_WR; Clr_RD;
palWritePort(GDISP_DATA_PORT, data);
Clr_CS;
}
__inline uint16_t GDISP_LLD(readdata)(void) {
Set_CS; Clr_RS; Clr_WR; Set_RD;
uint16_t data = palReadPort(GDISP_DATA_PORT);
Clr_CS;
return data;
}
__inline uint8_t GDISP_LLD(readreg)(uint8_t lcdReg) {
Set_CS; Set_RS; Clr_WR; Set_RD;
palWritePort(GDISP_DATA_PORT, lcdReg);
Clr_RS;
uint16_t data = palReadPort(GDISP_DATA_PORT);
Clr_CS;
return data;
}
__inline void GDISP_LLD(writestreamstart)(void) {
GDISP_LLD(writeindex)(SSD1963_WRITE_MEMORY_START);
}
__inline void GDISP_LLD(readstreamstart)(void) {
GDISP_LLD(writeindex)(SSD1963_READ_MEMORY_START);
}
__inline void GDISP_LLD(writestream)(uint16_t *buffer, uint16_t size) {
uint16_t i;
Set_CS; Clr_RS; Set_WR; Clr_RD;
for(i = 0; i < size; i++) {
Set_WR;
palWritePort(GDISP_DATA_PORT, buffer[i]);
Clr_WR;
}
Clr_CS;
}
__inline void GDISP_LLD(readstream)(uint16_t *buffer, size_t size) {
uint16_t i;
Set_CS; Clr_RS; Clr_WR; Set_RD;
for(i = 0; i < size; i++) {
Set_RD;
buffer[i] = palReadPort(GDISP_DATA_PORT);
Clr_RD;
}
}
#endif
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialisation.
* @return TRUE if successful, FALSE on error.
*
* @notapi
*/
bool_t lld_gdisp_init(void) {
/* Initialise the display */
#if defined(GDISP_USE_FSMC)
#if defined(STM32F1XX) || defined(STM32F3XX)
/* FSMC setup for F1/F3 */
rccEnableAHB(RCC_AHBENR_FSMCEN, 0);
#if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
#error "DMA not implemented for F1/F3 Devices"
#endif
#elif defined(STM32F4XX) || defined(STM32F2XX)
/* STM32F2-F4 FSMC init */
rccEnableAHB3(RCC_AHB3ENR_FSMCEN, 0);
#if defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
if (dmaStreamAllocate(GDISP_DMA_STREAM, 0, NULL, NULL)) chSysHalt();
dmaStreamSetMemory0(GDISP_DMA_STREAM, &GDISP_RAM);
dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
#endif
#else
#error "FSMC not implemented for this device"
#endif
/* 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));
const unsigned char FSMC_Bank = 0;
/* FSMC timing */
FSMC_Bank1->BTCR[FSMC_Bank+1] = (FSMC_BTR1_ADDSET_1 | FSMC_BTR1_ADDSET_3) \
| (FSMC_BTR1_DATAST_1 | FSMC_BTR1_DATAST_3) \
| (FSMC_BTR1_BUSTURN_1 | FSMC_BTR1_BUSTURN_3) ;
/* Bank1 NOR/SRAM control register configuration
* This is actually not needed as already set by default after reset */
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
#elif defined(GDISP_USE_GPIO)
IOBus busCMD = {GDISP_CMD_PORT, (1 << GDISP_CS) | (1 << GDISP_RS) | (1 << GDISP_WR) | (1 << GDISP_RD), 0};
IOBus busDATA = {GDISP_CMD_PORT, 0xFFFFF, 0};
palSetBusMode(&busCMD, PAL_MODE_OUTPUT_PUSHPULL);
palSetBusMode(&busDATA, PAL_MODE_OUTPUT_PUSHPULL);
#else
#error "Please define GDISP_USE_FSMC or GDISP_USE_GPIO"
#endif
GDISP_LLD(writeindex)(SSD1963_SOFT_RESET);
chThdSleepMicroseconds(100);
/* Driver PLL config */
GDISP_LLD(writeindex)(SSD1963_SET_PLL_MN);
GDISP_LLD(writedata)(35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz)
GDISP_LLD(writedata)(2); // SYSclk = PLLclk / 3 (120MHz)
GDISP_LLD(writedata)(4); // Apply calculation bit, else it is ignored
GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Enable PLL
GDISP_LLD(writedata)(0x01);
chThdSleepMicroseconds(200);
GDISP_LLD(writeindex)(SSD1963_SET_PLL); // Use PLL
GDISP_LLD(writedata)(0x03);
chThdSleepMicroseconds(200);
GDISP_LLD(writeindex)(SSD1963_SOFT_RESET);
chThdSleepMicroseconds(100);
/* Screen size */
GDISP_LLD(writeindex)(SSD1963_SET_GDISP_MODE);
// GDISP_LLD(writedata)(0x0000);
GDISP_LLD(writedata)(0b00011000); //Enabled dithering
GDISP_LLD(writedata)(0x0000);
GDISP_LLD(writedata)(mHIGH((GDISP_SCREEN_WIDTH+1)));
GDISP_LLD(writedata)((GDISP_SCREEN_WIDTH+1));
GDISP_LLD(writedata)(mHIGH((GDISP_SCREEN_HEIGHT+1)));
GDISP_LLD(writedata)((GDISP_SCREEN_HEIGHT+1));
GDISP_LLD(writedata)(0x0000);
GDISP_LLD(writeindex)(SSD1963_SET_PIXEL_DATA_INTERFACE);
GDISP_LLD(writedata)(SSD1963_PDI_16BIT565);
/* LCD Clock specs */
GDISP_LLD(writeindex)(SSD1963_SET_LSHIFT_FREQ);
GDISP_LLD(writedata)((GDISP_FPR >> 16) & 0xFF);
GDISP_LLD(writedata)((GDISP_FPR >> 8) & 0xFF);
GDISP_LLD(writedata)(GDISP_FPR & 0xFF);
GDISP_LLD(writeindex)(SSD1963_SET_HORI_PERIOD);
GDISP_LLD(writedata)(mHIGH(SCREEN_HSYNC_PERIOD));
GDISP_LLD(writedata)(mLOW(SCREEN_HSYNC_PERIOD));
GDISP_LLD(writedata)(mHIGH((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH)));
GDISP_LLD(writedata)(mLOW((SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH)));
GDISP_LLD(writedata)(SCREEN_HSYNC_PULSE);
GDISP_LLD(writedata)(0x00);
GDISP_LLD(writedata)(0x00);
GDISP_LLD(writedata)(0x00);
GDISP_LLD(writeindex)(SSD1963_SET_VERT_PERIOD);
GDISP_LLD(writedata)(mHIGH(SCREEN_VSYNC_PERIOD));
GDISP_LLD(writedata)(mLOW(SCREEN_VSYNC_PERIOD));
GDISP_LLD(writedata)(mHIGH((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH)));
GDISP_LLD(writedata)(mLOW((SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH)));
GDISP_LLD(writedata)(SCREEN_VSYNC_PULSE);
GDISP_LLD(writedata)(0x00);
GDISP_LLD(writedata)(0x00);
/* Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel */
GDISP_LLD(writeindex)(SSD1963_SET_TEAR_ON);
GDISP_LLD(writedata)(0x0000);
/* Turn on */
GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON);
#if defined(GDISP_USE_FSMC)
/* FSMC delay reduced as the controller now runs at full speed */
FSMC_Bank1->BTCR[FSMC_Bank+1] = FSMC_BTR1_ADDSET_0 | FSMC_BTR1_DATAST_2 | FSMC_BTR1_BUSTURN_0 ;
FSMC_Bank1->BTCR[FSMC_Bank] = FSMC_BCR1_MWID_0 | FSMC_BCR1_WREN | FSMC_BCR1_MBKEN;
#endif
/* Initialise the GDISP structure to match */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOn;
GDISP.Backlight = 100;
GDISP.Contrast = 50;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
void GDISP_LLD(setwindow)(coord_t x0, coord_t y0, coord_t x1, coord_t y1) {
/* We don't need to validate here as the LLD routines will validate first.
*
* #if GDISP_NEED_VALIDATION
* if (x0 >= GDISP.Width || y0 >= GDISP.Height || x0 < 0 || y0 < 0) return;
* else if (x1 >= GDISP.Width || y1 >= GDISP.Height || y1 < 0 || y2 < 0) return;
* #endif
*/
GDISP_LLD(writeindex)(SSD1963_SET_PAGE_ADDRESS);
GDISP_LLD(writedata)((y0 >> 8) & 0xFF);
GDISP_LLD(writedata)((y0 >> 0) & 0xFF);
GDISP_LLD(writedata)((y1 >> 8) & 0xFF);
GDISP_LLD(writedata)((y1 >> 0) & 0xFF);
GDISP_LLD(writeindex)(SSD1963_SET_COLUMN_ADDRESS);
GDISP_LLD(writedata)((x0 >> 8) & 0xFF);
GDISP_LLD(writedata)((x0 >> 0) & 0xFF);
GDISP_LLD(writedata)((x1 >> 8) & 0xFF);
GDISP_LLD(writedata)((x1 >> 0) & 0xFF);
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(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
GDISP_LLD(setwindow)(x, y, x, y);
GDISP_LLD(writestreamstart)();
GDISP_LLD(writedata)(color);
}
/* ---- Optional Routines ---- */
#if GDISP_HARDWARE_FILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a color.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] color The color of the fill
*
* @notapi
*/
void lld_gdisp_fill_area(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
uint32_t area;
area = cx*cy;
GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1);
GDISP_LLD(writestreamstart)();
#if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
uint8_t i;
dmaStreamSetPeripheral(GDISP_DMA_STREAM, &color);
dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
for (i = area/65535; i; i--) {
dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
dmaStreamEnable(GDISP_DMA_STREAM);
dmaWaitCompletion(GDISP_DMA_STREAM);
}
dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
dmaStreamEnable(GDISP_DMA_STREAM);
dmaWaitCompletion(GDISP_DMA_STREAM);
#else
uint32_t index;
for(index = 0; index < area; index++)
GDISP_LLD(writedata)(color);
#endif //#ifdef GDISP_USE_DMA
}
#endif
#if GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)
/**
* @brief Fill an area with a bitmap.
* @note Optional - The high level driver can emulate using software.
*
* @param[in] x, y The start filled area
* @param[in] cx, cy The width and height to be filled
* @param[in] srcx, srcy The bitmap position to start the fill from
* @param[in] srccx The width of a line in the bitmap.
* @param[in] buffer The pixels to use to fill the area.
*
* @notapi
*/
void lld_gdisp_blit_area_ex(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_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; srcx += GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; srcy += GDISP.clipy0 - y; y = GDISP.clipy0; }
if (srcx+cx > srccx) cx = srccx - srcx;
if (cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
GDISP_LLD(setwindow)(x, y, x+cx-1, y+cy-1);
GDISP_LLD(writestreamstart)();
buffer += srcx + srcy * srccx;
#if defined(GDISP_USE_FSMC) && defined(GDISP_USE_DMA) && defined(GDISP_DMA_STREAM)
uint32_t area = cx*cy;
uint8_t i;
dmaStreamSetPeripheral(GDISP_DMA_STREAM, buffer);
dmaStreamSetMode(GDISP_DMA_STREAM, STM32_DMA_CR_PL(0) | STM32_DMA_CR_PINC | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_M2M);
for (i = area/65535; i; i--) {
dmaStreamSetTransactionSize(GDISP_DMA_STREAM, 65535);
dmaStreamEnable(GDISP_DMA_STREAM);
dmaWaitCompletion(GDISP_DMA_STREAM);
}
dmaStreamSetTransactionSize(GDISP_DMA_STREAM, area%65535);
dmaStreamEnable(GDISP_DMA_STREAM);
dmaWaitCompletion(GDISP_DMA_STREAM);
#else
coord_t endx, endy;
unsigned lg;
endx = srcx + cx;
endy = y + cy;
lg = srccx - cx;
for(; y < endy; y++, buffer += lg)
for(x=srcx; x < endx; x++)
GDISP_LLD(writedata)(*buffer++);
#endif //#ifdef GDISP_USE_DMA
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
/**
* @brief Scroll vertically a section of the screen.
* @note Optional.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
if (x < GDISP.clipx0) { cx -= GDISP.clipx0 - x; x = GDISP.clipx0; }
if (y < GDISP.clipy0) { cy -= GDISP.clipy0 - y; y = GDISP.clipy0; }
if (!lines || cx <= 0 || cy <= 0 || x >= GDISP.clipx1 || y >= GDISP.clipy1) return;
if (x+cx > GDISP.clipx1) cx = GDISP.clipx1 - x;
if (y+cy > GDISP.clipy1) cy = GDISP.clipy1 - y;
#endif
/* NOT IMPLEMENTED YET */
/*
uint16_t size = x1 - x0 ;
lld_lcdWriteIndex(SSD1963_SET_SCROLL_AREA);
lld_lcdWriteData((x0 >> 8) & 0xFF);
lld_lcdWriteData((x0 >> 0) & 0xFF);
lld_lcdWriteData((size >> 8) & 0xFF);
lld_lcdWriteData((size >> 0) & 0xFF);
lld_lcdWriteData(((lcd_height-x1) >> 8) & 0xFF);
lld_lcdWriteData(((lcd_height-x1) >> 0) & 0xFF);
lld_lcdWriteIndex(SSD1963_SET_SCROLL_START);
lld_lcdWriteData((lines >> 8) & 0xFF);
lld_lcdWriteData((lines >> 0) & 0xFF);
*/
}
#endif
#if (GDISP_NEED_CONTROL && GDISP_HARDWARE_CONTROL) || defined(__DOXYGEN__)
/**
* @brief Driver Control
* @details Unsupported control codes are ignored.
* @note The value parameter should always be typecast to (void *).
* @note There are some predefined and some specific to the low level driver.
* @note GDISP_CONTROL_POWER - Takes a gdisp_powermode_t
* GDISP_CONTROL_ORIENTATION - Takes a gdisp_orientation_t
* GDISP_CONTROL_BACKLIGHT - Takes an int from 0 to 100. For a driver
* that only supports off/on anything other
* than zero is on.
* GDISP_CONTROL_CONTRAST - Takes an int from 0 to 100.
* GDISP_CONTROL_LLD - Low level driver control constants start at
* this value.
*
* @param[in] what What to do.
* @param[in] value The value to use (always cast to a void *).
*
* @notapi
*/
void lld_gdisp_control(unsigned what, void *value) {
/* NOT IMPLEMENTED YET */
switch(what) {
case GDISP_CONTROL_POWER:
if (GDISP.Powermode == (gdisp_powermode_t)value)
return;
switch((gdisp_powermode_t)value) {
case powerOff:
GDISP_LLD(writeindex)(SSD1963_EXIT_SLEEP_MODE); // leave sleep mode
chThdSleepMicroseconds(5000);
GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF);
GDISP_LLD(writeindex)(SSD1963_SET_DEEP_SLEEP); // enter deep sleep mode
break;
case powerOn:
GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000); // 2x Dummy reads to wake up from deep sleep
GDISP_LLD(readreg)(0x0000); chThdSleepMicroseconds(5000);
if (GDISP.Powermode != powerSleep)
lld_gdisp_init();
GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_ON);
break;
case powerSleep:
GDISP_LLD(writeindex)(SSD1963_SET_DISPLAY_OFF);
GDISP_LLD(writeindex)(SSD1963_ENTER_SLEEP_MODE); // enter sleep mode
chThdSleepMicroseconds(5000);
break;
default:
return;
}
GDISP.Powermode = (gdisp_powermode_t)value;
return;
case GDISP_CONTROL_ORIENTATION:
if (GDISP.Orientation == (gdisp_orientation_t)value)
return;
switch((gdisp_orientation_t)value) {
case GDISP_ROTATE_0:
/* Code here */
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_90:
/* Code here */
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
case GDISP_ROTATE_180:
/* Code here */
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Width = GDISP_SCREEN_WIDTH;
break;
case GDISP_ROTATE_270:
/* Code here */
GDISP.Height = GDISP_SCREEN_WIDTH;
GDISP.Width = GDISP_SCREEN_HEIGHT;
break;
default:
return;
}
#if GDISP_NEED_CLIP || GDISP_NEED_VALIDATION
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
GDISP.Orientation = (gdisp_orientation_t)value;
return;
/*
case GDISP_CONTROL_BACKLIGHT:
case GDISP_CONTROL_CONTRAST:
*/
}
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/SSD1963/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/SSD1963

View File

@ -0,0 +1,53 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/SSD1963/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "SSD1963"
#define GDISP_LLD(x) gdisp_lld_##x##_SSD1963
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
/* Maybe someday soon */
#define GDISP_HARDWARE_SCROLL FALSE
#define GDISP_HARDWARE_CONTROL FALSE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,53 @@
/*
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/>.
*/
/**
* @file SSD1963/gdisp_lld_panel.h
* @brief TFT LCD panel properties.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_PANEL_H
#define _GDISP_LLD_PANEL_H
/* LCD panel specs */
#define GDISP_SCREEN_WIDTH 480
#define GDISP_SCREEN_HEIGHT 272
#define SCREEN_FPS 60ULL
#define SCREEN_HSYNC_BACK_PORCH 2LL
#define SCREEN_HSYNC_FRONT_PORCH 2ULL
#define SCREEN_HSYNC_PULSE 41ULL
#define SCREEN_VSYNC_BACK_PORCH 2ULL
#define SCREEN_VSYNC_FRONT_PORCH 2ULL
#define SCREEN_VSYNC_PULSE 10ULL
#define SCREEN_HSYNC_PERIOD (SCREEN_HSYNC_PULSE + SCREEN_HSYNC_BACK_PORCH + GDISP_SCREEN_WIDTH + SCREEN_HSYNC_FRONT_PORCH)
#define SCREEN_VSYNC_PERIOD (SCREEN_VSYNC_PULSE + SCREEN_VSYNC_BACK_PORCH + GDISP_SCREEN_HEIGHT + SCREEN_VSYNC_FRONT_PORCH)
#define SCREEN_PCLK (SCREEN_HSYNC_PERIOD * SCREEN_VSYNC_PERIOD * SCREEN_FPS)
#define GDISP_FPR ((SCREEN_PCLK * 1048576)/100000000)
#endif
/** @} */

View File

@ -0,0 +1,38 @@
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: #define GDISP_NEED_MULTITHREAD TRUE
c) One (only) of:
#define GDISP_USE_GPIO
#define GDISP_USE_FSMC
d) If you want to use DMA (only works with FSMC):
#define GDISP_USE_DMA
#define GDISP_DMA_STREAM STM32_DMA2_STREAM6 //You can change the DMA channel according to your needs
2. Edit gdisp_lld_panel.h with your panel properties
3. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/SSD1963/gdisp_lld.mk
Example FSMC config with DMA:
#define GDISP_SCREEN_WIDTH 480
#define GDISP_SCREEN_HEIGHT 272
#define GDISP_USE_FSMC
#define GDISP_USE_DMA
#define GDISP_DMA_STREAM STM32_DMA2_STREAM6
#if defined(GDISP_USE_GPIO)
#define GDISP_CMD_PORT GPIOC
#define GDISP_DATA_PORT GPIOD
#define GDISP_CS 0
#define GDISP_RS 1
#define GDISP_WR 2
#define GDISP_RD 3
#endif

View File

@ -0,0 +1,133 @@
/*
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 SSD1963_H
#define SSD1963_H
#include "gdisp_lld_panel.h"
#if defined(GDISP_USE_GPIO)
#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);
#endif
#if defined(GDISP_USE_FSMC)
/* Using FSMC A16 as RS */
#define GDISP_REG (*((volatile uint16_t *) 0x60000000)) /* RS = 0 */
#define GDISP_RAM (*((volatile uint16_t *) 0x60020000)) /* RS = 1 */
#endif
#define mHIGH(x) (x >> 8)
#define mLOW(x) (x & 0xFF)
/* SSD1963 commands */
#define SSD1963_NOP 0x0000
#define SSD1963_SOFT_RESET 0x0001
#define SSD1963_GET_POWER_MODE 0x000A
#define SSD1963_GET_ADDRESS_MODE 0x000B
#define SSD1963_GET_DISPLAY_MODE 0x000D
#define SSD1963_GET_TEAR_EFFECT_STATUS 0x000E
#define SSD1963_ENTER_SLEEP_MODE 0x0010
#define SSD1963_EXIT_SLEEP_MODE 0x0011
#define SSD1963_ENTER_PARTIAL_MODE 0x0012
#define SSD1963_ENTER_NORMAL_MODE 0x0013
#define SSD1963_EXIT_INVERT_MODE 0x0020
#define SSD1963_ENTER_INVERT_MODE 0x0021
#define SSD1963_SET_GAMMA_CURVE 0x0026
#define SSD1963_SET_DISPLAY_OFF 0x0028
#define SSD1963_SET_DISPLAY_ON 0x0029
#define SSD1963_SET_COLUMN_ADDRESS 0x002A
#define SSD1963_SET_PAGE_ADDRESS 0x002B
#define SSD1963_WRITE_MEMORY_START 0x002C
#define SSD1963_READ_MEMORY_START 0x002E
#define SSD1963_SET_PARTIAL_AREA 0x0030
#define SSD1963_SET_SCROLL_AREA 0x0033
#define SSD1963_SET_TEAR_OFF 0x0034
#define SSD1963_SET_TEAR_ON 0x0035
#define SSD1963_SET_ADDRESS_MODE 0x0036
#define SSD1963_SET_SCROLL_START 0x0037
#define SSD1963_EXIT_IDLE_MODE 0x0038
#define SSD1963_ENTER_IDLE_MODE 0x0039
#define SSD1963_SET_PIXEL_FORMAT 0x003A
#define SSD1963_WRITE_MEMORY_CONTINUE 0x003C
#define SSD1963_READ_MEMORY_CONTINUE 0x003E
#define SSD1963_SET_TEAR_SCANLINE 0x0044
#define SSD1963_GET_SCANLINE 0x0045
#define SSD1963_READ_DDB 0x00A1
#define SSD1963_SET_GDISP_MODE 0x00B0
#define SSD1963_GET_GDISP_MODE 0x00B1
#define SSD1963_SET_HORI_PERIOD 0x00B4
#define SSD1963_GET_HORI_PERIOD 0x00B5
#define SSD1963_SET_VERT_PERIOD 0x00B6
#define SSD1963_GET_VERT_PERIOD 0x00B7
#define SSD1963_SET_GPIO_CONF 0x00B8
#define SSD1963_GET_GPIO_CONF 0x00B9
#define SSD1963_SET_GPIO_VALUE 0x00BA
#define SSD1963_GET_GPIO_STATUS 0x00BB
#define SSD1963_SET_POST_PROC 0x00BC
#define SSD1963_GET_POST_PROC 0x00BD
#define SSD1963_SET_PWM_CONF 0x00BE
#define SSD1963_GET_PWM_CONF 0x00BF
#define SSD1963_GET_GDISP_GEN0 0x00C0
#define SSD1963_SET_GDISP_GEN0 0x00C1
#define SSD1963_GET_GDISP_GEN1 0x00C2
#define SSD1963_SET_GDISP_GEN1 0x00C3
#define SSD1963_GET_GDISP_GEN2 0x00C4
#define SSD1963_SET_GDISP_GEN2 0x00C5
#define SSD1963_GET_GDISP_GEN3 0x00C6
#define SSD1963_SET_GDISP_GEN3 0x00C7
#define SSD1963_SET_GPIO0_ROP 0x00C8
#define SSD1963_GET_GPIO0_ROP 0x00C9
#define SSD1963_SET_GPIO1_ROP 0x00CA
#define SSD1963_GET_GPIO1_ROP 0x00CB
#define SSD1963_SET_GPIO2_ROP 0x00CC
#define SSD1963_GET_GPIO2_ROP 0x00CD
#define SSD1963_SET_GPIO3_ROP 0x00CE
#define SSD1963_GET_GPIO3_ROP 0x00CF
#define SSD1963_SET_DBC_CONF 0x00D0
#define SSD1963_GET_DBC_CONF 0x00D1
#define SSD1963_SET_DBC_TH 0x00D4
#define SSD1963_GET_DBC_TH 0x00D5
#define SSD1963_SET_PLL 0x00E0
#define SSD1963_SET_PLL_MN 0x00E2
#define SSD1963_GET_PLL_MN 0x00E3
#define SSD1963_GET_PLL_STATUS 0x00E4
#define SSD1963_SET_DEEP_SLEEP 0x00E5
#define SSD1963_SET_LSHIFT_FREQ 0x00E6
#define SSD1963_GET_LSHIFT_FREQ 0x00E7
#define SSD1963_SET_PIXEL_DATA_INTERFACE 0x00F0
#define SSD1963_PDI_8BIT 0
#define SSD1963_PDI_12BIT 1
#define SSD1963_PDI_16BIT 2
#define SSD1963_PDI_16BIT565 3
#define SSD1963_PDI_18BIT 4
#define SSD1963_PDI_24BIT 5
#define SSD1963_PDI_9BIT 6
#define SSD1963_GET_PIXEL_DATA_INTERFACE 0x00F1
#endif

View File

@ -0,0 +1,133 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/TestStub/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source (stub).
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
#ifndef GDISP_SCREEN_HEIGHT
#define GDISP_SCREEN_HEIGHT 128
#endif
#ifndef GDISP_SCREEN_WIDTH
#define GDISP_SCREEN_WIDTH 128
#endif
/* ---- Required Routines ---- */
/*
The following 2 routines are required.
All other routines are optional.
*/
/**
* @brief Low level GDISP driver initialization.
*
* @notapi
*/
bool_t lld_gdisp_init(void) {
/* Initialise the GDISP structure */
GDISP.Width = GDISP_SCREEN_WIDTH;
GDISP.Height = GDISP_SCREEN_HEIGHT;
GDISP.Orientation = GDISP_ROTATE_0;
GDISP.Powermode = powerOff;
GDISP.Backlight = 100;
GDISP.Contrast = 50;
#if GDISP_NEED_VALIDATION || GDISP_NEED_CLIP
GDISP.clipx0 = 0;
GDISP.clipy0 = 0;
GDISP.clipx1 = GDISP.Width;
GDISP.clipy1 = GDISP.Height;
#endif
return TRUE;
}
/**
* @brief Draws a pixel on the display.
*
* @param[in] x X location of the pixel
* @param[in] y Y location of the pixel
* @param[in] color The color of the pixel
*
* @notapi
*/
void lld_gdisp_draw_pixel(coord_t x, coord_t y, color_t color) {
(void)x;
(void)y;
(void)color;
}
/* ---- Optional Routines ---- */
#if (GDISP_NEED_PIXELREAD && GDISP_HARDWARE_PIXELREAD) || defined(__DOXYGEN__)
/**
* @brief Get the color of a particular pixel.
* @note Optional.
* @note If x,y is off the screen, the result is undefined.
*
* @param[in] x, y The start of the text
*
* @notapi
*/
color_t lld_gdisp_get_pixel_color(coord_t x, coord_t y) {
(void)x;
(void)y;
return 0;
}
#endif
#if (GDISP_NEED_SCROLL && GDISP_HARDWARE_SCROLL) || defined(__DOXYGEN__)
/**
* @brief Scroll vertically a section of the screen.
* @note Optional.
* @note If x,y + cx,cy is off the screen, the result is undefined.
* @note If lines is >= cy, it is equivelent to a area fill with bgcolor.
*
* @param[in] x, y The start of the area to be scrolled
* @param[in] cx, cy The size of the area to be scrolled
* @param[in] lines The number of lines to scroll (Can be positive or negative)
* @param[in] bgcolor The color to fill the newly exposed area.
*
* @notapi
*/
void lld_gdisp_vertical_scroll(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor) {
(void)x;
(void)y;
(void)cx;
(void)cy;
(void)lines;
(void)bgcolor;
}
#endif
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/TestStub/gdisp_lld.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/TestStub

View File

@ -0,0 +1,51 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/TestStub/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header (stub).
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "TestStub"
#define GDISP_LLD(x) gdisp_lld_##x##_TestStub
#define GDISP_HARDWARE_SCROLL GDISP_NEED_SCROLL
#define GDISP_HARDWARE_PIXELREAD GDISP_NEED_PIXELREAD
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#define GDISP_PACKED_PIXELS FALSE
#define GDISP_PACKED_LINES FALSE
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,16 @@
This low level driver is a test stub that doesn't talk to any
real hardware. It is included to allow testing of the compilation
process.
Do not use this driver as a template for new drivers. Use the
templates/gdispXXXXX directory for that.
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)
you want to compile test eg: GDISP_NEED_MULTITHREAD
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/gdisp/TestStub/gdisp_lld.mk

View File

@ -0,0 +1,271 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/VMT/gdisp_lld.c
* @brief GDISP Graphics Driver subsystem low level driver source for VMT.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
#define GDISP_LLD_NO_STRUCT
/* Include the emulation code for things we don't support */
#include "gdisp/lld/emulation.c"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
#define GDISP_LLD1(x) GDISP_VMT_NAME1(gdisp_lld_##x##_)
#define GDISP_LLD2(x) GDISP_VMT_NAME2(gdisp_lld_##x##_)
/* Prototypes for lld driver functions */
bool_t GDISP_LLD1(init)(void);
void *GDISP_LLD1(query)(unsigned what);
void GDISP_LLD1(clear)(color_t color);
void GDISP_LLD1(drawpixel)(coord_t x, coord_t y, color_t color);
void GDISP_LLD1(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
void GDISP_LLD1(blitareaex)(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);
void GDISP_LLD1(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
#if GDISP_NEED_CLIP
void GDISP_LLD1(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy);
#endif
#if GDISP_NEED_CIRCLE
void GDISP_LLD1(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
void GDISP_LLD1(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
#endif
#if GDISP_NEED_ELLIPSE
void GDISP_LLD1(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
void GDISP_LLD1(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
#endif
#if GDISP_NEED_ARC
void GDISP_LLD1(drawarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
void GDISP_LLD1(fillarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
#endif
#if GDISP_NEED_TEXT
void GDISP_LLD1(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color);
void GDISP_LLD1(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor);
#endif
#if GDISP_NEED_PIXELREAD
color_t GDISP_LLD1(getpixelcolor)(coord_t x, coord_t y);
#endif
#if GDISP_NEED_SCROLL
void GDISP_LLD1(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
#endif
#if GDISP_NEED_CONTROL
void GDISP_LLD1(control)(unsigned what, void *value);
#endif
bool_t GDISP_LLD2(init)(void);
void *GDISP_LLD2(query)(unsigned what);
void GDISP_LLD2(clear)(color_t color);
void GDISP_LLD2(drawpixel)(coord_t x, coord_t y, color_t color);
void GDISP_LLD2(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
void GDISP_LLD2(blitareaex)(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);
void GDISP_LLD2(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
#if GDISP_NEED_CLIP
void GDISP_LLD2(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy);
#endif
#if GDISP_NEED_CIRCLE
void GDISP_LLD2(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
void GDISP_LLD2(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
#endif
#if GDISP_NEED_ELLIPSE
void GDISP_LLD2(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
void GDISP_LLD2(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
#endif
#if GDISP_NEED_ARC
void GDISP_LLD2(drawarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
void GDISP_LLD2(fillarc)(coord_t x, coord_t y, coord_t radius, coord_t startangle, coord_t endangle, color_t color);
#endif
#if GDISP_NEED_TEXT
void GDISP_LLD2(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color);
void GDISP_LLD2(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor);
#endif
#if GDISP_NEED_PIXELREAD
color_t GDISP_LLD2(getpixelcolor)(coord_t x, coord_t y);
#endif
#if GDISP_NEED_SCROLL
void GDISP_LLD2(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
#endif
#if GDISP_NEED_CONTROL
void GDISP_LLD2(control)(unsigned what, void *value);
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/* Our VMT table variables */
void *GDISP_LLD_VMT(query)(unsigned what);
void GDISP_LLD_VMT(clear)(color_t color);
void GDISP_LLD_VMT(drawpixel)(coord_t x, coord_t y, color_t color);
void GDISP_LLD_VMT(fillarea)(coord_t x, coord_t y, coord_t cx, coord_t cy, color_t color);
void GDISP_LLD_VMT(blitareaex)(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);
void GDISP_LLD_VMT(drawline)(coord_t x0, coord_t y0, coord_t x1, coord_t y1, color_t color);
#if GDISP_NEED_CIRCLE
void GDISP_LLD_VMT(drawcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
void GDISP_LLD_VMT(fillcircle)(coord_t x, coord_t y, coord_t radius, color_t color);
#endif
#if GDISP_NEED_ELLIPSE
void GDISP_LLD_VMT(drawellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
void GDISP_LLD_VMT(fillellipse)(coord_t x, coord_t y, coord_t a, coord_t b, color_t color);
#endif
/* Text Rendering Functions */
#if GDISP_NEED_TEXT
void GDISP_LLD_VMT(drawchar)(coord_t x, coord_t y, char c, font_t font, color_t color);
void GDISP_LLD_VMT(fillchar)(coord_t x, coord_t y, char c, font_t font, color_t color, color_t bgcolor);
#endif
/* Pixel readback */
#if GDISP_NEED_PIXELREAD
color_t GDISP_LLD_VMT(getpixelcolor)(coord_t x, coord_t y);
#endif
/* Scrolling Function - clears the area scrolled out */
#if GDISP_NEED_SCROLL
void GDISP_LLD_VMT(verticalscroll)(coord_t x, coord_t y, coord_t cx, coord_t cy, int lines, color_t bgcolor);
#endif
/* Set driver specific control */
#if GDISP_NEED_CONTROL
void GDISP_LLD_VMT(control)(unsigned what, void *value);
#endif
/* Clipping Functions */
#if GDISP_NEED_CLIP
void GDISP_LLD_VMT(setclip)(coord_t x, coord_t y, coord_t cx, coord_t cy);
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
bool_t gdisp_lld_init_VMT(void) {
if (GDISP_VMT_NAME1(gdisp_lld_init_)()) {
gdisp_lld_query_VMT = GDISP_VMT_NAME1(gdisp_lld_query_);
gdisp_lld_clear_VMT = GDISP_VMT_NAME1(gdisp_lld_clear_);
gdisp_lld_drawpixel_VMT = GDISP_VMT_NAME1(gdisp_lld_drawpixel_);
gdisp_lld_fillarea_VMT = GDISP_VMT_NAME1(gdisp_lld_fillarea_);
gdisp_lld_blitareaex_VMT = GDISP_VMT_NAME1(gdisp_lld_blitareaex_);
gdisp_lld_drawline_VMT = GDISP_VMT_NAME1(gdisp_lld_drawline_);
#if GDISP_NEED_CIRCLE
gdisp_lld_drawcircle_VMT = GDISP_VMT_NAME1(gdisp_lld_drawcircle_);
gdisp_lld_fillcircle_VMT = GDISP_VMT_NAME1(gdisp_lld_fillcircle_);
#endif
#if GDISP_NEED_ELLIPSE
gdisp_lld_drawellipse_VMT = GDISP_VMT_NAME1(gdisp_lld_drawellipse_);
gdisp_lld_fillellipse_VMT = GDISP_VMT_NAME1(gdisp_lld_fillellipse_);
#endif
#if GDISP_NEED_ARC
gdisp_lld_drawarc_VMT = GDISP_VMT_NAME1(gdisp_lld_drawarc_);
gdisp_lld_fillarc_VMT = GDISP_VMT_NAME1(gdisp_lld_fillarc_);
#endif
#if GDISP_NEED_TEXT
gdisp_lld_drawchar_VMT = GDISP_VMT_NAME1(gdisp_lld_drawchar_);
gdisp_lld_fillchar_VMT = GDISP_VMT_NAME1(gdisp_lld_fillchar_);
#endif
#if GDISP_NEED_PIXELREAD
gdisp_lld_getpixelcolor_VMT = GDISP_VMT_NAME1(gdisp_lld_pixelread_);
#endif
#if GDISP_NEED_SCROLL
gdisp_lld_verticalscroll_VMT = GDISP_VMT_NAME1(gdisp_lld_scroll_);
#endif
#if GDISP_NEED_CONTROL
gdisp_lld_control_VMT = GDISP_VMT_NAME1(gdisp_lld_control_);
#endif
#if GDISP_NEED_CLIP
gdisp_lld_setclip_VMT = GDISP_VMT_NAME1(gdisp_lld_setclip_);
#endif
return TRUE;
}
if (GDISP_VMT_NAME2(gdisp_lld_init_)()) {
gdisp_lld_query_VMT = GDISP_VMT_NAME2(gdisp_lld_query_);
gdisp_lld_clear_VMT = GDISP_VMT_NAME2(gdisp_lld_clear_);
gdisp_lld_drawpixel_VMT = GDISP_VMT_NAME2(gdisp_lld_drawpixel_);
gdisp_lld_fillarea_VMT = GDISP_VMT_NAME2(gdisp_lld_fillarea_);
gdisp_lld_blitareaex_VMT = GDISP_VMT_NAME2(gdisp_lld_blitareaex_);
gdisp_lld_drawline_VMT = GDISP_VMT_NAME2(gdisp_lld_drawline_);
#if GDISP_NEED_CIRCLE
gdisp_lld_drawcircle_VMT = GDISP_VMT_NAME2(gdisp_lld_drawcircle_);
gdisp_lld_fillcircle_VMT = GDISP_VMT_NAME2(gdisp_lld_fillcircle_);
#endif
#if GDISP_NEED_ELLIPSE
gdisp_lld_drawellipse_VMT = GDISP_VMT_NAME2(gdisp_lld_drawellipse_);
gdisp_lld_fillellipse_VMT = GDISP_VMT_NAME2(gdisp_lld_fillellipse_);
#endif
#if GDISP_NEED_ARC
gdisp_lld_drawarc_VMT = GDISP_VMT_NAME2(gdisp_lld_drawarc_);
gdisp_lld_fillarc_VMT = GDISP_VMT_NAME2(gdisp_lld_fillarc_);
#endif
#if GDISP_NEED_TEXT
gdisp_lld_drawchar_VMT = GDISP_VMT_NAME2(gdisp_lld_drawchar_);
gdisp_lld_fillchar_VMT = GDISP_VMT_NAME2(gdisp_lld_fillchar_);
#endif
#if GDISP_NEED_PIXELREAD
gdisp_lld_getpixelcolor_VMT = GDISP_VMT_NAME2(gdisp_lld_pixelread_);
#endif
#if GDISP_NEED_SCROLL
gdisp_lld_verticalscroll_VMT = GDISP_VMT_NAME2(gdisp_lld_scroll_);
#endif
#if GDISP_NEED_CONTROL
gdisp_lld_control_VMT = GDISP_VMT_NAME2(gdisp_lld_control_);
#endif
#if GDISP_NEED_CLIP
gdisp_lld_setclip_VMT = GDISP_VMT_NAME2(gdisp_lld_setclip_);
#endif
return TRUE;
}
return FALSE;
}
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,7 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/gdisp/VMT/gdisp_lld.c \
$(GFXLIB)/drivers/gdisp/VMT/gdisp_lld_driver1.c \
$(GFXLIB)//drivers/gdisp/VMT/gdisp_lld_driver2.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/gdisp/VMT

View File

@ -0,0 +1,71 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/VMT/gdisp_lld_config.h
* @brief GDISP Graphic Driver subsystem low level driver header template.
*
* @addtogroup GDISP
* @{
*/
#ifndef _GDISP_LLD_CONFIG_H
#define _GDISP_LLD_CONFIG_H
#if GFX_USE_GDISP
/*===========================================================================*/
/* Driver hardware support. */
/*===========================================================================*/
#define GDISP_DRIVER_NAME "VMT"
#define GDISP_LLD(x) gdisp_lld_##x##_VMT
#define GDISP_LLD_VMT(x) (*GDISP_LLD(x))
#define GDISP_HARDWARE_LINES TRUE
#define GDISP_HARDWARE_CLEARS TRUE
#define GDISP_HARDWARE_FILLS TRUE
#define GDISP_HARDWARE_BITFILLS TRUE
#define GDISP_HARDWARE_CIRCLES TRUE
#define GDISP_HARDWARE_CIRCLEFILLS TRUE
#define GDISP_HARDWARE_ELLIPSES TRUE
#define GDISP_HARDWARE_ELLIPSEFILLS TRUE
#define GDISP_HARDWARE_ARCS TRUE
#define GDISP_HARDWARE_ARCFILLS TRUE
#define GDISP_HARDWARE_TEXT TRUE
#define GDISP_HARDWARE_TEXTFILLS TRUE
#define GDISP_HARDWARE_SCROLL TRUE
#define GDISP_HARDWARE_PIXELREAD TRUE
#define GDISP_HARDWARE_CONTROL TRUE
#define GDISP_HARDWARE_QUERY TRUE
#define GDISP_HARDWARE_CLIP TRUE
#define GDISP_SOFTWARE_TEXTFILLDRAW FALSE
#define GDISP_SOFTWARE_TEXTBLITCOLUMN FALSE
#define GDISP_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
#define GDISP_PACKED_PIXELS FALSE
#define GDISP_PACKED_LINES FALSE
#endif /* GFX_USE_GDISP */
#endif /* _GDISP_LLD_CONFIG_H */
/** @} */

View File

@ -0,0 +1,52 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/VMT/gdisp_lld_driver1.c
* @brief GDISP Graphics Driver subsystem low level driver source for VMT.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
#define CONFIGFILE() <../GDISP_VMT_NAME1()/gdisp_lld_config.h>
#define DRIVERFILE() <../GDISP_VMT_NAME1()/gdisp_lld.c>
/* We don't need these in our VMT referenced driver */
#undef GDISP_NEED_MSGAPI
#define GDISP_NEED_MSGAPI FALSE
/* Include the specific config file we want */
#include CONFIGFILE()
/* Bring in our API */
#include "gfx.h"
/* Add the low level driver */
#include DRIVERFILE()
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,52 @@
/*
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/>.
*/
/**
* @file drivers/gdisp/VMT/gdisp_lld_driver2.c
* @brief GDISP Graphics Driver subsystem low level driver source for VMT.
*
* @addtogroup GDISP
* @{
*/
#include "ch.h"
#include "hal.h"
#if GFX_USE_GDISP /*|| defined(__DOXYGEN__)*/
#define CONFIGFILE() <../GDISP_VMT_NAME2()/gdisp_lld_config.h>
#define DRIVERFILE() <../GDISP_VMT_NAME2()/gdisp_lld.c>
/* We don't need these in our VMT referenced driver */
#undef GDISP_NEED_MSGAPI
#define GDISP_NEED_MSGAPI FALSE
/* Include the specific config file we want */
#include CONFIGFILE()
/* Bring in our API */
#include "gfx.h"
/* Add the low level driver */
#include DRIVERFILE()
#endif /* GFX_USE_GDISP */
/** @} */

View File

@ -0,0 +1,23 @@
This driver enables you to have two underlying drivers handling different hardware.
A choice is made at run-time of which driver to call based on which driver succeeds
to initialise first (init returns TRUE).
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) Define these:
#define GDISP_VMT_NAME1(x) x##YourDriver1
#define GDISP_VMT_NAME2(x) x##YourDriver2
Note YourDriver1 & 2 are the basenames of the directories containing the driver.
Note that both drivers must be the same pixel format which is
GDISP_PIXELFORMAT_RGB565 by default. Alter gdispVMT/gdisp_lld_config.h if your
pixel format is different on both drivers.
d) Any driver specific defines. If both drivers use the same defines then they must
accept the same values for the define.
2. To your makefile add the following lines:
include $(CHIBIOS)/os/halext/halext.mk
include $(CHIBIOS)/os/halext/drivers/gdispVMT/gdisp_lld.mk

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/ginput/toggle/Pal/ginput_lld_toggle.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/ginput/toggle/Pal

View File

@ -0,0 +1,63 @@
/*
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/>.
*/
/**
* @file drivers/ginput/toggle/Pal/ginput_lld_toggle.c
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware.
*
* @defgroup Toggle Toggle
* @ingroup GINPUT
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if (GFX_USE_GINPUT && GINPUT_NEED_TOGGLE) /*|| defined(__DOXYGEN__)*/
#include "ginput/lld/toggle.h"
GINPUT_TOGGLE_DECLARE_STRUCTURE();
/**
* @brief Initialise the port.
*
* @param[in] ptc A pointer to one of the entries in GInputToggleConfigTable
*
* @notapi
*/
void ginput_lld_toggle_init(const GToggleConfig *ptc) {
palSetGroupMode(((IOBus *)ptc->id)->portid, ptc->mask, 0, ptc->mode);
}
/**
* @brief Get the bits from the port.
*
* @param[in] ptc A pointer to one of the entries in GInputToggleConfigTable
*
* @notapi
*/
unsigned ginput_lld_toggle_getbits(const GToggleConfig *ptc) {
return palReadBus((IOBus *)ptc->id);
}
#endif /* GFX_USE_GINPUT && GINPUT_NEED_TOGGLE */
/** @} */

View File

@ -0,0 +1,61 @@
/*
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/>.
*/
/**
* @file drivers/ginput/toggle/Pal/ginput_lld_toggle_board_example.h
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the example board.
*
* @defgroup Toggle Toggle
* @ingroup GINPUT
* @{
*/
#ifndef _GDISP_LLD_TOGGLE_BOARD_H
#define _GDISP_LLD_TOGGLE_BOARD_H
#error "GINPUT Toggle Pal Driver: You need to define your board definitions"
// The below are example values
#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
#define GINPUT_TOGGLE_CONFIG_ENTRIES 2 // The total number of GToggleConfig entries
#define GINPUT_TOGGLE_SW1 0 // Switch 1
#define GINPUT_TOGGLE_SW2 1 // Switch 2
#define GINPUT_TOGGLE_UP 2 // Joystick Up
#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
#define GINPUT_TOGGLE_DECLARE_STRUCTURE() \
const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = { \
{AT91C_BASE_PIOB, /* Switch 1 and Switch 2 */ \
PIOB_SW1_MASK|PIOB_SW2_MASK, \
PIOB_SW1_MASK|PIOB_SW2_MASK, \
PAL_MODE_INPUT}, \
{AT91C_BASE_PIOA, /* B1..4 Joystick */ \
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
PAL_MODE_INPUT}, \
}
#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
/** @} */

View File

@ -0,0 +1,57 @@
/*
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/>.
*/
/**
* @file drivers/ginput/toggle/Pal/ginput_lld_toggle_board_olimexsam7ex256.h
* @brief GINPUT Toggle low level driver source for the ChibiOS PAL hardware on the Olimex SAM7EX256 board.
*
* @defgroup Toggle Toggle
* @ingroup GINPUT
* @{
*/
#ifndef _GDISP_LLD_TOGGLE_BOARD_H
#define _GDISP_LLD_TOGGLE_BOARD_H
#define GINPUT_TOGGLE_NUM_PORTS 7 // The total number of toggle inputs
#define GINPUT_TOGGLE_CONFIG_ENTRIES 2 // The total number of GToggleConfig entries
#define GINPUT_TOGGLE_SW1 0 // Switch 1
#define GINPUT_TOGGLE_SW2 1 // Switch 2
#define GINPUT_TOGGLE_UP 2 // Joystick Up
#define GINPUT_TOGGLE_DOWN 3 // Joystick Down
#define GINPUT_TOGGLE_LEFT 4 // Joystick Left
#define GINPUT_TOGGLE_RIGHT 5 // Joystick Right
#define GINPUT_TOGGLE_CENTER 6 // Joystick Center
#define GINPUT_TOGGLE_DECLARE_STRUCTURE() \
const GToggleConfig GInputToggleConfigTable[GINPUT_TOGGLE_CONFIG_ENTRIES] = { \
{AT91C_BASE_PIOB, /* Switch 1 and Switch 2 */ \
PIOB_SW1_MASK|PIOB_SW2_MASK, \
PIOB_SW1_MASK|PIOB_SW2_MASK, \
PAL_MODE_INPUT}, \
{AT91C_BASE_PIOA, /* B1..4 Joystick */ \
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
PIOA_B1_MASK|PIOA_B2_MASK|PIOA_B3_MASK|PIOA_B4_MASK|PIOA_B5_MASK, \
PAL_MODE_INPUT}, \
}
#endif /* _GDISP_LLD_TOGGLE_BOARD_H */
/** @} */

View File

@ -0,0 +1,48 @@
/*
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/>.
*/
/**
* @file drivers/ginput/toggle/Pal/ginput_lld_toggle_config.h
* @brief GINPUT Toggle Driver configuration header.
*
* @defgroup Toggle Toggle
* @ingroup GINPUT
* @{
*/
#ifndef _GINPUT_LLD_TOGGLE_CONFIG_H
#define _GINPUT_LLD_TOGGLE_CONFIG_H
#if GFX_USE_GINPUT && GINPUT_NEED_TOGGLE
#if GINPUT_TOGGLE_USE_CUSTOM_BOARD
/* Include the user supplied board definitions */
#include "ginput_lld_toggle_board.h"
#elif defined(BOARD_OLIMEX_SAM7_EX256)
#include "ginput_lld_toggle_board_olimexsam7ex256.h"
#else
/* Include the user supplied board definitions */
#include "ginput_lld_toggle_board.h"
#endif
#endif /* GFX_USE_GDISP && GINPUT_NEED_TOGGLE */
#endif /* _GINPUT_LLD_TOGGLE_CONFIG_H */
/** @} */

View File

@ -0,0 +1,13 @@
To use this driver:
1. Add in your halconf.h:
a) #define GFX_USE_GINPUT TRUE
#define GINPUT_NEED_TOGGLE TRUE
d) If you are not using a known board then create a ginput_lld_toggle_board.h file
and ensure it is on your include path.
Use the ginput_lld_toggle_board_example.h file as a basis.
Currently known boards are:
Olimex SAM7-EX256
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/ginput/togglePal/ginput_lld.mk

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/ginput/touch/ADS7843

View File

@ -0,0 +1,144 @@
/*
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/>.
*/
/**
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse.c
* @brief GINPUT Touch low level driver source for the ADS7843.
*
* @defgroup Mouse Mouse
* @ingroup GINPUT
* @{
*/
#include "ch.h"
#include "hal.h"
#include "gfx.h"
#if (GFX_USE_GINPUT && GINPUT_NEED_MOUSE) /*|| defined(__DOXYGEN__)*/
#include "ginput/lld/mouse.h"
#if defined(GINPUT_MOUSE_USE_CUSTOM_BOARD) && GINPUT_MOUSE_USE_CUSTOM_BOARD
#include "ginput_lld_mouse_board.h"
#elif defined(BOARD_FIREBULL_STM32_F103)
#include "ginput_lld_mouse_board_firebull_stm32f103.h"
#elif defined(BOARD_OLIMEX_STM32_E407)
#include "ginput_lld_mouse_board_olimex_stm32_e407.h"
#else
#include "ginput_lld_mouse_board_example.h"
#endif
static uint16_t sampleBuf[7];
static coord_t lastx, lasty;
/**
* @brief 7-point median filtering code for touch samples
*
* @note This is an internally used routine only.
*
* @notapi
*/
static void filter(void) {
uint16_t temp;
int i,j;
for(i = 0; i < 4; i++) {
for(j = i; j < 7; j++) {
if(sampleBuf[i] > sampleBuf[j]) {
/* Swap the values */
temp = sampleBuf[i];
sampleBuf[i] = sampleBuf[j];
sampleBuf[j] = temp;
}
}
}
}
/**
* @brief Initialise the mouse/touch.
*
* @notapi
*/
void ginput_lld_mouse_init(void) {
init_board();
}
/**
* @brief Read the mouse/touch position.
*
* @param[in] pt A pointer to the structure to fill
*
* @note For drivers that don't support returning a position
* when the touch is up (most touch devices), it should
* return the previous position with the new Z value.
* The z value is the pressure for those touch devices
* that support it (-100 to 100 where > 0 is touched)
* or, 0 or 100 for those drivers that don't.
*
* @notapi
*/
void ginput_lld_mouse_get_reading(MouseReading *pt) {
uint16_t i;
// If touch-off return the previous results
if (!getpin_pressed()) {
pt->x = lastx;
pt->y = lasty;
pt->z = 0;
pt->buttons = 0;
return;
}
// Read the port to get the touch settings
aquire_bus();
/* Get the X value
* Discard the first conversion - very noisy and keep the ADC on hereafter
* till we are done with the sampling. Note that PENIRQ is disabled while reading.
* Finally switch on PENIRQ once again - perform a dummy read.
* Once we have the readings, find the medium using our filter function
*/
read_value(0xD1);
for(i = 0; i < 7; i++)
sampleBuf[i] = read_value(0xD1);
read_value(0xD0);
filter();
lastx = (coord_t)sampleBuf[3];
/* Get the Y value using the same process as above */
read_value(0x91);
for(i = 0; i < 7; i++)
sampleBuf[i] = read_value(0x91);
read_value(0x90);
filter();
lasty = (coord_t)sampleBuf[3];
// Release the bus
release_bus();
// Return the results
pt->x = lastx;
pt->y = lasty;
pt->z = 100;
pt->buttons = GINPUT_TOUCH_PRESSED;
}
#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
/** @} */

View File

@ -0,0 +1,88 @@
/*
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/>.
*/
/**
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_example.h
* @brief GINPUT Touch low level driver source for the ADS7843 on the example board.
*
* @defgroup Mouse Mouse
* @ingroup GINPUT
* @{
*/
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
#define _GINPUT_LLD_MOUSE_BOARD_H
/**
* @brief Initialise the board for the touch.
*
* @notapi
*/
static __inline void init_board(void) {
/* Code here */
#error "ginputADS7843: You must supply a definition for init_board for your board"
}
/**
* @brief Check whether the surface is currently touched
* @return TRUE if the surface is currently touched
*
* @notapi
*/
static __inline bool_t getpin_pressed(void) {
/* Code here */
#error "ginputADS7843: You must supply a definition for getpin_pressed for your board"
}
/**
* @brief Aquire the bus ready for readings
*
* @notapi
*/
static __inline void aquire_bus(void) {
/* Code here */
#error "ginputADS7843: You must supply a definition for aquire_bus for your board"
}
/**
* @brief Release the bus after readings
*
* @notapi
*/
static __inline void release_bus(void) {
/* Code here */
#error "ginputADS7843: You must supply a definition for release_bus for your board"
}
/**
* @brief Read a value from touch controller
* @return The value read from the controller
*
* params[in] port The controller port to read.
*
* @notapi
*/
static __inline uint16_t read_value(uint16_t port) {
/* Code here */
#error "ginputADS7843: You must supply a definition for read_value for your board"
}
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
/** @} */

View File

@ -0,0 +1,103 @@
/*
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/>.
*/
/**
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_firebull_stm32f103.h
* @brief GINPUT ouch low level driver source for the ADS7843 on the FireBull STM32F103-FB board.
*
* @defgroup Mouse Mouse
* @ingroup GINPUT
* @{
*/
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
#define _GINPUT_LLD_MOUSE_BOARD_H
static const SPIConfig spicfg = {
NULL,
GPIOC,
6,
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
};
/**
* @brief Initialise the board for the touch.
*
* @notapi
*/
static __inline void init_board(void) {
spiStart(&SPID1, &spicfg);
}
/**
* @brief Check whether the surface is currently touched
* @return TRUE if the surface is currently touched
*
* @notapi
*/
static __inline bool_t getpin_pressed(void) {
return (!palReadPad(GPIOC, 4));
}
/**
* @brief Aquire the bus ready for readings
*
* @notapi
*/
static __inline void aquire_bus(void) {
spiAcquireBus(&SPID1);
//TOUCHSCREEN_SPI_PROLOGUE();
palClearPad(GPIOC, 6);
}
/**
* @brief Release the bus after readings
*
* @notapi
*/
static __inline void release_bus(void) {
palSetPad(GPIOC, 6);
spiReleaseBus(&SPID1);
//TOUCHSCREEN_SPI_EPILOGUE();
}
/**
* @brief Read a value from touch controller
* @return The value read from the controller
*
* params[in] port The controller port to read.
*
* @notapi
*/
static __inline uint16_t read_value(uint16_t port) {
static uint8_t txbuf[3] = {0};
static uint8_t rxbuf[3] = {0};
uint16_t ret;
txbuf[0] = port;
spiExchange(&SPID1, 3, txbuf, rxbuf);
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
return ret;
}
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
/** @} */

View File

@ -0,0 +1,103 @@
/*
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/>.
*/
/**
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_board_olimex_stm32_e407.h
* @brief GINPUT Touch low level driver source for the ADS7843 on an Olimex STM32E407.
*
* @defgroup Mouse Mouse
* @ingroup GINPUT
* @{
*/
#ifndef _GINPUT_LLD_MOUSE_BOARD_H
#define _GINPUT_LLD_MOUSE_BOARD_H
static const SPIConfig spicfg = {
NULL,
GPIOG,
10,
/* SPI_CR1_BR_2 |*/ SPI_CR1_BR_1 | SPI_CR1_BR_0,
};
/**
* @brief Initialise the board for the touch.
*
* @notapi
*/
static __inline void init_board(void) {
spiStart(&SPID2, &spicfg);
}
/**
* @brief Check whether the surface is currently touched
* @return TRUE if the surface is currently touched
*
* @notapi
*/
static __inline bool_t getpin_pressed(void) {
return (!palReadPad(GPIOG, 0));
}
/**
* @brief Aquire the bus ready for readings
*
* @notapi
*/
static __inline void aquire_bus(void) {
spiAcquireBus(&SPID2);
//TOUCHSCREEN_SPI_PROLOGUE();
palClearPad(GPIOG, 10);
}
/**
* @brief Release the bus after readings
*
* @notapi
*/
static __inline void release_bus(void) {
palSetPad(GPIOG, 10);
spiReleaseBus(&SPID2);
//TOUCHSCREEN_SPI_EPILOGUE();
}
/**
* @brief Read a value from touch controller
* @return The value read from the controller
*
* params[in] port The controller port to read.
*
* @notapi
*/
static __inline uint16_t read_value(uint16_t port) {
static uint8_t txbuf[3] = {0};
static uint8_t rxbuf[3] = {0};
uint16_t ret;
txbuf[0] = port;
spiExchange(&SPID2, 3, txbuf, rxbuf);
ret = (rxbuf[1] << 5) | (rxbuf[2] >> 3);
return ret;
}
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */
/** @} */

View File

@ -0,0 +1,44 @@
/*
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/>.
*/
/**
* @file drivers/ginput/touch/ADS7843/ginput_lld_mouse_config.h
* @brief GINPUT LLD header file for mouse/touch driver.
*
* @defgroup Mouse Mouse
* @ingroup GINPUT
*
* @{
*/
#ifndef _LLD_GINPUT_MOUSE_CONFIG_H
#define _LLD_GINPUT_MOUSE_CONFIG_H
#define GINPUT_MOUSE_EVENT_TYPE GEVENT_TOUCH
#define GINPUT_MOUSE_NEED_CALIBRATION TRUE
#define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
#define GINPUT_MOUSE_MAX_CALIBRATION_ERROR 5
#define GINPUT_MOUSE_READ_CYCLES 4
#define GINPUT_MOUSE_POLL_PERIOD 25
#define GINPUT_MOUSE_MAX_CLICK_JITTER 10
#define GINPUT_MOUSE_MAX_MOVE_JITTER 2
#define GINPUT_MOUSE_CLICK_TIME 500
#endif /* _LLD_GINPUT_MOUSE_CONFIG_H */
/** @} */

View File

@ -0,0 +1,9 @@
To use this driver:
1. Add in your halconf.h:
a) #define GFX_USE_GINPUT TRUE
b) #define GINPUT_NEED_MOUSE TRUE
2. To your makefile add the following lines:
include $(GFXLIB)/drivers/ginput/touch/ADS7843/ginput_lld.mk

View File

@ -0,0 +1,5 @@
# List the required driver.
GFXSRC += $(GFXLIB)/drivers/ginput/touch/MCU/ginput_lld_mouse.c
# Required include directories
GFXINC += $(GFXLIB)/drivers/ginput/touch/MCU

Some files were not shown because too many files have changed in this diff Show More