Merge branch 'master' into newmouse
commit
0e74c164c3
84
Doxygenfile
84
Doxygenfile
|
@ -1,4 +1,4 @@
|
||||||
# Doxyfile 1.8.6
|
# Doxyfile 1.8.7
|
||||||
|
|
||||||
# This file describes the settings to be used by the documentation system
|
# This file describes the settings to be used by the documentation system
|
||||||
# doxygen (www.doxygen.org) for a project.
|
# doxygen (www.doxygen.org) for a project.
|
||||||
|
@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = docs
|
||||||
|
|
||||||
CREATE_SUBDIRS = NO
|
CREATE_SUBDIRS = NO
|
||||||
|
|
||||||
|
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
|
||||||
|
# characters to appear in the names of generated files. If set to NO, non-ASCII
|
||||||
|
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
|
||||||
|
# U+3044.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
|
ALLOW_UNICODE_NAMES = NO
|
||||||
|
|
||||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||||
# documentation generated by doxygen is written. Doxygen will use this
|
# documentation generated by doxygen is written. Doxygen will use this
|
||||||
# information to generate all constant output in the proper language.
|
# information to generate all constant output in the proper language.
|
||||||
|
@ -275,9 +283,12 @@ OPTIMIZE_OUTPUT_VHDL = NO
|
||||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||||
# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make
|
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
|
||||||
# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
|
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
|
||||||
# (default is Fortran), use: inc=Fortran f=C.
|
# Fortran. In the later case the parser tries to guess whether the code is fixed
|
||||||
|
# or free formatted code, this is the default for Fortran type files), VHDL. For
|
||||||
|
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
|
||||||
|
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
|
||||||
#
|
#
|
||||||
# Note For files without extension you can use no_extension as a placeholder.
|
# Note For files without extension you can use no_extension as a placeholder.
|
||||||
#
|
#
|
||||||
|
@ -516,6 +527,10 @@ HIDE_SCOPE_NAMES = NO
|
||||||
|
|
||||||
SHOW_INCLUDE_FILES = YES
|
SHOW_INCLUDE_FILES = YES
|
||||||
|
|
||||||
|
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
|
||||||
|
# grouped member an include statement to the documentation, telling the reader
|
||||||
|
# which file to include in order to use the member.
|
||||||
|
# The default value is: NO.
|
||||||
|
|
||||||
SHOW_GROUPED_MEMB_INC = NO
|
SHOW_GROUPED_MEMB_INC = NO
|
||||||
|
|
||||||
|
@ -937,7 +952,7 @@ REFERENCES_RELATION = YES
|
||||||
# link to the documentation.
|
# link to the documentation.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
|
|
||||||
REFERENCES_LINK_SOURCE = NO
|
REFERENCES_LINK_SOURCE = YES
|
||||||
|
|
||||||
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
|
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
|
||||||
# source code will show a tooltip with additional information such as prototype,
|
# source code will show a tooltip with additional information such as prototype,
|
||||||
|
@ -979,25 +994,6 @@ USE_HTAGS = NO
|
||||||
|
|
||||||
VERBATIM_HEADERS = NO
|
VERBATIM_HEADERS = NO
|
||||||
|
|
||||||
# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
|
|
||||||
# clang parser (see: http://clang.llvm.org/) for more acurate parsing at the
|
|
||||||
# cost of reduced performance. This can be particularly helpful with template
|
|
||||||
# rich C++ code for which doxygen's built-in parser lacks the necessary type
|
|
||||||
# information.
|
|
||||||
# Note: The availability of this option depends on whether or not doxygen was
|
|
||||||
# compiled with the --with-libclang option.
|
|
||||||
# The default value is: NO.
|
|
||||||
|
|
||||||
CLANG_ASSISTED_PARSING = NO
|
|
||||||
|
|
||||||
# If clang assisted parsing is enabled you can provide the compiler with command
|
|
||||||
# line options that you would normally use when invoking the compiler. Note that
|
|
||||||
# the include paths will already be set by doxygen for the files and directories
|
|
||||||
# specified with INPUT and INCLUDE_PATH.
|
|
||||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
|
|
||||||
|
|
||||||
CLANG_OPTIONS =
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# Configuration options related to the alphabetical class index
|
# Configuration options related to the alphabetical class index
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
@ -1261,7 +1257,8 @@ GENERATE_CHI = NO
|
||||||
CHM_INDEX_ENCODING =
|
CHM_INDEX_ENCODING =
|
||||||
|
|
||||||
# The BINARY_TOC flag controls whether a binary table of contents is generated (
|
# The BINARY_TOC flag controls whether a binary table of contents is generated (
|
||||||
# YES) or a normal table of contents ( NO) in the .chm file.
|
# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
|
||||||
|
# enables the Previous and Next buttons.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||||
|
|
||||||
|
@ -1501,11 +1498,11 @@ SEARCHENGINE = NO
|
||||||
|
|
||||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||||
# implemented using a web server instead of a web client using Javascript. There
|
# implemented using a web server instead of a web client using Javascript. There
|
||||||
# are two flavours of web server based searching depending on the
|
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||||
# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
|
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||||
# searching and an index file used by the script. When EXTERNAL_SEARCH is
|
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||||
# enabled the indexing and searching needs to be provided by external tools. See
|
# and searching needs to be provided by external tools. See the section
|
||||||
# the section "External Indexing and Searching" for details.
|
# "External Indexing and Searching" for details.
|
||||||
# The default value is: NO.
|
# The default value is: NO.
|
||||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||||
|
|
||||||
|
@ -1793,6 +1790,13 @@ MAN_OUTPUT = man
|
||||||
|
|
||||||
MAN_EXTENSION = .3
|
MAN_EXTENSION = .3
|
||||||
|
|
||||||
|
# The MAN_SUBDIR tag determines the name of the directory created within
|
||||||
|
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
|
||||||
|
# MAN_EXTENSION with the initial . removed.
|
||||||
|
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||||
|
|
||||||
|
MAN_SUBDIR =
|
||||||
|
|
||||||
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
|
||||||
# will generate one additional man file for each entity documented in the real
|
# will generate one additional man file for each entity documented in the real
|
||||||
# man page(s). These additional files only source the real man page, but without
|
# man page(s). These additional files only source the real man page, but without
|
||||||
|
@ -1820,18 +1824,6 @@ GENERATE_XML = NO
|
||||||
|
|
||||||
XML_OUTPUT = xml
|
XML_OUTPUT = xml
|
||||||
|
|
||||||
# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a
|
|
||||||
# validating XML parser to check the syntax of the XML files.
|
|
||||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
|
||||||
|
|
||||||
XML_SCHEMA =
|
|
||||||
|
|
||||||
# The XML_DTD tag can be used to specify a XML DTD, which can be used by a
|
|
||||||
# validating XML parser to check the syntax of the XML files.
|
|
||||||
# This tag requires that the tag GENERATE_XML is set to YES.
|
|
||||||
|
|
||||||
XML_DTD =
|
|
||||||
|
|
||||||
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
|
||||||
# listings (including syntax highlighting and cross-referencing information) to
|
# listings (including syntax highlighting and cross-referencing information) to
|
||||||
# the XML output. Note that enabling this will significantly increase the size
|
# the XML output. Note that enabling this will significantly increase the size
|
||||||
|
@ -1978,9 +1970,9 @@ PREDEFINED = __DOXYGEN__
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
|
|
||||||
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
|
||||||
# remove all refrences to function-like macros that are alone on a line, have an
|
# remove all references to function-like macros that are alone on a line, have
|
||||||
# all uppercase name, and do not end with a semicolon. Such function macros are
|
# an all uppercase name, and do not end with a semicolon. Such function macros
|
||||||
# typically used for boiler-plate code, and will confuse the parser if not
|
# are typically used for boiler-plate code, and will confuse the parser if not
|
||||||
# removed.
|
# removed.
|
||||||
# The default value is: YES.
|
# The default value is: YES.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
@ -2000,7 +1992,7 @@ SKIP_FUNCTION_MACROS = NO
|
||||||
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
|
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
|
||||||
# section "Linking to external documentation" for more information about the use
|
# section "Linking to external documentation" for more information about the use
|
||||||
# of tag files.
|
# of tag files.
|
||||||
# Note: Each tag file must have an unique name (where the name does NOT include
|
# Note: Each tag file must have a unique name (where the name does NOT include
|
||||||
# the path). If a tag file is not located in the directory in which doxygen is
|
# the path). If a tag file is not located in the directory in which doxygen is
|
||||||
# run, you must also specify the path to the tagfile here.
|
# run, you must also specify the path to the tagfile here.
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,8 @@ static inline void setwritemode(GDisplay *g)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t read_data(GDisplay *g) {
|
static inline uint16_t read_data(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
|
||||||
return palReadPort(GPIOE);
|
return palReadPort(GPIOE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
GFXINC += $(GFXLIB)/boards/base/RaspberryPi
|
||||||
|
GFXSRC += $(GFXLIB)/boards/base/RaspberryPi/rpi_mailbox.c
|
||||||
|
|
||||||
|
include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Set this to your frame buffer pixel format and size. You can also override these in your makefile.
|
||||||
|
#ifndef GDISP_LLD_PIXELFORMAT
|
||||||
|
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
|
||||||
|
#endif
|
||||||
|
#ifndef GDISP_SCREEN_WIDTH
|
||||||
|
#define GDISP_SCREEN_WIDTH 800
|
||||||
|
#endif
|
||||||
|
#ifndef GDISP_SCREEN_HEIGHT
|
||||||
|
#define GDISP_SCREEN_HEIGHT 600
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GDISP_DRIVER_VMT
|
||||||
|
|
||||||
|
#if GDISP_SCREEN_WIDTH > 4096 || GDISP_SCREEN_HEIGHT > 4096
|
||||||
|
#error "Raspberry Pi Framebuffer: Screen size is defined too large. Max is 4096x4096"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rpi_mailbox.h"
|
||||||
|
|
||||||
|
typedef struct FrameBufferDescription {
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t vWidth;
|
||||||
|
uint32_t vHeight;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t bitDepth;
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
void * pointer;
|
||||||
|
uint32_t size;
|
||||||
|
} FrameBufferDescription;
|
||||||
|
|
||||||
|
static FrameBufferDescription FrameBufferInfo __attribute__((aligned (16))) = { 1024, 768, 1024, 768, 0, 24, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
static void board_init(GDisplay *g, fbInfo *fbi) {
|
||||||
|
// Initialize the Raspberry Pi frame buffer
|
||||||
|
|
||||||
|
FrameBufferInfo.width = GDISP_SCREEN_WIDTH;
|
||||||
|
FrameBufferInfo.height = GDISP_SCREEN_HEIGHT;
|
||||||
|
FrameBufferInfo.vWidth = GDISP_SCREEN_WIDTH;
|
||||||
|
FrameBufferInfo.vHeight = GDISP_SCREEN_HEIGHT;
|
||||||
|
FrameBufferInfo.bitDepth = LLDCOLOR_BITS;
|
||||||
|
|
||||||
|
rpi_writemailbox(1, 0x40000000 + (uint32_t) &FrameBufferInfo);
|
||||||
|
|
||||||
|
if (rpi_readmailbox(1) != 0)
|
||||||
|
gfxHalt("Could not set display parameters")
|
||||||
|
|
||||||
|
// Set the details of the frame buffer
|
||||||
|
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||||
|
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||||
|
g->g.Backlight = 100;
|
||||||
|
g->g.Contrast = 50;
|
||||||
|
fbi->linelen = g->g.Width * sizeof(LLDCOLOR_TYPE); // bytes per row
|
||||||
|
fbi->pixels = FrameBufferInfo.pointer; // pointer to the memory frame buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_FLUSH
|
||||||
|
static void board_flush(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
static void board_backlight(GDisplay *g, uint8_t percent) {
|
||||||
|
(void) g;
|
||||||
|
(void) percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void board_contrast(GDisplay *g, uint8_t percent) {
|
||||||
|
(void) g;
|
||||||
|
(void) percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void board_power(GDisplay *g, powermode_t pwr) {
|
||||||
|
(void) g;
|
||||||
|
(void) pwr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GDISP_DRIVER_VMT */
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef _BCM2835_INTC_H_
|
||||||
|
#define _BCM2835_INTC_H_
|
||||||
|
|
||||||
|
//#include "bcm2835.h"
|
||||||
|
|
||||||
|
#define BCM2835_INTC_TOTAL_IRQ 64 + 8
|
||||||
|
|
||||||
|
#define BCM2835_BASE_INTC (0x2000B200)
|
||||||
|
#define BCM2835_INTC_IRQ_BASIC (BCM2835_BASE_INTC + 0x00)
|
||||||
|
#define BCM2835_IRQ_PENDING1 (BCM2835_BASE_INTC + 0x04)
|
||||||
|
#define BCM2835_IRQ_PENDING2 (BCM2835_BASE_INTC + 0x08)
|
||||||
|
#define BCM2835_IRQ_FIQ_CTRL (BCM2835_BASE_INTC + 0x0C)
|
||||||
|
#define BCM2835_IRQ_ENABLE1 (BCM2835_BASE_INTC + 0x10)
|
||||||
|
#define BCM2835_IRQ_ENABLE2 (BCM2835_BASE_INTC + 0x14)
|
||||||
|
#define BCM2835_IRQ_ENABLE_BASIC (BCM2835_BASE_INTC + 0x18)
|
||||||
|
#define BCM2835_IRQ_DISABLE1 (BCM2835_BASE_INTC + 0x1C)
|
||||||
|
#define BCM2835_IRQ_DISABLE2 (BCM2835_BASE_INTC + 0x20)
|
||||||
|
#define BCM2835_IRQ_DISABLE_BASIC (BCM2835_BASE_INTC + 0x24)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define BCM2835_IRQ_ID_AUX 29
|
||||||
|
#define BCM2835_IRQ_ID_SPI_SLAVE 43
|
||||||
|
#define BCM2835_IRQ_ID_PWA0 45
|
||||||
|
#define BCM2835_IRQ_ID_PWA1 46
|
||||||
|
#define BCM2835_IRQ_ID_SMI 48
|
||||||
|
#define BCM2835_IRQ_ID_GPIO_0 49
|
||||||
|
#define BCM2835_IRQ_ID_GPIO_1 50
|
||||||
|
#define BCM2835_IRQ_ID_GPIO_2 51
|
||||||
|
#define BCM2835_IRQ_ID_GPIO_3 52
|
||||||
|
#define BCM2835_IRQ_ID_I2C 53
|
||||||
|
#define BCM2835_IRQ_ID_SPI 54
|
||||||
|
#define BCM2835_IRQ_ID_PCM 55
|
||||||
|
#define BCM2835_IRQ_ID_UART 57
|
||||||
|
|
||||||
|
|
||||||
|
#define BCM2835_IRQ_ID_TIMER_0 64
|
||||||
|
#define BCM2835_IRQ_ID_MAILBOX_0 65
|
||||||
|
#define BCM2835_IRQ_ID_DOORBELL_0 66
|
||||||
|
#define BCM2835_IRQ_ID_DOORBELL_1 67
|
||||||
|
#define BCM2835_IRQ_ID_GPU0_HALTED 68
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,134 @@
|
||||||
|
/**
|
||||||
|
* Quick and very Dirty GPIO API.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long GPFSEL[6]; ///< Function selection registers.
|
||||||
|
unsigned long Reserved_1;
|
||||||
|
unsigned long GPSET[2];
|
||||||
|
unsigned long Reserved_2;
|
||||||
|
unsigned long GPCLR[2];
|
||||||
|
unsigned long Reserved_3;
|
||||||
|
unsigned long GPLEV[2];
|
||||||
|
unsigned long Reserved_4;
|
||||||
|
unsigned long GPEDS[2];
|
||||||
|
unsigned long Reserved_5;
|
||||||
|
unsigned long GPREN[2];
|
||||||
|
unsigned long Reserved_6;
|
||||||
|
unsigned long GPFEN[2];
|
||||||
|
unsigned long Reserved_7;
|
||||||
|
unsigned long GPHEN[2];
|
||||||
|
unsigned long Reserved_8;
|
||||||
|
unsigned long GPLEN[2];
|
||||||
|
unsigned long Reserved_9;
|
||||||
|
unsigned long GPAREN[2];
|
||||||
|
unsigned long Reserved_A;
|
||||||
|
unsigned long GPAFEN[2];
|
||||||
|
unsigned long Reserved_B;
|
||||||
|
unsigned long GPPUD[1];
|
||||||
|
unsigned long GPPUDCLK[2];
|
||||||
|
//Ignoring the reserved and test bytes
|
||||||
|
} BCM2835_GPIO_REGS;
|
||||||
|
|
||||||
|
volatile BCM2835_GPIO_REGS * const pRegs = (BCM2835_GPIO_REGS *) (0x20200000);
|
||||||
|
|
||||||
|
|
||||||
|
void SetGpioFunction(unsigned int pinNum, unsigned int funcNum) {
|
||||||
|
|
||||||
|
int offset = pinNum / 10;
|
||||||
|
|
||||||
|
unsigned long val = pRegs->GPFSEL[offset]; // Read in the original register value.
|
||||||
|
|
||||||
|
int item = pinNum % 10;
|
||||||
|
val &= ~(0x7 << (item * 3));
|
||||||
|
val |= ((funcNum & 0x7) << (item * 3));
|
||||||
|
pRegs->GPFSEL[offset] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetGpioDirection(unsigned int pinNum, enum GPIO_DIR dir) {
|
||||||
|
SetGpioFunction(pinNum,dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetGpio(unsigned int pinNum, unsigned int pinVal) {
|
||||||
|
unsigned long offset=pinNum/32;
|
||||||
|
unsigned long mask=(1<<(pinNum%32));
|
||||||
|
|
||||||
|
if(pinVal) {
|
||||||
|
pRegs->GPSET[offset]|=mask;
|
||||||
|
} else {
|
||||||
|
pRegs->GPCLR[offset]|=mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ReadGpio(unsigned int pinNum) {
|
||||||
|
return ((pRegs->GPLEV[pinNum/32])>>(pinNum%32))&1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
|
||||||
|
{
|
||||||
|
unsigned long mask=(1<<pinNum);
|
||||||
|
unsigned long offset=pinNum/32;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case DETECT_RISING:
|
||||||
|
pRegs->GPREN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_FALLING:
|
||||||
|
pRegs->GPFEN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_HIGH:
|
||||||
|
pRegs->GPHEN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_LOW:
|
||||||
|
pRegs->GPLEN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_RISING_ASYNC:
|
||||||
|
pRegs->GPAREN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_FALLING_ASYNC:
|
||||||
|
pRegs->GPAFEN[offset]|=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type)
|
||||||
|
{
|
||||||
|
unsigned long mask=~(1<<(pinNum%32));
|
||||||
|
unsigned long offset=pinNum/32;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case DETECT_RISING:
|
||||||
|
pRegs->GPREN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_FALLING:
|
||||||
|
pRegs->GPFEN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_HIGH:
|
||||||
|
pRegs->GPHEN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_LOW:
|
||||||
|
pRegs->GPLEN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_RISING_ASYNC:
|
||||||
|
pRegs->GPAREN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_FALLING_ASYNC:
|
||||||
|
pRegs->GPAFEN[offset]&=mask;
|
||||||
|
break;
|
||||||
|
case DETECT_NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearGpioInterrupt(unsigned int pinNum)
|
||||||
|
{
|
||||||
|
unsigned long mask=(1<<(pinNum%32));
|
||||||
|
unsigned long offset=pinNum/32;
|
||||||
|
|
||||||
|
pRegs->GPEDS[offset]=mask;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
#ifndef _GPIO_H_
|
||||||
|
#define _GPIO_H_
|
||||||
|
|
||||||
|
/* GPIO event detect types */
|
||||||
|
enum DETECT_TYPE {
|
||||||
|
DETECT_NONE,
|
||||||
|
DETECT_RISING,
|
||||||
|
DETECT_FALLING,
|
||||||
|
DETECT_HIGH,
|
||||||
|
DETECT_LOW,
|
||||||
|
DETECT_RISING_ASYNC,
|
||||||
|
DETECT_FALLING_ASYNC
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GPIO pull up or down states */
|
||||||
|
enum PULL_STATE {
|
||||||
|
PULL_DISABLE,
|
||||||
|
PULL_UP,
|
||||||
|
PULL_DOWN,
|
||||||
|
PULL_RESERVED
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Pin data direction */
|
||||||
|
enum GPIO_DIR {
|
||||||
|
GPIO_IN,
|
||||||
|
GPIO_OUT
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GPIO pin setup */
|
||||||
|
void SetGpioFunction (unsigned int pinNum, unsigned int funcNum);
|
||||||
|
/* A simple wrapper around SetGpioFunction */
|
||||||
|
void SetGpioDirection (unsigned int pinNum, enum GPIO_DIR dir);
|
||||||
|
|
||||||
|
/* Set GPIO output level */
|
||||||
|
void SetGpio (unsigned int pinNum, unsigned int pinVal);
|
||||||
|
|
||||||
|
/* Read GPIO pin level */
|
||||||
|
int ReadGpio (unsigned int pinNum);
|
||||||
|
|
||||||
|
/* GPIO pull up/down resistor control function (NOT YET IMPLEMENTED) */
|
||||||
|
int PudGpio (unsigned int pinNum, enum PULL_STATE state);
|
||||||
|
|
||||||
|
/* Interrupt related functions */
|
||||||
|
void EnableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type);
|
||||||
|
void DisableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type);
|
||||||
|
void ClearGpioInterrupt (unsigned int pinNum);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* Integrated Interrupt Controller for RaspberryPi.
|
||||||
|
* @author James Walmsley <james@fullfat-fs.co.uk>
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "interrupts.h"
|
||||||
|
#include "bcm2835_intc.h"
|
||||||
|
|
||||||
|
static INTERRUPT_VECTOR g_VectorTable[BCM2835_INTC_TOTAL_IRQ];
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned long IRQBasic; // Pending 0
|
||||||
|
unsigned long Pending1;
|
||||||
|
unsigned long Pending2;
|
||||||
|
unsigned long FIQCtrl;
|
||||||
|
unsigned long Enable1;
|
||||||
|
unsigned long Enable2;
|
||||||
|
unsigned long EnableBasic;
|
||||||
|
unsigned long Disable1;
|
||||||
|
unsigned long Disable2;
|
||||||
|
unsigned long DisableBasic;
|
||||||
|
} BCM2835_INTC_REGS;
|
||||||
|
|
||||||
|
static volatile BCM2835_INTC_REGS * const pRegs = (BCM2835_INTC_REGS *) (BCM2835_BASE_INTC);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables all IRQ's in the CPU's CPSR register.
|
||||||
|
**/
|
||||||
|
static void irqEnable() {
|
||||||
|
__asm volatile("mrs r0,cpsr"); // Read in the cpsr register.
|
||||||
|
__asm volatile("bic r0,r0,#0x80"); // Clear bit 8, (0x80) -- Causes IRQs to be enabled.
|
||||||
|
__asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register
|
||||||
|
}
|
||||||
|
|
||||||
|
static void irqDisable() {
|
||||||
|
__asm volatile("mrs r0,cpsr"); // Read in the cpsr register.
|
||||||
|
__asm volatile("orr r0,r0,#0x80"); // Set bit 8, (0x80) -- Causes IRQs to be disabled.
|
||||||
|
__asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define clz(a) \
|
||||||
|
({ unsigned long __value, __arg = (a); \
|
||||||
|
asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \
|
||||||
|
__value; })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the global IRQ handler on this platform!
|
||||||
|
* It is based on the assembler code found in the Broadcom datasheet.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
void irqHandler() {
|
||||||
|
register unsigned long ulMaskedStatus;
|
||||||
|
register unsigned long irqNumber;
|
||||||
|
|
||||||
|
ulMaskedStatus = pRegs->IRQBasic;
|
||||||
|
|
||||||
|
/* Bits 7 through 0 in IRQBasic represent interrupts 64-71 */
|
||||||
|
if (ulMaskedStatus & 0xFF) {
|
||||||
|
irqNumber=64 + 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0) */
|
||||||
|
else if(ulMaskedStatus & 0x100) {
|
||||||
|
ulMaskedStatus = pRegs->Pending1;
|
||||||
|
irqNumber = 0 + 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32) */
|
||||||
|
else if(ulMaskedStatus & 0x200) {
|
||||||
|
ulMaskedStatus = pRegs->Pending2;
|
||||||
|
irqNumber = 32 + 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// No interrupt avaialbe, so just return.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep only least significant bit, in case multiple interrupts have occured */
|
||||||
|
ulMaskedStatus&=-ulMaskedStatus;
|
||||||
|
/* Some magic to determine number of interrupt to serve */
|
||||||
|
irqNumber=irqNumber-clz(ulMaskedStatus);
|
||||||
|
/* Call interrupt handler */
|
||||||
|
g_VectorTable[irqNumber].pfnHandler(irqNumber, g_VectorTable[irqNumber].pParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void stubHandler(int nIRQ, void *pParam) {
|
||||||
|
/**
|
||||||
|
* Actually if we get here, we should probably disable the IRQ,
|
||||||
|
* otherwise we could lock up this system, as there is nothing to
|
||||||
|
* ackknowledge the interrupt.
|
||||||
|
**/
|
||||||
|
}
|
||||||
|
|
||||||
|
int InitInterruptController() {
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < BCM2835_INTC_TOTAL_IRQ; i++) {
|
||||||
|
g_VectorTable[i].pfnHandler = stubHandler;
|
||||||
|
g_VectorTable[i].pParam = (void *) 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int RegisterInterrupt(int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam) {
|
||||||
|
if(nIRQ<0 || nIRQ>71)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
irqDisable();
|
||||||
|
{
|
||||||
|
g_VectorTable[nIRQ].pfnHandler = pfnHandler;
|
||||||
|
g_VectorTable[nIRQ].pParam = pParam;
|
||||||
|
}
|
||||||
|
irqEnable();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EnableInterrupt(int nIRQ) {
|
||||||
|
/* Datasheet says "All other bits are unaffected", and I'm counting on that. */
|
||||||
|
unsigned int mask=1<<(nIRQ%32);
|
||||||
|
|
||||||
|
if(nIRQ >=0 && nIRQ <=31) {
|
||||||
|
pRegs->Enable1 = mask;
|
||||||
|
} else
|
||||||
|
if(nIRQ >=32 && nIRQ <=63){
|
||||||
|
pRegs->Enable2 = mask;
|
||||||
|
} else
|
||||||
|
if(nIRQ >= 64 && nIRQ <= 71) { // Basic IRQ enables
|
||||||
|
pRegs->EnableBasic = mask;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisableInterrupt(int nIRQ) {
|
||||||
|
/* Datasheet says "All other bits are unaffected", and I'm counting on that. */
|
||||||
|
unsigned int mask=1<<(nIRQ%32);
|
||||||
|
|
||||||
|
if(nIRQ >=0 && nIRQ <=31) {
|
||||||
|
pRegs->Disable1 = mask;
|
||||||
|
} else
|
||||||
|
if(nIRQ >=32 && nIRQ <=63){
|
||||||
|
pRegs->Disable2 = mask;
|
||||||
|
} else
|
||||||
|
if(nIRQ >= 64 && nIRQ <= 71) {
|
||||||
|
pRegs->DisableBasic = mask;
|
||||||
|
} else
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EnableInterrupts() {
|
||||||
|
irqEnable();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisableInterrupts() {
|
||||||
|
irqDisable();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* Tiny Interrupt Manager
|
||||||
|
*
|
||||||
|
* @author James Walmsley <james@fullfat-fs.co.uk>
|
||||||
|
* This code is licensed under the GNU GPLv3 license.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef _INTERRUPTS_H_
|
||||||
|
#define _INTERRUPTS_H_
|
||||||
|
|
||||||
|
typedef void (*FN_INTERRUPT_HANDLER)(int nIRQ, void *pParam);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FN_INTERRUPT_HANDLER pfnHandler; ///< Function that handles this IRQn
|
||||||
|
void *pParam; ///< A special parameter that the use can pass to the IRQ.
|
||||||
|
} INTERRUPT_VECTOR;
|
||||||
|
|
||||||
|
int InitInterruptController ();
|
||||||
|
int RegisterInterrupt (int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam);
|
||||||
|
int EnableInterrupt (int nIRQ);
|
||||||
|
int DisableInterrupt (int nIRQ);
|
||||||
|
int EnableInterrupts ();
|
||||||
|
int DisableInterrupts ();
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* mmio.h - access to MMIO registers */
|
||||||
|
|
||||||
|
#ifndef MMIO_H
|
||||||
|
#define MMIO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// write to MMIO register
|
||||||
|
static inline void mmio_write(uint32_t reg, uint32_t data) {
|
||||||
|
uint32_t *ptr = (uint32_t*)reg;
|
||||||
|
asm volatile("str %[data], [%[reg]]"
|
||||||
|
: : [reg]"r"(ptr), [data]"r"(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
// read from MMIO register
|
||||||
|
static inline uint32_t mmio_read(uint32_t reg) {
|
||||||
|
uint32_t *ptr = (uint32_t*)reg;
|
||||||
|
uint32_t data;
|
||||||
|
asm volatile("ldr %[data], [%[reg]]"
|
||||||
|
: [data]"=r"(data) : [reg]"r"(ptr));
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef MMIO_H
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* uart.c - UART initialization & communication */
|
||||||
|
/* Reference material:
|
||||||
|
* http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
|
||||||
|
* Chapter 13: UART
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <mmio.h>
|
||||||
|
#include <uart.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
// The GPIO registers base address.
|
||||||
|
GPIO_BASE = 0x20200000,
|
||||||
|
|
||||||
|
// The offsets for reach register.
|
||||||
|
|
||||||
|
// Controls actuation of pull up/down to ALL GPIO pins.
|
||||||
|
GPPUD = (GPIO_BASE + 0x94),
|
||||||
|
|
||||||
|
// Controls actuation of pull up/down for specific GPIO pin.
|
||||||
|
GPPUDCLK0 = (GPIO_BASE + 0x98),
|
||||||
|
|
||||||
|
// The base address for UART.
|
||||||
|
UART0_BASE = 0x20201000,
|
||||||
|
|
||||||
|
// The offsets for reach register for the UART.
|
||||||
|
UART0_DR = (UART0_BASE + 0x00),
|
||||||
|
UART0_RSRECR = (UART0_BASE + 0x04),
|
||||||
|
UART0_FR = (UART0_BASE + 0x18),
|
||||||
|
UART0_ILPR = (UART0_BASE + 0x20),
|
||||||
|
UART0_IBRD = (UART0_BASE + 0x24),
|
||||||
|
UART0_FBRD = (UART0_BASE + 0x28),
|
||||||
|
UART0_LCRH = (UART0_BASE + 0x2C),
|
||||||
|
UART0_CR = (UART0_BASE + 0x30),
|
||||||
|
UART0_IFLS = (UART0_BASE + 0x34),
|
||||||
|
UART0_IMSC = (UART0_BASE + 0x38),
|
||||||
|
UART0_RIS = (UART0_BASE + 0x3C),
|
||||||
|
UART0_MIS = (UART0_BASE + 0x40),
|
||||||
|
UART0_ICR = (UART0_BASE + 0x44),
|
||||||
|
UART0_DMACR = (UART0_BASE + 0x48),
|
||||||
|
UART0_ITCR = (UART0_BASE + 0x80),
|
||||||
|
UART0_ITIP = (UART0_BASE + 0x84),
|
||||||
|
UART0_ITOP = (UART0_BASE + 0x88),
|
||||||
|
UART0_TDR = (UART0_BASE + 0x8C),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* delay function
|
||||||
|
* int32_t delay: number of cycles to delay
|
||||||
|
*
|
||||||
|
* This just loops <delay> times in a way that the compiler
|
||||||
|
* wont optimize away.
|
||||||
|
*/
|
||||||
|
static void delay(int32_t count) {
|
||||||
|
asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n"
|
||||||
|
: : [count]"r"(count) : "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize UART0.
|
||||||
|
*/
|
||||||
|
void uart_init() {
|
||||||
|
// Disable UART0.
|
||||||
|
mmio_write(UART0_CR, 0x00000000);
|
||||||
|
// Setup the GPIO pin 14 && 15.
|
||||||
|
|
||||||
|
// Disable pull up/down for all GPIO pins & delay for 150 cycles.
|
||||||
|
mmio_write(GPPUD, 0x00000000);
|
||||||
|
delay(150);
|
||||||
|
|
||||||
|
// Disable pull up/down for pin 14,15 & delay for 150 cycles.
|
||||||
|
mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15));
|
||||||
|
delay(150);
|
||||||
|
|
||||||
|
// Write 0 to GPPUDCLK0 to make it take effect.
|
||||||
|
mmio_write(GPPUDCLK0, 0x00000000);
|
||||||
|
|
||||||
|
// Clear pending interrupts.
|
||||||
|
mmio_write(UART0_ICR, 0x7FF);
|
||||||
|
|
||||||
|
// Set integer & fractional part of baud rate.
|
||||||
|
// Divider = UART_CLOCK/(16 * Baud)
|
||||||
|
// Fraction part register = (Fractional part * 64) + 0.5
|
||||||
|
// UART_CLOCK = 3000000; Baud = 115200.
|
||||||
|
|
||||||
|
// Divider = 3000000/(16 * 115200) = 1.627 = ~1.
|
||||||
|
// Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40.
|
||||||
|
mmio_write(UART0_IBRD, 1);
|
||||||
|
mmio_write(UART0_FBRD, 40);
|
||||||
|
|
||||||
|
// Enable FIFO & 8 bit data transmissio (1 stop bit, no parity).
|
||||||
|
mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6));
|
||||||
|
|
||||||
|
// Mask all interrupts.
|
||||||
|
mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) |
|
||||||
|
(1 << 6) | (1 << 7) | (1 << 8) |
|
||||||
|
(1 << 9) | (1 << 10));
|
||||||
|
|
||||||
|
// Enable UART0, receive & transfer part of UART.
|
||||||
|
mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transmit a byte via UART0.
|
||||||
|
* uint8_t Byte: byte to send.
|
||||||
|
*/
|
||||||
|
void uart_putc(uint8_t byte) {
|
||||||
|
// wait for UART to become ready to transmit
|
||||||
|
while (1) {
|
||||||
|
if (!(mmio_read(UART0_FR) & (1 << 5))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mmio_write(UART0_DR, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print a string to the UART one character at a time
|
||||||
|
* const char *str: 0-terminated string
|
||||||
|
*/
|
||||||
|
void uart_puts(const char *str) {
|
||||||
|
while (*str) {
|
||||||
|
uart_putc(*str++);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/* uart.h - UART initialization & communication */
|
||||||
|
|
||||||
|
#ifndef UART_H
|
||||||
|
#define UART_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize UART0.
|
||||||
|
*/
|
||||||
|
void uart_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transmit a byte via UART0.
|
||||||
|
* uint8_t Byte: byte to send.
|
||||||
|
*/
|
||||||
|
void uart_putc(uint8_t byte);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print a string to the UART one character at a time
|
||||||
|
* const char *str: 0-terminated string
|
||||||
|
*/
|
||||||
|
void uart_puts(const char *str);
|
||||||
|
|
||||||
|
#endif // #ifndef UART_H
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
FreeRTOS V8.0.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS provides completely free yet professionally developed, *
|
||||||
|
* robust, strictly quality controlled, supported, and cross *
|
||||||
|
* platform software that has become a de facto standard. *
|
||||||
|
* *
|
||||||
|
* Help yourself get started quickly and support the FreeRTOS *
|
||||||
|
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||||
|
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||||
|
* *
|
||||||
|
* Thank you! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||||
|
|
||||||
|
>>! NOTE: The modification to the GPL is included to allow you to distribute
|
||||||
|
>>! a combined work that includes FreeRTOS without being obliged to provide
|
||||||
|
>>! the source code for proprietary components outside of the FreeRTOS
|
||||||
|
>>! kernel.
|
||||||
|
|
||||||
|
FreeRTOS 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. Full license text is available from the following
|
||||||
|
link: http://www.freertos.org/a00114.html
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||||
|
license and Real Time Engineers Ltd. contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||||
|
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||||
|
|
||||||
|
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||||
|
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||||
|
licenses offer ticketed support, indemnification and middleware.
|
||||||
|
|
||||||
|
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||||
|
engineered and independently SIL3 certified version for use in safety and
|
||||||
|
mission critical applications that require provable dependability.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FREERTOS_CONFIG_H
|
||||||
|
#define FREERTOS_CONFIG_H
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------
|
||||||
|
* Application specific definitions.
|
||||||
|
*
|
||||||
|
* These definitions should be adjusted for your particular hardware and
|
||||||
|
* application requirements.
|
||||||
|
*
|
||||||
|
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||||
|
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||||
|
*
|
||||||
|
* See http://www.freertos.org/a00110.html.
|
||||||
|
*----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define configUSE_PREEMPTION 1
|
||||||
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||||
|
#define configUSE_IDLE_HOOK 0
|
||||||
|
#define configUSE_TICK_HOOK 0
|
||||||
|
#define configTICK_RATE_HZ ( ( portTickType ) 1000 )
|
||||||
|
#define configCPU_CLOCK_HZ ( ( unsigned long ) 24000000 )
|
||||||
|
#define configPERIPHERAL_CLOCK_HZ ( 40000000UL )
|
||||||
|
#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 )
|
||||||
|
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
|
||||||
|
#define configISR_STACK_SIZE ( 250 )
|
||||||
|
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 4096 ) )
|
||||||
|
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||||
|
#define configUSE_TRACE_FACILITY 0
|
||||||
|
#define configUSE_16_BIT_TICKS 0
|
||||||
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
|
#define configUSE_MUTEXES 1
|
||||||
|
#define configCHECK_FOR_STACK_OVERFLOW 3
|
||||||
|
#define configQUEUE_REGISTRY_SIZE 0
|
||||||
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||||
|
#define configUSE_APPLICATION_TASK_TAG 1
|
||||||
|
#define configUSE_COUNTING_SEMAPHORES 1
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 0
|
||||||
|
|
||||||
|
|
||||||
|
/* Co-routine definitions. */
|
||||||
|
#define configUSE_CO_ROUTINES 0
|
||||||
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
|
to exclude the API function. */
|
||||||
|
|
||||||
|
#define INCLUDE_vTaskPrioritySet 1
|
||||||
|
#define INCLUDE_uxTaskPriorityGet 1
|
||||||
|
#define INCLUDE_vTaskDelete 1
|
||||||
|
#define INCLUDE_vTaskCleanUpResources 0
|
||||||
|
#define INCLUDE_vTaskSuspend 1
|
||||||
|
#define INCLUDE_vTaskDelayUntil 1
|
||||||
|
#define INCLUDE_vTaskDelay 1
|
||||||
|
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||||
|
#define INCLUDE_eTaskGetState 1
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
|
||||||
|
(lowest) to 0 (1?) (highest). */
|
||||||
|
#define configKERNEL_INTERRUPT_PRIORITY 255
|
||||||
|
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||||
|
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||||
|
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 /* equivalent to 0xb0, or priority 11. */
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the value being used as per the ST library which permits 16
|
||||||
|
priority values, 0 to 15. This must correspond to the
|
||||||
|
configKERNEL_INTERRUPT_PRIORITY setting. Here 15 corresponds to the lowest
|
||||||
|
NVIC value of 255. */
|
||||||
|
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15
|
||||||
|
|
||||||
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
# build environment
|
||||||
|
PREFIX ?= /your compiler path/gcc-arm-none-eabi-4_8-2014q1
|
||||||
|
ARCH ?= $(PREFIX)/bin/arm-none-eabi
|
||||||
|
|
||||||
|
CC = ${ARCH}-gcc
|
||||||
|
CPP = ${ARCH}-g++
|
||||||
|
AS = ${ARCH}-as
|
||||||
|
LD = ${ARCH}-ld
|
||||||
|
AR = ${ARCH}-ar
|
||||||
|
OBJCOPY = ${ARCH}-objcopy
|
||||||
|
|
||||||
|
PLATFORM = raspi
|
||||||
|
LINKER_SCRIPT = raspberrypi.ld
|
||||||
|
|
||||||
|
CFLAGS = -march=armv6z -g -Wall -Wextra
|
||||||
|
ASFLAGS = -g
|
||||||
|
|
||||||
|
CFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s
|
||||||
|
ASFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s
|
||||||
|
LDFLAGS = #--error-unresolved-symbols
|
||||||
|
|
||||||
|
GFXLIB := ../uGFX
|
||||||
|
include $(GFXLIB)/gfx.mk
|
||||||
|
include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk
|
||||||
|
|
||||||
|
OSLIB := ../FreeRTOS
|
||||||
|
MODULES := $(OSLIB)/Source/portable/GCC/RaspberryPi
|
||||||
|
MODULES += $(OSLIB)/Source/portable/MemMang
|
||||||
|
MODULES += $(OSLIB)/Source
|
||||||
|
MODULES += Drivers
|
||||||
|
|
||||||
|
SRC_DIR := $(MODULES)
|
||||||
|
INC_DIR := $(addsuffix /include,$(SRC_DIR))
|
||||||
|
BUILD_DIR := $(addsuffix /build,$(SRC_DIR))
|
||||||
|
|
||||||
|
INCLUDEDIRS := $(OSLIB)/Source/portable/GCC/RaspberryPi
|
||||||
|
INCLUDEDIRS += $(OSLIB)/Source/include
|
||||||
|
INCLUDEDIRS += Drivers
|
||||||
|
INCLUDEDIRS += $(GFXINC)
|
||||||
|
|
||||||
|
INCLUDES := $(addprefix -I,$(INCLUDEDIRS))
|
||||||
|
|
||||||
|
ASRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.s))
|
||||||
|
AOBJ := $(ASRC:.s=.o)
|
||||||
|
CSRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c))
|
||||||
|
CSRC += $(GFXSRC)
|
||||||
|
COBJ := $(CSRC:.c=.o)
|
||||||
|
|
||||||
|
vpath %.c $(SRC_DIR)
|
||||||
|
vpath %.cpp $(SRC_DIR)
|
||||||
|
vpath %.s $(SRC_DIR)
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c -o $*.o $<
|
||||||
|
|
||||||
|
%.o: %.s
|
||||||
|
$(AS) $(ASFLAGS_FOR_TARGET) $(INCLUDES) $(ASFLAGS) -o $*.o $<
|
||||||
|
|
||||||
|
OBJ = $(AOBJ) $(COBJ)
|
||||||
|
|
||||||
|
bin/kernel.img: bin/kernel.elf
|
||||||
|
${OBJCOPY} -O binary $< $@
|
||||||
|
|
||||||
|
bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/lib/gcc/arm-none-eabi/4.8.3" -lgcc
|
||||||
|
bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/arm-none-eabi/lib" -lc
|
||||||
|
bin/kernel.elf: $(OBJ)
|
||||||
|
${LD} $(OBJ) -Map bin/kernel.map -o $@ -T $(LINKER_SCRIPT) ${LDFLAGS}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f bin/*.elf bin/*.img bin/*.map $(OBJ)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
|
#include "Drivers/interrupts.h"
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
static void displayTask(void *pvParameters) {
|
||||||
|
coord_t width, height;
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
vTaskDelay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the systems main entry, some call it a boot thread.
|
||||||
|
*
|
||||||
|
* -- Absolutely nothing wrong with this being called main(), just it doesn't have
|
||||||
|
* -- the same prototype as you'd see in a linux program.
|
||||||
|
**/
|
||||||
|
int main(void) {
|
||||||
|
|
||||||
|
DisableInterrupts();
|
||||||
|
InitInterruptController();
|
||||||
|
|
||||||
|
// Initialize and clear the display
|
||||||
|
gfxInit();
|
||||||
|
|
||||||
|
xTaskCreate(displayTask,
|
||||||
|
(portCHAR *)"Display Task",
|
||||||
|
128,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
vTaskStartScheduler();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We should never get here, but just in case something goes wrong,
|
||||||
|
* we'll place the CPU into a safe loop.
|
||||||
|
*/
|
||||||
|
while(1) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
|
||||||
|
{
|
||||||
|
( void ) pcTaskName;
|
||||||
|
( void ) pxTask;
|
||||||
|
|
||||||
|
/* Run time task stack overflow checking is performed if
|
||||||
|
configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
|
||||||
|
called if a task stack overflow is detected. Note the system/interrupt
|
||||||
|
stack is not checked. */
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
for( ;; );
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vApplicationTickHook( void )
|
||||||
|
{
|
||||||
|
/* This function will be called by each tick interrupt if
|
||||||
|
configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be
|
||||||
|
added here, but the tick hook is called from an interrupt context, so
|
||||||
|
code must not attempt to block, and only the interrupt safe FreeRTOS API
|
||||||
|
functions can be used (those that end in FromISR()). */
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* BlueThunder Linker Script for the raspberry Pi!
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
RESERVED (r) : ORIGIN = 0x00000000, LENGTH = 32K
|
||||||
|
INIT_RAM (rwx) : ORIGIN = 0x00008000, LENGTH = 32K
|
||||||
|
RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 128M
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/*
|
||||||
|
* Our init section allows us to place the bootstrap code at address 0x8000
|
||||||
|
*
|
||||||
|
* This is where the Graphics processor forces the ARM to start execution.
|
||||||
|
* However the interrupt vector code remains at 0x0000, and so we must copy the correct
|
||||||
|
* branch instructions to 0x0000 - 0x001C in order to get the processor to handle interrupts.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.init : {
|
||||||
|
KEEP(*(.init))
|
||||||
|
} > INIT_RAM = 0
|
||||||
|
|
||||||
|
.module_entries : {
|
||||||
|
__module_entries_start = .;
|
||||||
|
KEEP(*(.module_entries))
|
||||||
|
KEEP(*(.module_entries.*))
|
||||||
|
__module_entries_end = .;
|
||||||
|
__module_entries_size = SIZEOF(.module_entries);
|
||||||
|
} > INIT_RAM
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the main code section, it is essentially of unlimited size. (128Mb).
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
.text : {
|
||||||
|
*(.text)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Next we put the data.
|
||||||
|
*/
|
||||||
|
.data : {
|
||||||
|
*(.data)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
__bss_end = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place HEAP here???
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stack starts at the top of the RAM, and moves down!
|
||||||
|
**/
|
||||||
|
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
.extern system_init
|
||||||
|
.extern __bss_start
|
||||||
|
.extern __bss_end
|
||||||
|
.extern vFreeRTOS_ISR
|
||||||
|
.extern vPortYieldProcessor
|
||||||
|
.extern DisableInterrupts
|
||||||
|
.extern main
|
||||||
|
.section .init
|
||||||
|
.globl _start
|
||||||
|
;;
|
||||||
|
_start:
|
||||||
|
;@ All the following instruction should be read as:
|
||||||
|
;@ Load the address at symbol into the program counter.
|
||||||
|
|
||||||
|
ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi!
|
||||||
|
;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset!
|
||||||
|
|
||||||
|
ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb!
|
||||||
|
ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode.
|
||||||
|
ldr pc,prefetch_handler ;@ Prefetch/abort handler.
|
||||||
|
ldr pc,data_handler ;@ Data abort handler/
|
||||||
|
ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler.
|
||||||
|
ldr pc,irq_handler ;@ IRQ handler
|
||||||
|
ldr pc,fiq_handler ;@ Fast interrupt handler.
|
||||||
|
|
||||||
|
;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses
|
||||||
|
reset_handler: .word reset
|
||||||
|
undefined_handler: .word undefined_instruction
|
||||||
|
swi_handler: .word vPortYieldProcessor
|
||||||
|
prefetch_handler: .word prefetch_abort
|
||||||
|
data_handler: .word data_abort
|
||||||
|
unused_handler: .word unused
|
||||||
|
irq_handler: .word vFreeRTOS_ISR
|
||||||
|
fiq_handler: .word fiq
|
||||||
|
|
||||||
|
reset:
|
||||||
|
;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000
|
||||||
|
|
||||||
|
mov r0,#0x8000 ;@ Store the source pointer
|
||||||
|
mov r1,#0x0000 ;@ Store the destination pointer.
|
||||||
|
|
||||||
|
;@ Here we copy the branching instructions
|
||||||
|
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0
|
||||||
|
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1
|
||||||
|
|
||||||
|
;@ So the branches get the correct address we also need to copy our vector table!
|
||||||
|
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented.
|
||||||
|
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data.
|
||||||
|
|
||||||
|
|
||||||
|
;@ Set up the various STACK pointers for different CPU modes
|
||||||
|
;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
|
||||||
|
mov r0,#0xD2
|
||||||
|
msr cpsr_c,r0
|
||||||
|
mov sp,#0x8000
|
||||||
|
|
||||||
|
;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
|
||||||
|
mov r0,#0xD1
|
||||||
|
msr cpsr_c,r0
|
||||||
|
mov sp,#0x4000
|
||||||
|
|
||||||
|
;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
|
||||||
|
mov r0,#0xD3
|
||||||
|
msr cpsr_c,r0
|
||||||
|
mov sp,#0x8000000
|
||||||
|
|
||||||
|
ldr r0, =__bss_start
|
||||||
|
ldr r1, =__bss_end
|
||||||
|
|
||||||
|
mov r2, #0
|
||||||
|
|
||||||
|
zero_loop:
|
||||||
|
cmp r0,r1
|
||||||
|
it lt
|
||||||
|
strlt r2,[r0], #4
|
||||||
|
blt zero_loop
|
||||||
|
|
||||||
|
bl DisableInterrupts
|
||||||
|
|
||||||
|
|
||||||
|
;@ mov sp,#0x1000000
|
||||||
|
b main ;@ We're ready?? Lets start main execution!
|
||||||
|
.section .text
|
||||||
|
|
||||||
|
undefined_instruction:
|
||||||
|
b undefined_instruction
|
||||||
|
|
||||||
|
prefetch_abort:
|
||||||
|
b prefetch_abort
|
||||||
|
|
||||||
|
data_abort:
|
||||||
|
b data_abort
|
||||||
|
|
||||||
|
unused:
|
||||||
|
b unused
|
||||||
|
|
||||||
|
fiq:
|
||||||
|
b fiq
|
||||||
|
|
||||||
|
hang:
|
||||||
|
b hang
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
This directory contains the interface for the Raspberry Pi framebuffer.
|
||||||
|
This talks directly to the raspberry pi hardware (not via a linux framebuffer driver).
|
||||||
|
|
||||||
|
This graphics interface is software driven - it is not an accelerated interface.
|
||||||
|
|
||||||
|
This board definition should work on any operating system that will work on the Raspberry Pi
|
||||||
|
eg. Linux, FreeRTOS.
|
||||||
|
|
||||||
|
On this board uGFX currently supports:
|
||||||
|
- GDISP via the framebuffer driver
|
||||||
|
|
||||||
|
THe following variables may optionally be defined in your gfxconf.h or your makefile...
|
||||||
|
- GDISP_LLD_PIXELFORMAT default = GDISP_PIXELFORMAT_RGB565
|
||||||
|
- GDISP_SCREEN_WIDTH default = 800
|
||||||
|
- GDISP_SCREEN_HEIGHT default = 600
|
||||||
|
|
||||||
|
Note that this also provides a Raspberry Pi specific api defined in rpi_mailbox.h to talk
|
||||||
|
directly to the graphics co-processor from the ARM processor.
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Access system mailboxes
|
||||||
|
*/
|
||||||
|
#include "rpi_mailbox.h"
|
||||||
|
|
||||||
|
/* Mailbox memory addresses */
|
||||||
|
static volatile unsigned int *MAILBOX0READ = (unsigned int *) (0x2000b880);
|
||||||
|
static volatile unsigned int *MAILBOX0STATUS = (unsigned int *) (0x2000b898);
|
||||||
|
static volatile unsigned int *MAILBOX0WRITE = (unsigned int *) (0x2000b8a0);
|
||||||
|
|
||||||
|
/* Bit 31 set in status register if the write mailbox is full */
|
||||||
|
#define MAILBOX_FULL 0x80000000
|
||||||
|
|
||||||
|
/* Bit 30 set in status register if the read mailbox is empty */
|
||||||
|
#define MAILBOX_EMPTY 0x40000000
|
||||||
|
|
||||||
|
unsigned int rpi_readmailbox(unsigned int channel)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
if (channel > 15)
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
|
||||||
|
/* Wait for mailbox to be full */
|
||||||
|
while (*MAILBOX0STATUS & MAILBOX_EMPTY);
|
||||||
|
|
||||||
|
val = *MAILBOX0READ;
|
||||||
|
|
||||||
|
if ((val & 15) == channel)
|
||||||
|
return (val & 0xFFFFFFF0);
|
||||||
|
else
|
||||||
|
return 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpi_writemailbox(unsigned int channel, unsigned int data)
|
||||||
|
{
|
||||||
|
if (channel > 15)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (data & 0x000F)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Wait for mailbox to be not full */
|
||||||
|
while (*MAILBOX0STATUS & MAILBOX_FULL);
|
||||||
|
|
||||||
|
*MAILBOX0WRITE = (data | channel);
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef RPI_MAILBOX_H
|
||||||
|
#define RPI_MAILBOX_H
|
||||||
|
|
||||||
|
extern unsigned int readmailbox(unsigned int channel);
|
||||||
|
extern void writemailbox(unsigned int channel, unsigned int data);
|
||||||
|
|
||||||
|
#endif /* RPI_MAILBOX_H */
|
|
@ -0,0 +1,5 @@
|
||||||
|
GFXINC += $(GFXLIB)/boards/base/eCos-Synthetic-Framebuffer
|
||||||
|
GFXSRC +=
|
||||||
|
GFXDEFS += -DGFX_USE_OS_ECOS=TRUE
|
||||||
|
|
||||||
|
include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: this implementation makes a number of design choices...
|
||||||
|
* 1/ We are using the macro definitions for eCos framebuffer driver. If you want to use the
|
||||||
|
* function's instead you could use the g->board variable to store your cyg_fb pointer.
|
||||||
|
* 2/ We assume the initialisation succeeds. It is probably a fatal error if it doesn't.
|
||||||
|
* 3/ We hard-code in this file the pixel format, whether flushing is required and the FRAMEBUF device.
|
||||||
|
* Please adjust them for your hardware.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set this to your frame buffer pixel format.
|
||||||
|
#ifndef GDISP_LLD_PIXELFORMAT
|
||||||
|
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Uncomment this if your frame buffer device requires flushing ("Synch" in eCos speak)
|
||||||
|
#define GDISP_HARDWARE_FLUSH TRUE
|
||||||
|
|
||||||
|
#ifdef GDISP_DRIVER_VMT
|
||||||
|
|
||||||
|
#include <cyg/io/framebuf.h>
|
||||||
|
|
||||||
|
// SET THIS HERE!!!
|
||||||
|
// This must also match the pixel format above
|
||||||
|
#define FRAMEBUF fb0
|
||||||
|
|
||||||
|
static void board_init(GDisplay *g, fbInfo *fbi) {
|
||||||
|
// Initialize the frame buffer device - we assume everything is going to succeed.
|
||||||
|
CYG_FB_ON(FRAMEBUF);
|
||||||
|
#if (CYG_FB_FLAGS0(FRAMEBUF) & CYG_FB_FLAGS0_MUST_BE_ON)
|
||||||
|
CYG_FB_FILL_BLOCK(FRAMEBUF, 0, 0, CYG_FB_WIDTH(FRAMEBUF), CYG_FB_HEIGHT(FRAMEBUF), CYG_FB_MAKE_COLOUR(FRAMEBUF, 0, 0, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set the details of the frame buffer
|
||||||
|
#ifdef CYGHWR_IO_FRAMEBUF_FUNCTIONALITY_VIEWPORT
|
||||||
|
g->g.Width = CYG_FB_VIEWPORT_WIDTH(FRAMEBUF);
|
||||||
|
g->g.Height = CYG_FB_VIEWPORT_HEIGHT(FRAMEBUF);
|
||||||
|
#else
|
||||||
|
g->g.Width = CYG_FB_WIDTH(FRAMEBUF);
|
||||||
|
g->g.Height = CYG_FB_HEIGHT(FRAMEBUF);
|
||||||
|
#endif
|
||||||
|
g->g.Backlight = 100;
|
||||||
|
g->g.Contrast = 50;
|
||||||
|
fbi->linelen = CYG_FB_STRIDE(FRAMEBUF); // bytes per row
|
||||||
|
fbi->pixels = CYG_FB_BASE(FRAMEBUF); // pointer to the memory frame buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_FLUSH
|
||||||
|
static void board_flush(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
|
||||||
|
// You might want to replace CYG_FB_UPDATE_NOW with CYG_FB_UPDATE_VERTICAL_RETRACE
|
||||||
|
// if you are not using uGFX's auto flush or timer flush mechanisms and frame synchronisation
|
||||||
|
// is important for your display.
|
||||||
|
CYG_FB_SYNCH(FRAMEBUF, CYG_FB_UPDATE_NOW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
static void board_backlight(GDisplay *g, uint8_t percent) {
|
||||||
|
(void) g;
|
||||||
|
#if (CYG_FB_FLAGS0(FRAMEBUF) & CYG_FB_FLAGS0_BACKLIGHT)
|
||||||
|
cyg_fb_ioctl_backlight backlight;
|
||||||
|
size_t len = sizeof(cyg_fb_ioctl_backlight);
|
||||||
|
|
||||||
|
if (CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_BACKLIGHT_GET, &backlight, &len) || !backlight.fbbl_max)
|
||||||
|
return;
|
||||||
|
if (backlight.fbbl_max == 1)
|
||||||
|
backlight.fbbl_current = percent ? 1 : 0;
|
||||||
|
else
|
||||||
|
backlight.fbbl_current = (((uint32_t)percent)*backlight.fbbl_max)/100;
|
||||||
|
CYG_FB_IOCTL(FRAMEBUF, CYG_FB_IOCTL_BACKLIGHT_SET, &backlight, &len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void board_contrast(GDisplay *g, uint8_t percent) {
|
||||||
|
(void) g;
|
||||||
|
(void) percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void board_power(GDisplay *g, powermode_t pwr) {
|
||||||
|
// Not implemented yet.
|
||||||
|
(void) g;
|
||||||
|
(void) pwr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GDISP_DRIVER_VMT */
|
|
@ -0,0 +1,165 @@
|
||||||
|
#
|
||||||
|
# !!!! Do NOT edit this makefile with an editor which replace tabs by spaces !!!!
|
||||||
|
#
|
||||||
|
##############################################################################################
|
||||||
|
#
|
||||||
|
# On command line:
|
||||||
|
#
|
||||||
|
# make INSTALL_DIR=/path/to/ecos/install all = Create project
|
||||||
|
#
|
||||||
|
# make clean = Clean project files.
|
||||||
|
#
|
||||||
|
# To rebuild project do "make clean" and "make all".
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################################
|
||||||
|
# Start of default section
|
||||||
|
#
|
||||||
|
|
||||||
|
INSTALL_DIR=$$(INSTALL_DIR) # override on make command line
|
||||||
|
|
||||||
|
include $(INSTALL_DIR)/include/pkgconf/ecos.mak
|
||||||
|
|
||||||
|
CC = $(ECOS_COMMAND_PREFIX)gcc
|
||||||
|
AS = $(CC) -x assembler-with-cpp
|
||||||
|
CXX = $(CC)
|
||||||
|
LD = $(CC)
|
||||||
|
CFLAGS = -I$(INSTALL_DIR)/include
|
||||||
|
CXXFLAGS = $(CFLAGS) -g
|
||||||
|
LDFLAGS = -nostartfiles -L$(INSTALL_DIR)/lib -Ttarget.ld
|
||||||
|
|
||||||
|
# List all default C defines here, like -D_DEBUG=1
|
||||||
|
DDEFS =
|
||||||
|
|
||||||
|
# List all default ASM defines here, like -D_DEBUG=1
|
||||||
|
DADEFS =
|
||||||
|
|
||||||
|
# List all default directories to look for include files here
|
||||||
|
DINCDIR =
|
||||||
|
|
||||||
|
# List the default directory to look for the libraries here
|
||||||
|
DLIBDIR =
|
||||||
|
|
||||||
|
# List all default libraries here
|
||||||
|
DLIBS =
|
||||||
|
|
||||||
|
#
|
||||||
|
# End of default section
|
||||||
|
##############################################################################################
|
||||||
|
|
||||||
|
##############################################################################################
|
||||||
|
# Start of user section
|
||||||
|
#
|
||||||
|
|
||||||
|
# Define project name here
|
||||||
|
PROJECT = ugfx_over_ecos
|
||||||
|
|
||||||
|
# Imported source files and paths for uGFX
|
||||||
|
GFXLIB = ../ugfx
|
||||||
|
|
||||||
|
include ${GFXLIB}/gfx.mk
|
||||||
|
include ${GFXLIB}/boards/base/eCos-Synthetic-Framebuffer/board.mk
|
||||||
|
|
||||||
|
# Where is our source code - alter these for your project.
|
||||||
|
# Either just include the demo makefile or add your own definitions
|
||||||
|
include $(GFXLIB)/demos/modules/gdisp/basics/demo.mk
|
||||||
|
|
||||||
|
#MYFILES =
|
||||||
|
#MYCSRC =
|
||||||
|
#MYDEFS =
|
||||||
|
|
||||||
|
# List all user C define here, like -D_DEBUG=1
|
||||||
|
UDEFS = $(MYDEFS) $(GFXDEFS)
|
||||||
|
|
||||||
|
# Define ASM defines here
|
||||||
|
UADEFS =
|
||||||
|
|
||||||
|
# List C source files here
|
||||||
|
SRC = $(GFXSRC) \
|
||||||
|
$(MYCSRC)
|
||||||
|
|
||||||
|
# List ASM source files here
|
||||||
|
ASRC =
|
||||||
|
|
||||||
|
# List all user directories here
|
||||||
|
UINCDIR = $(MYFILES) $(GFXINC)
|
||||||
|
|
||||||
|
# List the user directory to look for the libraries here
|
||||||
|
ULIBDIR =
|
||||||
|
|
||||||
|
# List all user libraries here
|
||||||
|
ULIBS =
|
||||||
|
|
||||||
|
# Define optimisation level here
|
||||||
|
OPT = -ggdb -O0 -fomit-frame-pointer
|
||||||
|
|
||||||
|
#
|
||||||
|
# End of user defines
|
||||||
|
##############################################################################################
|
||||||
|
|
||||||
|
INCDIR = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))
|
||||||
|
LIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))
|
||||||
|
DEFS = $(DDEFS) $(UDEFS)
|
||||||
|
ADEFS = $(DADEFS) $(UADEFS)
|
||||||
|
OBJS = $(ASRC:.s=.o) $(SRC:.c=.o)
|
||||||
|
LIBS = $(DLIBS) $(ULIBS)
|
||||||
|
|
||||||
|
ASFLAGS = -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
|
||||||
|
CPFLAGS = $(OPT) -Wall -Wextra -Wstrict-prototypes -fverbose-asm $(DEFS)
|
||||||
|
|
||||||
|
ifeq ($(HOST_OSX),yes)
|
||||||
|
ifeq ($(OSX_SDK),)
|
||||||
|
OSX_SDK = /Developer/SDKs/MacOSX10.7.sdk
|
||||||
|
endif
|
||||||
|
ifeq ($(OSX_ARCH),)
|
||||||
|
OSX_ARCH = -mmacosx-version-min=10.3 -arch i386
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPFLAGS += -isysroot $(OSX_SDK) $(OSX_ARCH)
|
||||||
|
LDFLAGS = -Wl -Map=$(PROJECT).map,-syslibroot,$(OSX_SDK),$(LIBDIR)
|
||||||
|
LIBS += $(OSX_ARCH)
|
||||||
|
else
|
||||||
|
# Linux, or other
|
||||||
|
CPFLAGS += -m32 -Wa,-alms=$(<:.c=.lst) -I$(INSTALL_DIR)/include
|
||||||
|
LDFLAGS = -g -nostdlib -m32 -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR) -nostartfiles -L$(INSTALL_DIR)/lib -Ttarget.ld
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Generate dependency information
|
||||||
|
CPFLAGS += -MD -MP -MF .dep/$(@F).d
|
||||||
|
|
||||||
|
#
|
||||||
|
# makefile rules
|
||||||
|
#
|
||||||
|
|
||||||
|
all: $(OBJS) $(PROJECT)
|
||||||
|
|
||||||
|
%.o : %.c
|
||||||
|
$(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.o : %.s
|
||||||
|
$(AS) -c $(ASFLAGS) $< -o $@
|
||||||
|
|
||||||
|
$(PROJECT): $(OBJS)
|
||||||
|
$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
gcov:
|
||||||
|
-mkdir gcov
|
||||||
|
$(COV) -u $(subst /,\,$(SRC))
|
||||||
|
-mv *.gcov ./gcov
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-rm -f $(OBJS)
|
||||||
|
-rm -f $(PROJECT)
|
||||||
|
-rm -f $(PROJECT).map
|
||||||
|
-rm -f $(SRC:.c=.c.bak)
|
||||||
|
-rm -f $(SRC:.c=.lst)
|
||||||
|
-rm -f $(ASRC:.s=.s.bak)
|
||||||
|
-rm -f $(ASRC:.s=.lst)
|
||||||
|
-rm -fR .dep
|
||||||
|
|
||||||
|
#
|
||||||
|
# Include the dependency files, should be the last of the makefile
|
||||||
|
#
|
||||||
|
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
|
||||||
|
|
||||||
|
# *** EOF ***
|
|
@ -0,0 +1,7 @@
|
||||||
|
Copy these files into your own project directory and alter them to suite.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
1/ Look at the MYFILES definition and the MYCSRC definition.
|
||||||
|
2/ To run please install eCos synthetic framebuffer according to the documentation.
|
||||||
|
3/ Call application ./ugfx_over_ecos -io
|
|
@ -0,0 +1,11 @@
|
||||||
|
This directory contains the interface for eCos using a synthetic framebuffer display.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
On this board uGFX currently supports:
|
||||||
|
|
||||||
|
- GDISP via the framebuffer driver
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
There is an example Makefile and project in the examples directory.
|
|
@ -10,6 +10,11 @@ FEATURE: Added Linux-Framebuffer board definition
|
||||||
FEATURE: Added FatFS support for GFILE
|
FEATURE: Added FatFS support for GFILE
|
||||||
FEATURE: Added gfileMount() and gfileUnmount()
|
FEATURE: Added gfileMount() and gfileUnmount()
|
||||||
FEATURE: Added gfileSync()
|
FEATURE: Added gfileSync()
|
||||||
|
FEATURE: Added gwinDrawThickLine()
|
||||||
|
FEATURE: Added support for eCos
|
||||||
|
FEATURE: Added PCF8812 gdisp driver
|
||||||
|
FEATURE: Added PCD8544 gdisp driver
|
||||||
|
FEATURE: Added Raspberry Pi board support
|
||||||
|
|
||||||
|
|
||||||
*** Release 2.1 ***
|
*** Release 2.1 ***
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PCD8544_H
|
||||||
|
#define _PCD8544_H
|
||||||
|
|
||||||
|
#define PCD8544_SET_FUNC 0x20 // Function set
|
||||||
|
#define PCD8544_H 0x01
|
||||||
|
#define PCD8544_V 0x02
|
||||||
|
#define PCD8544_PD 0x04
|
||||||
|
|
||||||
|
#define PCD8544_SET_DISPLAY 0x08
|
||||||
|
#define PCD8544_DISPLAY_MODE_BLANK 0x00 // bit D = 0, E = 0
|
||||||
|
#define PCD8544_DISPLAY_MODE_FILL 0x01 // bit D = 0, E = 1
|
||||||
|
#define PCD8544_DISPLAY_MODE_NORMAL 0x04 // bit D = 1, E = 0
|
||||||
|
#define PCD8544_DISPLAY_MODE_INVERT 0x05 // bit D = 1, E = 1
|
||||||
|
|
||||||
|
#define PCD8544_SET_Y 0x40 // 0 0 1 0 0 Y3 Y2 Y1 Y0
|
||||||
|
#define PCD8544_SET_X 0x80 // 0 1 X6 X5 X4 X3 X2 X1 X0
|
||||||
|
|
||||||
|
// =========================================
|
||||||
|
|
||||||
|
#define PCD8544_SET_TEMP 0x04 // set temperature coefficient (TCx)
|
||||||
|
#define PCD8544_TEMP_MODE_0 0x00 // TC1 = 0, TC0 = 0
|
||||||
|
#define PCD8544_TEMP_MODE_1 0x01 // TC1 = 0, TC0 = 1
|
||||||
|
#define PCD8544_TEMP_MODE_2 0x02 // TC1 = 1, TC0 = 0
|
||||||
|
#define PCD8544_TEMP_MODE_3 0x03 // TC1 = 1, TC0 = 1
|
||||||
|
|
||||||
|
#define PCD8544_SET_BIAS 0x10 // set bias system (BSx)
|
||||||
|
#define PCD8544_BIAS_MODE_7 0x00 // 1 to 100
|
||||||
|
#define PCD8544_BIAS_MODE_6 0x01 // 1 to 80
|
||||||
|
#define PCD8544_BIAS_MODE_5 0x02 // 1 to 65
|
||||||
|
#define PCD8544_BIAS_MODE_4 0x03 // 1 to 48
|
||||||
|
#define PCD8544_BIAS_MODE_3 0x04 // 1 to 40 or 1 to 34
|
||||||
|
#define PCD8544_BIAS_MODE_2 0x05 // 1 to 24
|
||||||
|
#define PCD8544_BIAS_MODE_1 0x06 // 1 to 18 or 1 to 16
|
||||||
|
#define PCD8544_BIAS_MODE_0 0x07 // 1 to 10 or 1 to 9 or 1 to 8
|
||||||
|
|
||||||
|
#define PCD8544_SET_VOP 0x80 // write VOP to register, 1 VOP6 VOP5 VOP4 VOP3 VOP2 VOP1 VOP0
|
||||||
|
|
||||||
|
#endif /* _PCD8544_H */
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GDISP_LLD_BOARD_H
|
||||||
|
#define _GDISP_LLD_BOARD_H
|
||||||
|
|
||||||
|
static inline void init_board(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void post_init_board(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void setpin_reset(GDisplay *g, bool_t state) {
|
||||||
|
(void) g;
|
||||||
|
(void) state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void acquire_bus(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void release_bus(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write_cmd(GDisplay *g, uint8_t cmd) {
|
||||||
|
(void) g;
|
||||||
|
(void) cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
|
||||||
|
(void) g;
|
||||||
|
(void) data;
|
||||||
|
(void) length;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _GDISP_LLD_BOARD_H */
|
|
@ -0,0 +1,2 @@
|
||||||
|
GFXINC += $(GFXLIB)/drivers/gdisp/PCD8544
|
||||||
|
GFXSRC += $(GFXLIB)/drivers/gdisp/PCD8544/gdisp_lld_PCD8544.c
|
|
@ -0,0 +1,225 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GDISP
|
||||||
|
|
||||||
|
#define GDISP_DRIVER_VMT GDISPVMT_PCD8544
|
||||||
|
#include "drivers/gdisp/PCD8544/gdisp_lld_config.h"
|
||||||
|
#include "src/gdisp/driver.h"
|
||||||
|
#include "board_PCD8544.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define GDISP_SCREEN_HEIGHT 48
|
||||||
|
#define GDISP_SCREEN_WIDTH 84
|
||||||
|
|
||||||
|
#define GDISP_INITIAL_CONTRAST 51
|
||||||
|
#define GDISP_INITIAL_BACKLIGHT 100
|
||||||
|
|
||||||
|
#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0)
|
||||||
|
|
||||||
|
#include "drivers/gdisp/PCD8544/PCD8544.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local routines. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
// Some common routines and macros
|
||||||
|
#define RAM(g) ((uint8_t *)g->priv)
|
||||||
|
|
||||||
|
#define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_SCREEN_WIDTH)
|
||||||
|
#define xybit(y) (1 << ((y) & 7))
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As this controller can't update on a pixel boundary we need to maintain the
|
||||||
|
* the entire display surface in memory so that we can do the necessary bit
|
||||||
|
* operations. Fortunately it is a small display in monochrome.
|
||||||
|
* Display 48 * 84 / 8 = 504
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GDISP_SCREEN_BYTES ((GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT) / 8)
|
||||||
|
|
||||||
|
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
|
// The private area is the display surface.
|
||||||
|
if (!(g->priv = gfxAlloc(GDISP_SCREEN_BYTES)))
|
||||||
|
gfxHalt("GDISP PCD8544: Failed to allocate private memory");
|
||||||
|
|
||||||
|
// Initialise the board interface
|
||||||
|
init_board(g);
|
||||||
|
|
||||||
|
// Hardware reset
|
||||||
|
setpin_reset(g, TRUE);
|
||||||
|
gfxSleepMilliseconds(100);
|
||||||
|
setpin_reset(g, FALSE);
|
||||||
|
gfxSleepMilliseconds(100);
|
||||||
|
|
||||||
|
acquire_bus(g);
|
||||||
|
|
||||||
|
write_cmd(g, PCD8544_SET_FUNC | PCD8544_H);
|
||||||
|
write_cmd(g, PCD8544_SET_TEMP | PCD8544_TEMP_MODE_2);
|
||||||
|
write_cmd(g, PCD8544_SET_BIAS | PCD8544_BIAS_MODE_4);
|
||||||
|
write_cmd(g, PCD8544_SET_VOP | (0x40));
|
||||||
|
write_cmd(g, PCD8544_SET_FUNC);
|
||||||
|
write_cmd(g, PCD8544_SET_DISPLAY | PCD8544_DISPLAY_MODE_NORMAL);
|
||||||
|
write_cmd(g, PCD8544_SET_X); // X = 0
|
||||||
|
write_cmd(g, PCD8544_SET_Y); // Y = 0
|
||||||
|
|
||||||
|
write_data(g, 0x00, GDISP_SCREEN_BYTES);
|
||||||
|
|
||||||
|
// Finish Init
|
||||||
|
post_init_board(g);
|
||||||
|
|
||||||
|
// Release the bus
|
||||||
|
release_bus(g);
|
||||||
|
|
||||||
|
/* Turn on the back-light */
|
||||||
|
set_backlight(g, GDISP_INITIAL_BACKLIGHT);
|
||||||
|
|
||||||
|
/* Initialise the GDISP structure */
|
||||||
|
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||||
|
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||||
|
g->g.Orientation = GDISP_ROTATE_0;
|
||||||
|
g->g.Powermode = powerOn;
|
||||||
|
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
|
||||||
|
g->g.Contrast = GDISP_INITIAL_CONTRAST;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_FLUSH
|
||||||
|
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
|
||||||
|
|
||||||
|
// Don't flush if we don't need it.
|
||||||
|
if (!(g->flags & GDISP_FLG_NEEDFLUSH)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_bus(g);
|
||||||
|
|
||||||
|
write_cmd(g, PCD8544_SET_X | 0); // X = 0
|
||||||
|
write_cmd(g, PCD8544_SET_Y | 0); // Y = 0
|
||||||
|
|
||||||
|
write_data(g, RAM(g), GDISP_SCREEN_BYTES);
|
||||||
|
|
||||||
|
release_bus(g);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_DRAWPIXEL
|
||||||
|
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||||
|
coord_t x, y;
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
switch(g->g.Orientation) {
|
||||||
|
default:
|
||||||
|
case GDISP_ROTATE_0:
|
||||||
|
x = g->p.x;
|
||||||
|
y = g->p.y;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_90:
|
||||||
|
x = g->p.y;
|
||||||
|
y = g->g.Width - g->p.x - 1;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_180:
|
||||||
|
x = g->g.Width - g->p.x - 1;
|
||||||
|
y = g->g.Height - g->p.y - 1;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_270:
|
||||||
|
x = g->g.Height - g->p.y - 1;
|
||||||
|
y = g->p.x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
x = g->p.x;
|
||||||
|
y = g->p.y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (gdispColor2Native(g->p.color) != Black) {
|
||||||
|
RAM(g)[xyaddr(x, y)] |= xybit(y);
|
||||||
|
} else {
|
||||||
|
RAM(g)[xyaddr(x, y)] &= ~xybit(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
LLDSPEC void gdisp_lld_control(GDisplay *g) {
|
||||||
|
switch(g->p.x) {
|
||||||
|
case GDISP_CONTROL_POWER:
|
||||||
|
if (g->g.Powermode == (powermode_t)g->p.ptr)
|
||||||
|
return;
|
||||||
|
switch((powermode_t)g->p.ptr) {
|
||||||
|
case powerOff:
|
||||||
|
case powerSleep:
|
||||||
|
case powerDeepSleep:
|
||||||
|
write_cmd(g, PCD8544_SET_FUNC | PCD8544_PD);
|
||||||
|
break;
|
||||||
|
case powerOn:
|
||||||
|
write_cmd(g, PCD8544_SET_FUNC);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g->g.Powermode = (powermode_t)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_ORIENTATION:
|
||||||
|
if (g->g.Orientation == (orientation_t)g->p.ptr)
|
||||||
|
return;
|
||||||
|
switch((orientation_t)g->p.ptr) {
|
||||||
|
case GDISP_ROTATE_0:
|
||||||
|
case GDISP_ROTATE_180:
|
||||||
|
if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
|
||||||
|
coord_t tmp;
|
||||||
|
|
||||||
|
tmp = g->g.Width;
|
||||||
|
g->g.Width = g->g.Height;
|
||||||
|
g->g.Height = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_90:
|
||||||
|
case GDISP_ROTATE_270:
|
||||||
|
if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) {
|
||||||
|
coord_t tmp;
|
||||||
|
|
||||||
|
tmp = g->g.Width;
|
||||||
|
g->g.Width = g->g.Height;
|
||||||
|
g->g.Height = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g->g.Orientation = (orientation_t)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_BACKLIGHT:
|
||||||
|
if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
|
||||||
|
set_backlight(g, (unsigned)g->p.ptr);
|
||||||
|
g->g.Backlight = (unsigned)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_CONTRAST:
|
||||||
|
if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
|
||||||
|
write_cmd(g, PCD8544_SET_VOP | (unsigned)g->p.ptr);
|
||||||
|
g->g.Contrast = (unsigned)g->p.ptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GFX_USE_GDISP
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GDISP_LLD_CONFIG_H
|
||||||
|
#define _GDISP_LLD_CONFIG_H
|
||||||
|
|
||||||
|
#if GFX_USE_GDISP
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver hardware support. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
|
||||||
|
#define GDISP_HARDWARE_DRAWPIXEL TRUE
|
||||||
|
#define GDISP_HARDWARE_CONTROL TRUE
|
||||||
|
|
||||||
|
// Set this to your frame buffer pixel format.
|
||||||
|
#ifndef GDISP_LLD_PIXELFORMAT
|
||||||
|
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GFX_USE_GDISP */
|
||||||
|
|
||||||
|
#endif /* _GDISP_LLD_CONFIG_H */
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PCF8812_H
|
||||||
|
#define _PCF8812_H
|
||||||
|
|
||||||
|
#define PCF8812_SET_FUNC 0x20 // Function set
|
||||||
|
#define PCF8812_H 0x01
|
||||||
|
#define PCF8812_V 0x02
|
||||||
|
#define PCF8812_PD 0x04
|
||||||
|
|
||||||
|
#define PCF8812_SET_DISPLAY 0x08
|
||||||
|
#define PCF8812_DISPLAY_MODE_BLANK 0x00 // bit D = 0, E = 0
|
||||||
|
#define PCF8812_DISPLAY_MODE_FILL 0x01 // bit D = 0, E = 1
|
||||||
|
#define PCF8812_DISPLAY_MODE_NORMAL 0x04 // bit D = 1, E = 0
|
||||||
|
#define PCF8812_DISPLAY_MODE_INVERT 0x05 // bit D = 1, E = 1
|
||||||
|
|
||||||
|
#define PCF8812_SET_PRS 0x10 // Set Vop range, VLCD programming range select
|
||||||
|
|
||||||
|
#define PCF8812_SET_Y 0x40 // 0 0 1 0 0 Y3 Y2 Y1 Y0
|
||||||
|
#define PCF8812_SET_X 0x80 // 0 1 X6 X5 X4 X3 X2 X1 X0
|
||||||
|
|
||||||
|
// =========================================
|
||||||
|
|
||||||
|
#define PCF8812_SET_TEMP 0x04 // set temperature coefficient (TCx)
|
||||||
|
#define PCF8812_TEMP_MODE_0 0x00 // TC1 = 0, TC0 = 0
|
||||||
|
#define PCF8812_TEMP_MODE_1 0x01 // TC1 = 0, TC0 = 1
|
||||||
|
#define PCF8812_TEMP_MODE_2 0x02 // TC1 = 1, TC0 = 0
|
||||||
|
#define PCF8812_TEMP_MODE_3 0x03 // TC1 = 1, TC0 = 1
|
||||||
|
|
||||||
|
#define PCF8812_SET_VMULT 0x08 // Set voltage multiplier factor
|
||||||
|
#define PCF8812_VMULT_MODE_0 0x00 // S1 = 0, S0 = 0 - 2 × voltage multiplier
|
||||||
|
#define PCF8812_VMULT_MODE_1 0x01 // S1 = 0, S0 = 1 - 3 × voltage multiplier
|
||||||
|
#define PCF8812_VMULT_MODE_2 0x02 // S1 = 1, S0 = 0 - 4 × voltage multiplier
|
||||||
|
#define PCF8812_VMULT_MODE_3 0x03 // S1 = 1, S0 = 1 - 5 × voltage multiplier
|
||||||
|
|
||||||
|
#define PCF8812_SET_BIAS 0x10 // set bias system (BSx)
|
||||||
|
#define PCF8812_BIAS_MODE_7 0x00 // 1 to 100
|
||||||
|
#define PCF8812_BIAS_MODE_6 0x01 // 1 to 80
|
||||||
|
#define PCF8812_BIAS_MODE_5 0x02 // 1 to 65
|
||||||
|
#define PCF8812_BIAS_MODE_4 0x03 // 1 to 48
|
||||||
|
#define PCF8812_BIAS_MODE_3 0x04 // 1 to 40 or 1 to 34
|
||||||
|
#define PCF8812_BIAS_MODE_2 0x05 // 1 to 24
|
||||||
|
#define PCF8812_BIAS_MODE_1 0x06 // 1 to 18 or 1 to 16
|
||||||
|
#define PCF8812_BIAS_MODE_0 0x07 // 1 to 10 or 1 to 9 or 1 to 8
|
||||||
|
|
||||||
|
#define PCF8812_SET_VOP 0x80 // write VOP to register, 1 VOP6 VOP5 VOP4 VOP3 VOP2 VOP1 VOP0
|
||||||
|
|
||||||
|
#endif /* _PCF8812_H */
|
|
@ -0,0 +1,5 @@
|
||||||
|
Driver for PCF8812/OM6206 controller
|
||||||
|
==========================
|
||||||
|
Displays based on this controller:
|
||||||
|
Nokia 3410
|
||||||
|
Siemens C55/A55/A52
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GDISP_LLD_BOARD_H
|
||||||
|
#define _GDISP_LLD_BOARD_H
|
||||||
|
|
||||||
|
static inline void init_board(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void post_init_board(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void setpin_reset(GDisplay *g, bool_t state) {
|
||||||
|
(void) g;
|
||||||
|
(void) state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void acquire_bus(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void release_bus(GDisplay *g) {
|
||||||
|
(void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write_cmd(GDisplay *g, uint8_t cmd) {
|
||||||
|
(void) g;
|
||||||
|
(void) cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length) {
|
||||||
|
(void) g;
|
||||||
|
(void) data;
|
||||||
|
(void) length;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _GDISP_LLD_BOARD_H */
|
|
@ -0,0 +1,2 @@
|
||||||
|
GFXINC += $(GFXLIB)/drivers/gdisp/PCF8812
|
||||||
|
GFXSRC += $(GFXLIB)/drivers/gdisp/PCF8812/gdisp_lld_PCF8812.c
|
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_GDISP
|
||||||
|
|
||||||
|
#define GDISP_DRIVER_VMT GDISPVMT_PCF8812
|
||||||
|
#include "drivers/gdisp/PCF8812/gdisp_lld_config.h"
|
||||||
|
#include "src/gdisp/driver.h"
|
||||||
|
#include "board_PCF8812.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define GDISP_MATRIX_HEIGHT 72
|
||||||
|
#define GDISP_MATRIX_WIDTH 102
|
||||||
|
|
||||||
|
#define GDISP_SCREEN_HEIGHT 65
|
||||||
|
#define GDISP_SCREEN_WIDTH 96
|
||||||
|
|
||||||
|
#define GDISP_INITIAL_CONTRAST 51
|
||||||
|
#define GDISP_INITIAL_BACKLIGHT 100
|
||||||
|
|
||||||
|
#define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER << 0)
|
||||||
|
|
||||||
|
#include "drivers/gdisp/PCF8812/PCF8812.h"
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local routines. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
// Some common routines and macros
|
||||||
|
#define RAM(g) ((uint8_t *)g->priv)
|
||||||
|
|
||||||
|
#define xyaddr(x, y) ((x) + ((y) >> 3) * GDISP_MATRIX_WIDTH)
|
||||||
|
#define xybit(y) (1 << ((y) & 7))
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As this controller can't update on a pixel boundary we need to maintain the
|
||||||
|
* the entire display surface in memory so that we can do the necessary bit
|
||||||
|
* operations. Fortunately it is a small display in monochrome.
|
||||||
|
* Matrix 102 * 65 / 8 = 828,75 bytes.
|
||||||
|
* Display 96 * 65 / 8 = 780
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define GDISP_SCREEN_BYTES ((GDISP_SCREEN_WIDTH * GDISP_SCREEN_HEIGHT) / 8)
|
||||||
|
#define GDISP_MATRIX_BYTES ((GDISP_MATRIX_WIDTH * GDISP_MATRIX_HEIGHT) / 8) // real height 65 pixels, this fix 65 / 8 != 9
|
||||||
|
|
||||||
|
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
|
||||||
|
// The private area is the display surface.
|
||||||
|
if (!(g->priv = gfxAlloc(GDISP_MATRIX_BYTES)))
|
||||||
|
gfxHalt("GDISP PCF8812: Failed to allocate private memory");
|
||||||
|
|
||||||
|
// Initialise the board interface
|
||||||
|
init_board(g);
|
||||||
|
|
||||||
|
// Hardware reset
|
||||||
|
setpin_reset(g, TRUE);
|
||||||
|
gfxSleepMilliseconds(100);
|
||||||
|
setpin_reset(g, FALSE);
|
||||||
|
gfxSleepMilliseconds(100);
|
||||||
|
|
||||||
|
acquire_bus(g);
|
||||||
|
|
||||||
|
write_cmd(g, PCF8812_SET_FUNC | PCF8812_H);
|
||||||
|
write_cmd(g, PCF8812_SET_TEMP | PCF8812_TEMP_MODE_2);
|
||||||
|
write_cmd(g, PCF8812_SET_BIAS | PCF8812_BIAS_MODE_4);
|
||||||
|
write_cmd(g, PCF8812_SET_VOP | (0x40));
|
||||||
|
write_cmd(g, PCF8812_SET_FUNC);
|
||||||
|
write_cmd(g, PCF8812_SET_DISPLAY | PCF8812_DISPLAY_MODE_NORMAL);
|
||||||
|
write_cmd(g, PCF8812_SET_X); // X = 0
|
||||||
|
write_cmd(g, PCF8812_SET_Y); // Y = 0
|
||||||
|
|
||||||
|
|
||||||
|
write_data(g, 0x00, GDISP_MATRIX_BYTES);
|
||||||
|
|
||||||
|
// Finish Init
|
||||||
|
post_init_board(g);
|
||||||
|
|
||||||
|
// Release the bus
|
||||||
|
release_bus(g);
|
||||||
|
|
||||||
|
/* Turn on the back-light */
|
||||||
|
set_backlight(g, GDISP_INITIAL_BACKLIGHT);
|
||||||
|
|
||||||
|
/* Initialise the GDISP structure */
|
||||||
|
g->g.Width = GDISP_SCREEN_WIDTH;
|
||||||
|
g->g.Height = GDISP_SCREEN_HEIGHT;
|
||||||
|
g->g.Orientation = GDISP_ROTATE_0;
|
||||||
|
g->g.Powermode = powerOn;
|
||||||
|
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
|
||||||
|
g->g.Contrast = GDISP_INITIAL_CONTRAST;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_FLUSH
|
||||||
|
LLDSPEC void gdisp_lld_flush(GDisplay *g) {
|
||||||
|
|
||||||
|
// Don't flush if we don't need it.
|
||||||
|
if (!(g->flags & GDISP_FLG_NEEDFLUSH)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
acquire_bus(g);
|
||||||
|
|
||||||
|
write_cmd(g, PCF8812_SET_X | 0); // X = 0
|
||||||
|
write_cmd(g, PCF8812_SET_Y | 0); // Y = 0
|
||||||
|
|
||||||
|
write_data(g, RAM(g), GDISP_MATRIX_BYTES);
|
||||||
|
|
||||||
|
release_bus(g);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_HARDWARE_DRAWPIXEL
|
||||||
|
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
|
||||||
|
coord_t x, y;
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
switch(g->g.Orientation) {
|
||||||
|
default:
|
||||||
|
case GDISP_ROTATE_0:
|
||||||
|
x = g->p.x;
|
||||||
|
y = g->p.y;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_90:
|
||||||
|
x = g->p.y;
|
||||||
|
y = g->g.Width - g->p.x - 1;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_180:
|
||||||
|
x = g->g.Width - g->p.x - 1;
|
||||||
|
y = g->g.Height - g->p.y - 1;
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_270:
|
||||||
|
x = g->g.Height - g->p.y - 1;
|
||||||
|
y = g->p.x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
x = g->p.x;
|
||||||
|
y = g->p.y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (gdispColor2Native(g->p.color) != Black) {
|
||||||
|
RAM(g)[xyaddr(x, y)] |= xybit(y);
|
||||||
|
} else {
|
||||||
|
RAM(g)[xyaddr(x, y)] &= ~xybit(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
g->flags |= GDISP_FLG_NEEDFLUSH;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if GDISP_NEED_CONTROL
|
||||||
|
LLDSPEC void gdisp_lld_control(GDisplay *g) {
|
||||||
|
switch(g->p.x) {
|
||||||
|
case GDISP_CONTROL_POWER:
|
||||||
|
if (g->g.Powermode == (powermode_t)g->p.ptr)
|
||||||
|
return;
|
||||||
|
switch((powermode_t)g->p.ptr) {
|
||||||
|
case powerOff:
|
||||||
|
case powerSleep:
|
||||||
|
case powerDeepSleep:
|
||||||
|
write_cmd(g, PCF8812_SET_FUNC | PCF8812_PD);
|
||||||
|
break;
|
||||||
|
case powerOn:
|
||||||
|
write_cmd(g, PCF8812_SET_FUNC);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g->g.Powermode = (powermode_t)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_ORIENTATION:
|
||||||
|
if (g->g.Orientation == (orientation_t)g->p.ptr)
|
||||||
|
return;
|
||||||
|
switch((orientation_t)g->p.ptr) {
|
||||||
|
case GDISP_ROTATE_0:
|
||||||
|
case GDISP_ROTATE_180:
|
||||||
|
if (g->g.Orientation == GDISP_ROTATE_90 || g->g.Orientation == GDISP_ROTATE_270) {
|
||||||
|
coord_t tmp;
|
||||||
|
|
||||||
|
tmp = g->g.Width;
|
||||||
|
g->g.Width = g->g.Height;
|
||||||
|
g->g.Height = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GDISP_ROTATE_90:
|
||||||
|
case GDISP_ROTATE_270:
|
||||||
|
if (g->g.Orientation == GDISP_ROTATE_0 || g->g.Orientation == GDISP_ROTATE_180) {
|
||||||
|
coord_t tmp;
|
||||||
|
|
||||||
|
tmp = g->g.Width;
|
||||||
|
g->g.Width = g->g.Height;
|
||||||
|
g->g.Height = tmp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g->g.Orientation = (orientation_t)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_BACKLIGHT:
|
||||||
|
if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
|
||||||
|
set_backlight(g, (unsigned)g->p.ptr);
|
||||||
|
g->g.Backlight = (unsigned)g->p.ptr;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case GDISP_CONTROL_CONTRAST:
|
||||||
|
if ((unsigned)g->p.ptr > 100) g->p.ptr = (void *)100;
|
||||||
|
g->g.Contrast = (unsigned)g->p.ptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // GFX_USE_GDISP
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GDISP_LLD_CONFIG_H
|
||||||
|
#define _GDISP_LLD_CONFIG_H
|
||||||
|
|
||||||
|
#if GFX_USE_GDISP
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver hardware support. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define GDISP_HARDWARE_FLUSH TRUE // This controller requires flushing
|
||||||
|
#define GDISP_HARDWARE_DRAWPIXEL TRUE
|
||||||
|
#define GDISP_HARDWARE_CONTROL TRUE
|
||||||
|
|
||||||
|
// Set this to your frame buffer pixel format.
|
||||||
|
#ifndef GDISP_LLD_PIXELFORMAT
|
||||||
|
#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_MONO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GFX_USE_GDISP */
|
||||||
|
|
||||||
|
#endif /* _GDISP_LLD_CONFIG_H */
|
|
@ -32,6 +32,11 @@
|
||||||
//#define GFX_USE_OS_WIN32 FALSE
|
//#define GFX_USE_OS_WIN32 FALSE
|
||||||
//#define GFX_USE_OS_LINUX FALSE
|
//#define GFX_USE_OS_LINUX FALSE
|
||||||
//#define GFX_USE_OS_OSX FALSE
|
//#define GFX_USE_OS_OSX FALSE
|
||||||
|
//#define GFX_USE_OS_ECOS FALSE
|
||||||
|
//#define GFX_USE_OS_RAW32 FALSE
|
||||||
|
// #define GOS_RAW_HEAP_SIZE 0
|
||||||
|
// #define INTERRUPTS_OFF() optional_code
|
||||||
|
// #define INTERRUPTS_ON() optional_code
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -73,7 +73,7 @@ extern "C" {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the size of a file
|
* @brief Get the size of a file
|
||||||
* @note Please use @p gfileGetSize() if the file is not opened
|
* @note Please use @p gfileGetSize() if the file is opened
|
||||||
*
|
*
|
||||||
* @param[in] fname The file name
|
* @param[in] fname The file name
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gfx.h"
|
||||||
|
|
||||||
|
#if GFX_USE_OS_ECOS
|
||||||
|
|
||||||
|
void _gosInit(void)
|
||||||
|
{
|
||||||
|
/* Don't initialise if the user already has */
|
||||||
|
//cyg_scheduler_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _gosDeinit(void)
|
||||||
|
{
|
||||||
|
/* ToDo */
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSleepMilliseconds(delaytime_t ms)
|
||||||
|
{
|
||||||
|
switch(ms) {
|
||||||
|
case TIME_IMMEDIATE: cyg_thread_yield(); return;
|
||||||
|
case TIME_INFINITE: cyg_thread_suspend(cyg_thread_self()); return;
|
||||||
|
default: cyg_thread_delay(gfxMillisecondsToTicks(ms)); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSleepMicroseconds(delaytime_t ms)
|
||||||
|
{
|
||||||
|
switch(ms) {
|
||||||
|
case TIME_IMMEDIATE: return;
|
||||||
|
case TIME_INFINITE: cyg_thread_suspend(cyg_thread_self()); return;
|
||||||
|
default: cyg_thread_delay(gfxMillisecondsToTicks(ms/1000)); return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit)
|
||||||
|
{
|
||||||
|
if (val > limit)
|
||||||
|
val = limit;
|
||||||
|
|
||||||
|
psem->limit = limit;
|
||||||
|
cyg_semaphore_init(&psem->sem, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSemDestroy(gfxSem *psem)
|
||||||
|
{
|
||||||
|
cyg_semaphore_destroy(&psem->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms)
|
||||||
|
{
|
||||||
|
switch(ms) {
|
||||||
|
case TIME_IMMEDIATE: return cyg_semaphore_trywait(&psem->sem);
|
||||||
|
case TIME_INFINITE: return cyg_semaphore_wait(&psem->sem);
|
||||||
|
default: return cyg_semaphore_timed_wait(&psem->sem, gfxMillisecondsToTicks(ms)+cyg_current_time());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t gfxSemWaitI(gfxSem *psem)
|
||||||
|
{
|
||||||
|
return cyg_semaphore_trywait(&psem->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSemSignal(gfxSem *psem)
|
||||||
|
{
|
||||||
|
if (psem->limit == MAX_SEMAPHORE_COUNT)
|
||||||
|
cyg_semaphore_post(&psem->sem);
|
||||||
|
else {
|
||||||
|
cyg_scheduler_lock();
|
||||||
|
if (gfxSemCounterI(psem) < psem->limit)
|
||||||
|
cyg_semaphore_post(&psem->sem);
|
||||||
|
cyg_scheduler_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gfxSemSignalI(gfxSem *psem)
|
||||||
|
{
|
||||||
|
if (psem->limit == MAX_SEMAPHORE_COUNT || gfxSemCounterI(psem) < psem->limit)
|
||||||
|
cyg_semaphore_post(&psem->sem);
|
||||||
|
}
|
||||||
|
|
||||||
|
semcount_t gfxSemCounterI(gfxSem *psem) {
|
||||||
|
semcount_t cnt;
|
||||||
|
|
||||||
|
cyg_semaphore_peek(&psem->sem, &cnt);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param)
|
||||||
|
{
|
||||||
|
gfxThreadHandle th;
|
||||||
|
|
||||||
|
if (!stackarea) {
|
||||||
|
if (!stacksz) stacksz = CYGNUM_HAL_STACK_SIZE_TYPICAL;
|
||||||
|
if (!(stackarea = gfxAlloc(stacksz+sizeof(cyg_thread))))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stacksz)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
cyg_thread_create(prio, fn, param, "uGFX", (((cyg_thread *)stackarea)+1), stacksz, &th, (cyg_thread *)stackarea);
|
||||||
|
cyg_thread_resume(th);
|
||||||
|
return th;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GFX_USE_OS_ECOS */
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms of the GFX License. If a copy of
|
||||||
|
* the license was not distributed with this file, you can obtain one at:
|
||||||
|
*
|
||||||
|
* http://ugfx.org/license.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GOS_ECOS_H
|
||||||
|
#define _GOS_ECOS_H
|
||||||
|
|
||||||
|
#if GFX_USE_OS_ECOS
|
||||||
|
|
||||||
|
#include <cyg/hal/hal_arch.h>
|
||||||
|
#include <cyg/kernel/kapi.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Type definitions */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
typedef cyg_bool_t bool_t;
|
||||||
|
typedef cyg_int8 int8_t;
|
||||||
|
typedef cyg_uint8 uint8_t;
|
||||||
|
typedef cyg_int16 int16_t;
|
||||||
|
typedef cyg_uint16 uint16_t;
|
||||||
|
typedef cyg_int32 int32_t;
|
||||||
|
typedef cyg_uint32 uint32_t;
|
||||||
|
typedef cyg_uint32 size_t;
|
||||||
|
|
||||||
|
#define TRUE -1
|
||||||
|
#define FALSE 0
|
||||||
|
#define TIME_IMMEDIATE 0
|
||||||
|
#define TIME_INFINITE 0xFFFFFFFF
|
||||||
|
|
||||||
|
typedef cyg_ucount32 delaytime_t;
|
||||||
|
typedef cyg_tick_count_t systemticks_t;
|
||||||
|
typedef cyg_count32 semcount_t;
|
||||||
|
typedef void threadreturn_t;
|
||||||
|
typedef cyg_addrword_t threadpriority_t;
|
||||||
|
typedef cyg_handle_t gfxThreadHandle;
|
||||||
|
|
||||||
|
#define MAX_SEMAPHORE_COUNT 0x7FFFFFFF
|
||||||
|
#define LOW_PRIORITY (CYGNUM_KERNEL_SCHED_PRIORITIES-2)
|
||||||
|
#define NORMAL_PRIORITY (CYGNUM_KERNEL_SCHED_PRIORITIES/2)
|
||||||
|
#define HIGH_PRIORITY 0
|
||||||
|
|
||||||
|
#define DECLARE_THREAD_STACK(name, sz) struct { cyg_thread t; unsigned char stk[sz]; } name[1]
|
||||||
|
#define DECLARE_THREAD_FUNCTION(fnName, param) threadreturn_t fnName(cyg_addrword_t param)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
cyg_sem_t sem;
|
||||||
|
semcount_t limit;
|
||||||
|
} gfxSem;
|
||||||
|
|
||||||
|
typedef cyg_mutex_t gfxMutex;
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Function declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define gfxSystemTicks() cyg_current_time()
|
||||||
|
#define gfxExit() exit(0)
|
||||||
|
#define gfxHalt(msg) exit(-1)
|
||||||
|
#define gfxYield() cyg_thread_yield()
|
||||||
|
|
||||||
|
#define gfxMillisecondsToTicks(ms) (((ms)*(CYGNUM_HAL_RTC_DENOMINATOR*1000))/(CYGNUM_HAL_RTC_NUMERATOR/1000))
|
||||||
|
void gfxSleepMilliseconds(delaytime_t ms);
|
||||||
|
void gfxSleepMicroseconds(delaytime_t ms);
|
||||||
|
|
||||||
|
#define gfxAlloc(sz) malloc(sz)
|
||||||
|
#define gfxFree(ptr) free(ptr)
|
||||||
|
#define gfxRealloc(ptr, oldsz, newsz) realloc(ptr, newsz)
|
||||||
|
|
||||||
|
#define gfxSystemLock() cyg_scheduler_lock()
|
||||||
|
#define gfxSystemUnlock() cyg_scheduler_unlock()
|
||||||
|
|
||||||
|
#define gfxMutexInit(pmutex) cyg_mutex_init(pmutex)
|
||||||
|
#define gfxMutexExit(pmutex) cyg_mutex_unlock(pmutex)
|
||||||
|
#define gfxMutexDestroy(pmutex) cyg_mutex_destroy(pmutex)
|
||||||
|
#define gfxMutexEnter(pmutex) cyg_mutex_lock(pmutex)
|
||||||
|
|
||||||
|
void gfxSemInit(gfxSem *psem, semcount_t val, semcount_t limit);
|
||||||
|
void gfxSemDestroy(gfxSem *psem);
|
||||||
|
bool_t gfxSemWait(gfxSem *psem, delaytime_t ms);
|
||||||
|
bool_t gfxSemWaitI(gfxSem *psem);
|
||||||
|
void gfxSemSignal(gfxSem *psem);
|
||||||
|
void gfxSemSignalI(gfxSem *psem);
|
||||||
|
semcount_t gfxSemCounterI(gfxSem *psem);
|
||||||
|
#define gfxSemCounter(psem) gfxSemCounterI(psem)
|
||||||
|
|
||||||
|
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param);
|
||||||
|
#define gfxThreadWait(thread) NOTIMPLEMENTED_YET
|
||||||
|
#define gfxThreadMe() cyg_thread_self()
|
||||||
|
#define gfxThreadClose(thread) (void)thread
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GFX_USE_OS_ECOS */
|
||||||
|
#endif /* _GOS_ECOS_H */
|
|
@ -451,6 +451,8 @@
|
||||||
#include "src/gos/osx.h"
|
#include "src/gos/osx.h"
|
||||||
#elif GFX_USE_OS_RAW32
|
#elif GFX_USE_OS_RAW32
|
||||||
#include "src/gos/raw32.h"
|
#include "src/gos/raw32.h"
|
||||||
|
#elif GFX_USE_OS_ECOS
|
||||||
|
#include "src/gos/ecos.h"
|
||||||
#else
|
#else
|
||||||
#error "Your operating system is not supported yet"
|
#error "Your operating system is not supported yet"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,4 +4,5 @@ GFXSRC += $(GFXLIB)/src/gos/chibios.c \
|
||||||
$(GFXLIB)/src/gos/linux.c \
|
$(GFXLIB)/src/gos/linux.c \
|
||||||
$(GFXLIB)/src/gos/osx.c \
|
$(GFXLIB)/src/gos/osx.c \
|
||||||
$(GFXLIB)/src/gos/raw32.c \
|
$(GFXLIB)/src/gos/raw32.c \
|
||||||
|
$(GFXLIB)/src/gos/ecos.c
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,13 @@
|
||||||
#ifndef GFX_USE_OS_RAW32
|
#ifndef GFX_USE_OS_RAW32
|
||||||
#define GFX_USE_OS_RAW32 FALSE
|
#define GFX_USE_OS_RAW32 FALSE
|
||||||
#endif
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief Use a eCos
|
||||||
|
* @details Defaults to FALSE
|
||||||
|
*/
|
||||||
|
#ifndef GFX_USE_OS_ECOS
|
||||||
|
#define GFX_USE_OS_ECOS FALSE
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
@ -75,6 +82,19 @@
|
||||||
#ifndef GFX_FREERTOS_USE_TRACE
|
#ifndef GFX_FREERTOS_USE_TRACE
|
||||||
#define GFX_FREERTOS_USE_TRACE FALSE
|
#define GFX_FREERTOS_USE_TRACE FALSE
|
||||||
#endif
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief How much RAM should uGFX use for the heap
|
||||||
|
* @details Defaults to 0. Only valid with GFX_USE_OS_RAW32
|
||||||
|
* @note If 0 then the standard C runtime malloc(), free() and realloc()
|
||||||
|
* are used.
|
||||||
|
* @note If it is non-zero then this is the number of bytes of RAM
|
||||||
|
* to use for the heap (gfxAlloc() and gfxFree()). No C
|
||||||
|
* runtime routines will be used and a new routine @p gfxAddHeapBlock()
|
||||||
|
* is added allowing the user to add extra memory blocks to the heap.
|
||||||
|
*/
|
||||||
|
#ifndef GOS_RAW_HEAP_SIZE
|
||||||
|
#define GOS_RAW_HEAP_SIZE 0
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#endif /* _GOS_OPTIONS_H */
|
#endif /* _GOS_OPTIONS_H */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef _GOS_RULES_H
|
#ifndef _GOS_RULES_H
|
||||||
#define _GOS_RULES_H
|
#define _GOS_RULES_H
|
||||||
|
|
||||||
#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS
|
#if !GFX_USE_OS_CHIBIOS && !GFX_USE_OS_WIN32 && !GFX_USE_OS_LINUX && !GFX_USE_OS_OSX && !GFX_USE_OS_RAW32 && !GFX_USE_OS_FREERTOS && !GFX_USE_OS_ECOS
|
||||||
#if GFX_DISPLAY_RULE_WARNINGS
|
#if GFX_DISPLAY_RULE_WARNINGS
|
||||||
#warning "GOS: No Operating System has been defined. ChibiOS (GFX_USE_OS_CHIBIOS) has been turned on for you."
|
#warning "GOS: No Operating System has been defined. ChibiOS (GFX_USE_OS_CHIBIOS) has been turned on for you."
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
#define GFX_USE_OS_CHIBIOS TRUE
|
#define GFX_USE_OS_CHIBIOS TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS != 1 * TRUE
|
#if GFX_USE_OS_CHIBIOS + GFX_USE_OS_WIN32 + GFX_USE_OS_LINUX + GFX_USE_OS_OSX + GFX_USE_OS_RAW32 + GFX_USE_OS_FREERTOS + GFX_USE_OS_ECOS != 1 * TRUE
|
||||||
#error "GOS: More than one operation system has been defined as TRUE."
|
#error "GOS: More than one operation system has been defined as TRUE."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ typedef struct GFrameObject {
|
||||||
/**
|
/**
|
||||||
* @brief Create a frame widget
|
* @brief Create a frame widget
|
||||||
*
|
*
|
||||||
* @details This widget provides a window like we know it from desktop systems. You usually use this together with
|
* @details This widget provides a window like we know it from desktop systems.
|
||||||
* gwinAddChild().
|
|
||||||
*
|
*
|
||||||
* @param[in] g The GDisplay to display this window on
|
* @param[in] g The GDisplay to display this window on
|
||||||
* @param[in] fo The GFrameObject structure to initialize. If this is NULL the structure is dynamically allocated.
|
* @param[in] fo The GFrameObject structure to initialize. If this is NULL the structure is dynamically allocated.
|
||||||
|
@ -54,7 +53,7 @@ typedef struct GFrameObject {
|
||||||
* @param[in] flags Some flags, see notes.
|
* @param[in] flags Some flags, see notes.
|
||||||
*
|
*
|
||||||
* @note Possible flags are: GWIN_FRAME_BORDER, GWIN_FRAME_CLOSE_BTN, GWIN_FRAME_MINMAX_BTN.
|
* @note Possible flags are: GWIN_FRAME_BORDER, GWIN_FRAME_CLOSE_BTN, GWIN_FRAME_MINMAX_BTN.
|
||||||
* Whether the close or the minimize maximize buttons are used, the boarder is automatically invoked.
|
* When the close or the minimize/maximize buttons are used, the boarder is automatically invoked.
|
||||||
* @note These frame buttons are processed internally. The close button will invoke a gwinDestroy() which will
|
* @note These frame buttons are processed internally. The close button will invoke a gwinDestroy() which will
|
||||||
* destroy the window itself and EVERY child it contains (also children of children).
|
* destroy the window itself and EVERY child it contains (also children of children).
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* @file src/gwin/gimage.h
|
* @file src/gwin/gimage.h
|
||||||
* @brief GWIN image widget header file.
|
* @brief GWIN image widget header file.
|
||||||
*
|
*
|
||||||
* @defgroup Image Image
|
* @defgroup ImageBox ImageBox
|
||||||
* @ingroup Widgets
|
* @ingroup Widgets
|
||||||
*
|
*
|
||||||
* @details GWIN allos it to create an image widget. The widget
|
* @details GWIN allos it to create an image widget. The widget
|
||||||
|
|
|
@ -344,6 +344,11 @@ void gwinBlitArea(GHandle gh, coord_t x, coord_t y, coord_t cx, coord_t cy, coor
|
||||||
gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
gdispGFillConvexPoly(gh->display, tx+gh->x, ty+gh->y, pntarray, cnt, gh->color);
|
||||||
_gwinDrawEnd(gh);
|
_gwinDrawEnd(gh);
|
||||||
}
|
}
|
||||||
|
void gwinDrawThickLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1, coord_t width, bool_t round) {
|
||||||
|
if (!_gwinDrawStart(gh)) return;
|
||||||
|
gdispGDrawThickLine(gh->display, gh->x+x0, gh->y+y0, gh->x+x1, gh->y+y1, gh->color, width, round);
|
||||||
|
_gwinDrawEnd(gh);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GDISP_NEED_IMAGE
|
#if GDISP_NEED_IMAGE
|
||||||
|
|
|
@ -892,6 +892,23 @@ extern "C" {
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
|
void gwinFillConvexPoly(GHandle gh, coord_t tx, coord_t ty, const point *pntarray, unsigned cnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw a thick line in the window
|
||||||
|
* @details The line thickness is specified in pixels. The line ends can
|
||||||
|
* be selected to be either flat or round.
|
||||||
|
* @note Uses gdispGFillConvexPoly() internally to perform the drawing.
|
||||||
|
* @note Uses the current foreground color to draw the line
|
||||||
|
*
|
||||||
|
* @param[in] gh The window handle
|
||||||
|
* @param[in] x0,y0 The start position
|
||||||
|
* @param[in] x1,y1 The end position
|
||||||
|
* @param[in] width The width of the line
|
||||||
|
* @param[in] round Use round ends for the line
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void gwinDrawThickLine(GHandle gh, coord_t x0, coord_t y0, coord_t x1, coord_t y1, coord_t width, bool_t round);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue